Selective VPN Routing: Gluetun, NordVPN and a Per-Site SOCKS5 Proxy
Routing your whole machine through a VPN is a blunt instrument. It slows down everything, breaks banking sites that dislike foreign IPs, and gets you captchas on half the internet. What I actually wanted was narrower: send a handful of sites (social media and YouTube) out through a non-UK exit, and leave everything else on my normal connection.
The recipe is simple: a Docker container that holds the VPN tunnel, a small SOCKS5 proxy living inside that tunnel, and a browser extension that decides, page by page, what uses the proxy.
The architecture
Browser (TabProxy rules)
|
|-- youtube.com, instagram.com, x.com ... --> SOCKS5 :1080 --> gluetun --> NordVPN (non-UK exit)
|
'-- everything else --> direct connection
Step 1: Gluetun and a SOCKS5 proxy
Gluetun is a VPN client container with a built-in kill switch firewall. It supports NordVPN natively. One thing worth knowing up front: gluetun ships with an HTTP proxy and Shadowsocks, but not a native SOCKS5 server. The clean solution is to run a tiny SOCKS5 server (microsocks) as a second container that shares gluetun's network namespace, so all its traffic is forced through the tunnel.
NordVPN credentials
You don't have to use NordVPN, it's just what I do, however it is important to choose a VPN provider with a proven "no logs" policy, ie they do not retain ANY logs of your traffic through their network.
Don't use your Nord account email and password. In the Nord Account dashboard, go to the manual setup section and generate service credentials. These are what OpenVPN needs.
docker-compose.yml
services:
gluetun:
image: qmcgaw/gluetun:latest
container_name: gluetun
cap_add:
- NET_ADMIN
devices:
- /dev/net/tun:/dev/net/tun
environment:
- VPN_SERVICE_PROVIDER=nordvpn
- VPN_TYPE=openvpn
- OPENVPN_USER=your_nord_service_username
- OPENVPN_PASSWORD=your_nord_service_password
- SERVER_COUNTRIES=Netherlands
- TZ=Europe/London
# Allow LAN clients to reach the SOCKS port through gluetun's firewall
- FIREWALL_INPUT_PORTS=1080
ports:
- "1080:1080/tcp" # SOCKS5 (published on gluetun, as microsocks shares its network)
restart: unless-stopped
socks5:
image: vimagick/microsocks:latest
container_name: socks5
network_mode: "service:gluetun"
command: -p 1080
depends_on:
gluetun:
condition: service_healthy
restart: unless-stopped
A few notes:
SERVER_COUNTRIESis the important line. Pick anywhere that is not the UK. Netherlands, Germany, Ireland and so on all work. Some countries have their own age-check rules, so choose accordingly.- Because
socks5usesnetwork_mode: service:gluetun, it has no network of its own. If the VPN drops, the proxy has no route out. That is exactly the kill switch behaviour you want. - Ports are published on the gluetun container, not the socks5 one.
- If you would rather use WireGuard, gluetun supports it for NordVPN too (
VPN_TYPE=wireguardplus yourWIREGUARD_PRIVATE_KEY), and it is generally faster.
Bring it up and test it
docker compose up -d
docker logs -f gluetun
Wait for a line saying the tunnel is up and the public IP has been detected. Then check the exit IP through the proxy:
curl --socks5-hostname 127.0.0.1:1080 https://ifconfig.me
curl https://ifconfig.me
The first should show a Nord exit IP in your chosen country, the second your normal UK address. If they differ, the hard part is done.
If the proxy runs on another machine on your network (a homelab box, say), replace 127.0.0.1 with its LAN IP. Don't expose port 1080 to the internet. An open SOCKS proxy will get abused very quickly. Keep it LAN-only, or reach it over Tailscale/WireGuard.
Step 2: Per-page routing with TabProxy
Now the browser side. The idea behind a tab or pattern based proxy extension is that the proxy is applied selectively, not globally. Only the sites you list go through SOCKS, and everything else goes direct.
Configure the proxy
In the extension, add a new proxy with these settings:
- Type: SOCKS5
- Host:
127.0.0.1(or the LAN IP of your Docker host) - Port:
1080 - Proxy DNS: enabled (in Firefox terms, "Proxy DNS when using SOCKS v5")
That last one matters more than it looks. If DNS lookups happen locally, your ISP's resolver still sees which sites you visit and can hand back geo-specific answers. Resolving through the proxy keeps name lookups inside the tunnel as well. The --socks5-hostname flag in the curl test above does the same thing. If concerned about DNS snooping by your ISP or others, you can use a chrome based browser (such as Brave) that can use DoH (DNS over HTTPS) and route your DNS calls to services such as Cloudflare that support DoH. This way your DNS requests are wrapped in encrypted SSL and your ISP cannot see them and thus block or filter them.
Choose what goes through it
Social sites and video platforms load assets from a lot of secondary domains, so listing only the front door will leave you with broken pages or partial geo-detection. A starting set of patterns:
*.youtube.com
*.googlevideo.com
*.ytimg.com
*.youtu.be
*.facebook.com
*.fbcdn.net
*.instagram.com
*.cdninstagram.com
*.x.com
*.twitter.com
*.twimg.com
*.reddit.com
*.redd.it
*.redditmedia.com
*.redditstatic.com
*.tiktok.com
*.tiktokcdn.com
Everything not matching falls through to a direct connection, so your banking, work tools and streaming services never see the VPN.
Tip: open the browser's network panel on a page that misbehaves and look for failed requests. Whatever domain is failing or being blocked is the one you need to add.
If your extension of choice turns out to be tab-scoped rather than pattern-scoped (or you want both), a pattern-based tool like FoxyProxy does the same job with URL patterns, and the SOCKS5 settings above are identical.
Verify per site
Load a "what's my IP" page on a non-listed site and confirm it shows your UK address. Then open a listed site and check that the exit country is what you expect. Nord exit IPs are sometimes flagged by big platforms, so if one site throws a captcha or blocks you, restart gluetun to get a different server:
docker compose restart gluetun
What this does and doesn't do
This is a straightforward way to make certain sites see you as browsing from another country. That means UK-specific age verification prompts on those sites generally won't be triggered, as they key off the apparent location of the connection.
A few honest caveats:
- Using a VPN is legal in the UK, but platforms' terms of service may not love it, and services can change how they detect and handle VPN traffic at any time.
- Your traffic to those sites is now visible to Nord's exit network instead of your ISP. You are moving trust, not eliminating it, however the lack of log retention by the VPN provider is key here.
- Logged-in accounts can still be tied to you by other signals (account history, payment details, phone number). Location is only one input.
- Free-standing "bypass" claims age quickly. Test it yourself, and expect to tweak the domain list over time.
Wrap-up
The nice part of this setup is how little it costs you. One compose file, two tiny containers, and a browser rule list. Your normal traffic stays fast and local, the sites you choose go out via a Nord exit, and if the VPN falls over the proxy simply stops working rather than leaking your real IP.
From here it is easy to extend: run several gluetun instances on different ports for different countries, put the proxy behind Tailscale so it works from your phone, or point other tools (yt-dlp, for example) at the same SOCKS port.