WireGuard Split Tunneling Guide

What Is Split Tunneling?

Split tunneling routes only specific traffic through your VPN while the rest uses your normal internet connection. In a full tunnel, all traffic flows through the VPN — this adds latency, uses your VPN server’s bandwidth for everything, and breaks local network access. Split tunneling gives you the best of both worlds: private access to your self-hosted services without slowing down Netflix, video calls, or local network printers.

Prerequisites

Full Tunnel vs Split Tunnel

AspectFull TunnelSplit Tunnel
AllowedIPs0.0.0.0/0, ::/0Specific subnets only
All internet trafficThrough VPNNormal ISP connection
Self-hosted servicesThrough VPNThrough VPN
Speed impactHigher latency on everythingNo impact on normal browsing
PrivacyAll traffic encryptedOnly VPN-bound traffic encrypted
Local network accessBroken (unless excluded)Works normally
Bandwidth usageVPN server handles all trafficVPN server only handles targeted traffic

Basic Split Tunnel Setup

The key is the AllowedIPs setting in the client’s [Peer] section. Instead of 0.0.0.0/0 (send everything), list only the subnets you want routed through the VPN.

Route Only VPN Subnet

The simplest split tunnel — access only devices on the WireGuard network:

# Client config (wg0.conf)
[Interface]
PrivateKey = <client-private-key>
Address = 10.0.0.2/32
DNS = 10.0.0.1  # Optional: use VPN server's DNS

[Peer]
PublicKey = <server-public-key>
Endpoint = vpn.yourdomain.com:51820
AllowedIPs = 10.0.0.0/24
PersistentKeepalive = 25

This routes traffic to 10.0.0.x through WireGuard. Everything else — web browsing, streaming, gaming — goes through your normal connection.

Route VPN + Home LAN

Access both WireGuard peers and your home network (e.g., 192.168.1.0/24):

[Peer]
PublicKey = <server-public-key>
Endpoint = vpn.yourdomain.com:51820
AllowedIPs = 10.0.0.0/24, 192.168.1.0/24
PersistentKeepalive = 25

Server-side requirement: Your WireGuard server must be able to route to the home LAN. If the server IS on the home LAN, enable IP forwarding:

sudo sysctl -w net.ipv4.ip_forward=1

And add routing rules in the server’s WireGuard config:

[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = <server-private-key>
PostUp = iptables -A FORWARD -i wg0 -o eth0 -j ACCEPT; iptables -A FORWARD -i eth0 -o wg0 -m state --state RELATED,ESTABLISHED -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -o eth0 -j ACCEPT; iptables -D FORWARD -i eth0 -o wg0 -m state --state RELATED,ESTABLISHED -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

Route Multiple Service Subnets

If your self-hosted services use different Docker networks or subnets:

[Peer]
PublicKey = <server-public-key>
Endpoint = vpn.yourdomain.com:51820
AllowedIPs = 10.0.0.0/24, 172.18.0.0/16, 192.168.1.0/24
PersistentKeepalive = 25
SubnetPurpose
10.0.0.0/24WireGuard peer network
172.18.0.0/16Docker bridge network (your containers)
192.168.1.0/24Home LAN

DNS Split Tunneling

By default, a split tunnel doesn’t route DNS through the VPN. This means you can reach services by IP but not by hostname. To fix this:

Option 1: Use VPN Server’s DNS

Set your VPN server as the DNS server in the client config:

[Interface]
PrivateKey = <client-private-key>
Address = 10.0.0.2/32
DNS = 10.0.0.1

This routes ALL DNS through the VPN (simple but may slow DNS for non-VPN sites).

Option 2: Run Pi-hole / AdGuard Home on the VPN

Run Pi-hole or AdGuard Home on your server, accessible via the WireGuard IP. You get split-tunnel routing PLUS ad-blocking on all DNS queries:

[Interface]
DNS = 10.0.0.1  # Pi-hole on WireGuard server

Option 3: Conditional DNS (Advanced)

On Linux clients, use resolvconf or systemd-resolved to route only specific domains through the VPN DNS:

[Interface]
PostUp = resolvectl dns %i 10.0.0.1; resolvectl domain %i ~home.lan
PostDown = resolvectl revert %i

This sends .home.lan queries to the VPN DNS and everything else to your normal DNS.

Per-Application Split Tunnel (Linux)

WireGuard routes at the network level, not per-app. But you can use network namespaces to route specific applications through the VPN:

# Create a network namespace
sudo ip netns add vpn

# Move the WireGuard interface into it
sudo ip link set wg0 netns vpn

# Run an application inside the namespace
sudo ip netns exec vpn firefox

This is advanced and most users don’t need it. If you need per-app control, consider using Tailscale which supports exit nodes and ACLs for finer-grained routing.

Mobile Device Configuration

iOS / Android

The WireGuard mobile app supports split tunneling via AllowedIPs. In the app:

  1. Edit your tunnel configuration
  2. Under “Peer,” set Allowed IPs to your specific subnets (e.g., 10.0.0.0/24, 192.168.1.0/24)
  3. Remove 0.0.0.0/0 if present

On-Demand Rules (iOS)

iOS WireGuard supports on-demand activation:

  • Activate on Wi-Fi: Connect to VPN only when on untrusted networks
  • Activate on cellular: Stay connected on mobile data
  • Exclude home Wi-Fi: Don’t use VPN when already on your home network

Configure in the WireGuard iOS app under tunnel → Edit → On Demand.

Common Mistakes

  1. Forgetting IP forwarding on the server — Without net.ipv4.ip_forward=1, the server won’t route split-tunnel traffic to your LAN.
  2. Wrong AllowedIPs on the server side — The server’s [Peer] section for each client must include that client’s VPN IP: AllowedIPs = 10.0.0.2/32. Don’t put 0.0.0.0/0 on the server’s peer config unless the client is an exit node.
  3. DNS not routing through VPN — You can reach 10.0.0.x by IP but nextcloud.home doesn’t resolve. Set the DNS field in [Interface] or use conditional DNS.
  4. Docker networks not reachable — If your containers use 172.17.0.0/16 and you only route 10.0.0.0/24, you won’t reach containers. Add the Docker subnet to AllowedIPs.
  5. Using 0.0.0.0/0 as a “catch-all” with exclusions — WireGuard’s AllowedIPs is additive, not subtractive. You can’t say “route everything EXCEPT YouTube.” Use specific subnets you DO want to route.

Next Steps

  • Set up WireGuard if you haven’t already
  • Run Pi-hole on your server for VPN-wide ad blocking
  • Configure Headscale for easier key management with split tunneling built in
  • Learn about Docker Networking to understand container subnet routing

Comments