Problem Statement & Goal
By default, the NordVPN Linux client redirects all system outbound traffic through the VPN tunnel. To prevent breaking local hosting services (Samba, SSH, Syncthing, Copyparty, Cockpit, Immich, Jellyfin, Teslamate), a cumbersome list of 14 ports and 10 broad Google/Ubuntu subnets was previously allowlisted.
Comparative Evaluation: Option #2 vs Option #3
| Evaluation Dimension | Option #2: Linux Network Namespace (`netns`) | Option #3: NordVPN CLI + Policy Routing |
|---|---|---|
| Isolation Boundary | Kernel-Level Namespace Complete TCP/IP stack separation. |
Host-Level Routing Table Shared network stack with policy markers. |
| Leak-Proof Kill Switch | Hardware-Grade (100%) If tunnel drops, packets have no physical route out. |
Software Dependent Relies on persistent daemon state & IP rule order. |
| Host Service Impact | Zero Impact: Host default gateway and routing table are never modified. | Zero Impact: Global routing turned off via set routing off. |
| WebUI Accessibility (:8080) | Accessible via lightweight veth virtual bridge or local port proxy. | Directly accessible on host LAN IP (192.168.1.100:8080). |
| Maintenance & Reconnects | High Stability WireGuard interface persists or reconnects independently. |
Moderate Complexity Dynamic internal IP changes require route updates. |
| Recommended Verdict | Recommended (Standard in Headless Linux) | Viable Alternative (Official CLI preserved) |
Option #2: Linux Network Namespace (netns) Plan
Kernel Isolation
Option #2 constructs a dedicated Linux network namespace (e.g., ns-vpn).
The NordVPN WireGuard interface resides entirely inside this namespace.
The host server's network stack is 100% isolated, and qbittorrent-nox@mason.service runs directly inside the namespace.
NordLynx uses the standard WireGuard protocol. You can obtain your WireGuard private key and server endpoint using the NordVPN access token or via the CLI:
# Generate / check token or use Wireguard config generator
# NordVPN private key can be retrieved from NordAccount -> Security -> Manual Setup
# Example WireGuard interface config (/etc/wireguard/wg-nord.conf):
[Interface]
PrivateKey = <YOUR_NORD_PRIVATE_KEY>
Address = 10.5.0.2/32
DNS = 103.86.96.100, 103.86.99.100
[Peer]
PublicKey = <SERVER_PUBLIC_KEY>
Endpoint = us8291.nordvpn.com:51820
AllowedIPs = 0.0.0.0/0
To allow your LAN devices to access the qBittorrent WebUI (port 8080) while keeping all torrent traffic encapsulated inside the VPN, create a pair of virtual ethernet interfaces:
#!/bin/bash
# /usr/local/bin/setup-vpn-netns.sh
set -e
# 1. Create namespace
ip netns add ns-vpn || true
ip netns exec ns-vpn ip link set dev lo up
# 2. Setup veth pair for WebUI access (10.200.1.0/24)
ip link add veth-host type veth peer name veth-vpn
ip link set veth-vpn netns ns-vpn
ip addr add 10.200.1.1/24 dev veth-host
ip link set dev veth-host up
ip netns exec ns-vpn ip addr add 10.200.1.2/24 dev veth-vpn
ip netns exec ns-vpn ip link set dev veth-vpn up
# 3. Bring up WireGuard inside ns-vpn
ip link add dev wg-nord type wireguard
ip link set wg-nord netns ns-vpn
ip netns exec ns-vpn wg setconf wg-nord /etc/wireguard/wg-nord.conf
ip netns exec ns-vpn ip addr add 10.5.0.2/32 dev wg-nord
ip netns exec ns-vpn ip link set wg-nord up
ip netns exec ns-vpn ip route add default dev wg-nord
# 4. Route WebUI port 8080 from Host LAN to Namespace
iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 10.200.1.2:8080
iptables -t nat -A POSTROUTING -p tcp -d 10.200.1.2 --dport 8080 -j MASQUERADE
Systemd provides native support for network namespaces via NetworkNamespacePath.
Modify /etc/systemd/system/qbittorrent-nox@mason.service.d/override.conf:
[Unit]
Requires=vpn-netns.service
After=vpn-netns.service
[Service]
NetworkNamespacePath=/run/netns/ns-vpn
# Alternatively: ExecStart=/usr/bin/ip netns exec ns-vpn /usr/bin/qbittorrent-nox
Option #3: NordVPN CLI + Policy Routing Plan
Official CLI Maintained
Option #3 retains the official nordvpn CLI tool and daemon, but disables the automatic hijacking of the host's default route.
Linux Policy-Based Routing (PBR) routes packets originating from the nordlynx interface through the VPN gateway.
Instruct the NordVPN daemon to connect and establish the tunnel without altering the host's primary routing table:
# 1. Turn off default route management in NordVPN
nordvpn set routing off
# 2. Connect to preferred server
nordvpn connect
# 3. Verify: Host default gateway is UNTOUCHED
ip route show default
# Output remains: default via 192.168.1.254 dev enp0s31f6
Because global routing is disabled, the Linux kernel needs an explicit routing table for traffic bound to nordlynx.
# 1. Register a dedicated routing table
echo "200 vpn_traffic" | sudo tee -a /etc/iproute2/rt_tables
# 2. Add default route to table 200 via nordlynx
sudo ip route add default dev nordlynx table vpn_traffic
# 3. Direct all packets with source IP of nordlynx to table 200
NORD_IP=$(ip -4 addr show dev nordlynx | grep -oP '(?<=inet\s)\d+(\.\d+){3}')
sudo ip rule add from $NORD_IP table vpn_traffic priority 200
# 4. Flush route cache
sudo ip route flush cache
In ~/.config/qBittorrent/qBittorrent.conf, verify that qBittorrent binds strictly to nordlynx for peer connections while keeping WebUI listening on all IPs:
[BitTorrent]
Session\Interface=nordlynx
Session\InterfaceName=nordlynx
Session\Port=6881
[Preferences]
WebUI\Address=*
WebUI\Port=8080
Whenever NordVPN reconnects, the assigned internal IP of nordlynx may change.
A systemd dispatcher or small daemon monitors nordlynx state and updates the ip rule dynamically:
# /etc/systemd/system/nordvpn-pbr.service
[Unit]
Description=NordVPN Policy Routing Dispatcher
After=nordvpnd.service
BindsTo=nordvpnd.service
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/bin/update-nordvpn-pbr.sh
[Install]
WantedBy=multi-user.target
Final Assessment & Next Steps
Both options achieve your exact goal of preventing NordVPN from taking over host network routes.
Option #2 (Network Namespace) is the industry standard for Linux media/seedbox servers because it provides complete, kernel-level leak protection with zero dependence on the NordVPN daemon's firewall quirks.
Option #3 (Policy Routing) is best if you strongly prefer using the official nordvpn connect <country> CLI syntax.