Watching YouTube Anonymously: How I Route Media Traffic over Mullvad VPN with OPNsense

Firewall Oct 2, 2025

I don’t want YouTube to know who I am or where I watch from. I want to enjoy videos without feeding the profile machine. Full-tunnel VPN for everything? Overkill. The smarter move is policy-based routing: only YouTube traffic goes through Mullvad; everything else goes out normally.

This guide shows exactly how I built that on OPNsense with Mullvad (WireGuard). It’s practical, fast, and honest about the trade-offs (dynamic CDNs, DNS leaks, and “smart” TVs that hardcode DNS).


My network in a nutshell

  • OPNsense as the edge device (between ISP modem and my LAN) running on my protectli.
  • VLANs for separation:
    • LAN → everyday clients
    • MEDIA → TV, streaming box, media PC (the targets for YouTube policy routing)
    • (optional) GUEST / IOT, etc.
  • WireGuard client on OPNsense, connected to Mullvad → creates a VPN gateway I can use in rules.
  • Unbound DNS on OPNsense as the central resolver. Client devices are forced to use OPNsense for DNS (to avoid leaks).
You can apply the YouTube rule to all clients, or just the MEDIA VLAN. I prefer the VLAN approach: fewer surprises, easy to test.

Why I Use a Protectli Box for OPNsense

Running OPNsense on consumer hardware is fine for testing, but if you’re serious about routing, VLANs, VPN, and policy-based routing, you’ll want something more reliable. I’ve been using a Protectli Vault as my OPNsense box — and honestly, it’s one of the best decisions I’ve made for my homelab.

It’s fanless (so completely silent), runs cool, and is built specifically for firewall/router use cases. WireGuard performance is excellent, and even with multiple VLANs, intrusion detection, and VPN tunnels, it doesn’t break a sweat.

👉 If you’re looking for a rock-solid device to run OPNsense or pfSense on, check out the Protectli Vault on Amazon (affiliate link).

With this, you don’t have to worry about your firewall being the bottleneck when you push YouTube traffic through Mullvad or when you start segmenting your home network further.


Prerequisites

  • OPNsense installed and working.
  • A Mullvad account and a WireGuard config (keys + endpoint).
  • Admin access to OPNsense.
  • Basic comfort with Firewall rules and NAT.

Step-by-step setup

0) Housekeeping (worth the 2 minutes)

  • Update OPNsense to a current release.
  • Backup: System → Configuration → Backups → Download configuration.

1) Set up Mullvad (WireGuard) on OPNsense

  1. Install WireGuard plugin if not present.
  2. Create a Local instance:
    VPN → WireGuard
    • Add a Local with your private/public key pair (from Mullvad).
    • Set a Tunnel Address, e.g. 10.64.0.2/32 (Mullvad examples vary; follow the config Mullvad generated).
  3. Add Peer (Mullvad):
    • Public key = from Mullvad
    • Endpoint address/port = from Mullvad
    • Allowed IPs: 0.0.0.0/0 (we’ll steer only selected traffic with firewall rules later).
  4. Enable the instance.
  5. Assign interface:
    Interfaces → Assignments → add the WireGuard device (e.g. wg0) as an OPT interface; enable it, give it a name like WG_MULLVAD.
  6. Gateway: OPNsense usually auto-creates it. If not, create one under
    System → Routing → Gateways, name it WG_MULLVAD_GW.
    • Tip: if the gateway monitor flaps, either set a stable monitor IP reachable via the tunnel or disable monitoring for this gateway.

2) Outbound NAT for the tunnel

Policy-based routing still needs NAT out the tunnel.

  • Go to Firewall → NAT → Outbound.
  • Switch to Hybrid (or Manual) mode.
  • Add a rule:
    • Interface: WG_MULLVAD
    • Source: your MEDIA network (or LAN if you’ll apply policy there)
    • Translation / Address: Interface address (the WG interface)
  • Save & Apply.
If you already use automatic outbound NAT, Hybrid is safer: you add only what you need for WG while keeping defaults.

3) DNS hygiene (no leaks)

YouTube policy routing is pointless if your clients leak DNS to the ISP or public resolvers.

  1. Force clients to use OPNsense DNS:
    • DHCP: hand out OPNsense’s IP as DNS server.
    • Then block/redirect any direct DNS (port 53) from clients to the internet.
      • Easiest: NAT Port Forward on LAN/MEDIA:
        • From: LAN net (or MEDIA net)
        • To: any, Port: 53 (TCP/UDP)
        • Redirect target IP: Firewall / This firewall
        • Redirect target port: 53
          This silently hairpins rogue DNS to Unbound.
  2. Run Unbound (Services → Unbound DNS) as your central resolver.
    • Optional: enable DNS-over-TLS upstreams or Mullvad DNS if you want all DNS to egress via the tunnel.
    • Minimal viable setup: keep Unbound local; the key is simply “no direct DNS from clients to WAN”.
Smart TVs often hardcode DNS (8.8.8.8, etc.). The redirect above neutralizes that.

4) Build a YouTube destination alias

We’ll match on destination domains (OPNsense resolves them to IPs for the firewall table). Start small; you can extend later.

  • Firewall → Aliases → +
    • Type: FQDN (or Host(s), depending on UI)
    • Name: YOUTUBE_DEST
    • Entries (one per line):youtube.com
      www.youtube.com
      m.youtube.com
      youtubei.googleapis.com
      ytimg.com
      s.ytimg.com
      r.youtube.com
      googlevideo.com
    • Save.
Reality check: YouTube/CDNs shift a lot. The key domains are googlevideo.com (actual media streams) and ytimg.com (assets). You may need to add more over time.

5) Policy rule: send YouTube to Mullvad

On the interface where the clients live (I use MEDIA):

  • Firewall → Rules → MEDIA (or LAN)
  • Add a Pass rule above your general allow rule:
    • Source: MEDIA net (or specific hosts)
    • Destination: YOUTUBE_DEST (the alias)
    • Protocol: any
    • Advanced → Gateway: WG_MULLVAD_GW
    • Description: Route YouTube via Mullvad
  • Save & Apply.
  • Make sure your default “allow to any” rule stays below this new rule.
Order matters. pf evaluates top-down. If your generic allow fires first, your policy route won’t.

6) (Optional) A quick sanity blocker for DNS

On MEDIA, add a rule above everything that blocks dest port 53 to ! This Firewall (negate “This Firewall”), so only the NAT-redirect to Unbound works. It’s belt-and-suspenders against weird client behavior.


7) Test & verify

  • Traceroute from a client to googlevideo.com
    • Windows: tracert googlevideo.com
    • Linux/macOS: traceroute googlevideo.com
      The path should go out through the Mullvad tunnel (you’ll typically see an extra hop consistent with WG egress).
  • OPNsense Live View:
    Firewall → Log Files → Live View → filter by your rule description or by destination hostnames. You should see matches tagged with the WG gateway.
  • Packet Capture:
    Interfaces → Diagnostics → Packet Capture on WG_MULLVAD → filter host googlevideo.com → start a YouTube stream and confirm you see packets.
  • Reality test: start a video, then check your visible IP on a separate tab that loads media from YouTube (ads/CDN checks can help). For deeper checks, inspect connections on the client (e.g., netstat, tcpdump).

How it works (under the hood)

  • Policy-based routing (pf “route-to”)
    OPNsense uses FreeBSD’s pf. When a rule matches and you set a Gateway, pf adds a route-to directive for that state. That means: packets in this state are pinned to the specified gateway/interface — here, the WireGuard tunnel. Replies follow the same state, so back-and-forth stays in the tunnel.
  • FQDN aliases → IP tables
    Your YOUTUBE_DEST alias is not “DNS at runtime per packet”. OPNsense resolves the FQDNs on a schedule and builds an IP table. If YouTube/CDN IPs move, the alias refresh must catch up. That’s why YouTube routing is “mostly right”, not perfect.
  • NAT on WG
    Outbound NAT on the WG interface ensures your internal client IPs translate to the WG interface address when going out the tunnel. Without this, upstream would drop or misroute your traffic.
  • DNS leaks
    If clients send DNS directly to the internet, YouTube (and others) can still see your real network location via DNS logs — even if the media stream rides the VPN. The NAT redirect (or explicit block) forces all client DNS to Unbound on OPNsense, which you control.
  • Why googlevideo.com matters
    The actual video segments are almost always served from *.googlevideo.com CDN names. If you only route youtube.com and skip googlevideo.com, the watch page might go via VPN but the video won’t.

Maintenance & gotchas

  • CDN churn: Expect to occasionally add hostnames. Start with the list above; add regional variations if you see misses in logs.
  • Smart TV DNS: Many TVs hardcode 8.8.8.8 or vendor DNS. The NAT redirect fixes this. If a TV also uses DoH/DoT, you may need additional blocks or force it into the MEDIA VLAN where egress is tightly controlled.
  • Gateway monitoring: If the WG gateway shows as “down” but traffic still works, it’s just a monitor problem. Either set a known, reachable monitor via the tunnel or disable monitor for that gateway.
  • Performance: WireGuard on OPNsense is fast enough for 4K on decent hardware. If things stutter, try a nearer Mullvad exit or different port.

youtube.com
www.youtube.com
m.youtube.com
youtubei.googleapis.com
ytimg.com
s.ytimg.com
r.youtube.com
googlevideo.com

Add more as you observe them in logs (regional edges, *.c.youtube.com, etc.).


TL;DR

  • Set up Mullvad (WireGuard) on OPNsense and get a WG_MULLVAD_GW.
  • Force all client DNS to Unbound on OPNsense (block/redirect port 53).
  • Create a YOUTUBE_DEST alias (FQDNs above).
  • Add a top-ordered firewall rule on your client network that routes Destination: YOUTUBE_DEST via WG_MULLVAD_GW.
  • Test with traceroute, Live View, and packet capture.

YouTube now plays over Mullvad. Everything else stays normal. Clean, targeted, and under your control.

Tags