Watching YouTube Anonymously: How I Route Media Traffic over Mullvad VPN with OPNsense
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 clientsMEDIA
→ 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
- Install WireGuard plugin if not present.
- 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).
- 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).
- Enable the instance.
- Assign interface:
Interfaces → Assignments
→ add the WireGuard device (e.g.wg0
) as an OPT interface; enable it, give it a name likeWG_MULLVAD
. - Gateway: OPNsense usually auto-creates it. If not, create one under
System → Routing → Gateways
, name itWG_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 (orLAN
if you’ll apply policy there) - Translation / Address: Interface address (the WG interface)
- 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.
- 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
(orMEDIA net
) - To:
any
, Port:53 (TCP/UDP)
- Redirect target IP: Firewall / This firewall
- Redirect target port:
53
This silently hairpins rogue DNS to Unbound.
- From:
- Easiest: NAT Port Forward on
- 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 aregooglevideo.com
(actual media streams) andytimg.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
(orLAN
)- 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
- Source:
- 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).
- Windows:
- 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
onWG_MULLVAD
→ filterhost 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’spf
. 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
YourYOUTUBE_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 routeyoutube.com
and skipgooglevideo.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
viaWG_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.