← Back to Home

WireGuard Split Tunneling with AllowedIPs

WireGuard's AllowedIPs parameter doubles as both an ACL filter and a routing table. NetRoute Pro generates a ready-to-paste AllowedIPs string from any website's domains. No extra ip route commands needed — just edit the peer config and reload.

Command Syntax

Syntax:

AllowedIPs = <CIDR1>, <CIDR2>, <CIDR3>

Example:

AllowedIPs = 1.1.1.0/24, 8.8.8.0/24, 162.159.0.0/16

Add to the [Peer] section of wg0.conf. Officially documented in the WireGuard quickstart.

Prerequisites

Step 1. Generate AllowedIPs in NetRoute Pro

  1. Open the target website in Chrome
  2. Click the NetRoute Pro icon in your extensions
  3. Select the WireGuard platform
  4. Click Analyze Website
  5. Copy the generated AllowedIPs line — it looks like:
AllowedIPs = 104.21.32.0/24, 172.67.182.0/24, 162.159.135.0/24, ...
Tip: enable RIPE BGP optimization in the extension — it replaces individual IPs with real announced BGP prefixes, giving stable subnets that don’t break when Cloudflare/Fastly rotate IPs. Caveat: RIPE BGP returns all prefixes announced by the destination AS — for multi-tenant CDNs (Cloudflare AS13335, AWS AS16509, DigitalOcean AS14061) that’s tens of thousands of IPs covering unrelated sites. Use BGP optimization for single-tenant ASes; keep plain /24 CIDR aggregation for shared CDNs.

Step 2. Paste into your peer config

Linux (wg-quick)

Edit your tunnel config file (typically in /etc/wireguard/, for example /etc/wireguard/wg0.conf). Under the [Peer] section, replace the existing AllowedIPs = ... line with the string you copied:

[Peer]
PublicKey = <your-peer-public-key>
Endpoint = <your-endpoint>:51820
AllowedIPs = 104.21.32.0/24, 172.67.182.0/24, 162.159.135.0/24
PersistentKeepalive = 25

Windows / macOS (GUI)

  1. Open the WireGuard app
  2. Select your tunnel and click Edit
  3. In the config editor, modify the AllowedIPs field under [Peer]
  4. Click Save

Android / iOS

  1. Open the WireGuard mobile app
  2. Tap your tunnel → Edit
  3. Replace the Allowed IPs field value
  4. Tap Save (top right)
Heads up: on Android, tap Back/Save carefully — the app sometimes resets the field on exit if you leave focus without saving explicitly.

Step 3. Restart the tunnel

Reload the peer so the new routing table takes effect.

DNS leak — required reading

WireGuard’s AllowedIPs routes traffic by IP. It does not route DNS. Your browser still asks the system resolver (usually your ISP’s, learned via DHCP) for example.com first — only the resulting IP traffic flows through the tunnel. The ISP sees which sites you visit even though the data is encrypted.

Three options, by threat model:

  1. Hide DNS from ISP fully (split-DNS via wg-quick). Add a DNS = line under [Interface] — wg-quick configures it at tunnel up:
    [Interface]
    PrivateKey = ...
    Address    = 10.0.0.2/24
    DNS        = 10.0.0.1, ~example.com, ~another-site.com
    The ~domain entries make systemd-resolved use the VPN’s DNS only for those domains (split-DNS). Without them, all DNS goes through the VPN.
  2. Reduce ISP visibility (public DoH/DoT). Use a public resolver for everything:
    DNS = 1.1.1.1, 1.0.0.1
    ISP no longer sees domain queries; Cloudflare does.
  3. Accept the leak. Skip the DNS line entirely — only the data path is encrypted, lookups stay on your default resolver. Fine for unblocking-only use cases.

Verify with dnsleaktest.com or browserleaks.com/dns — the resolver shown should belong to your VPN provider or chosen DoH, not your ISP.

Browser-level IP leaks (WebRTC)

Even with split tunneling correctly configured at the OS level, JavaScript on a webpage can use WebRTC to discover your real local and public IP addresses through STUN/ICE, bypassing the VPN. This is by design (P2P video/audio needs direct addresses), not a bug — but it’s a leak the VPN cannot prevent at the network layer.

IPv6 dual-stack bypass

WireGuard’s AllowedIPs entries are address-family specific. If you listed only IPv4 prefixes, traffic to the same domain over IPv6 (which most modern sites prefer per RFC 6724) bypasses the tunnel and exits via your ISP’s default v6 route.

Two fixes:

Fail-closed (kill switch)

When the WireGuard tunnel goes down (network change, manual stop, routing failure), the kernel removes routes bound to the wg interface — and traffic to the previously-tunneled CIDRs leaks via the default route. Use wg-quick’s PostUp/PostDown hooks to install fail-closed firewall rules tied to the tunnel lifecycle:

[Interface]
PrivateKey = ...
Address    = 10.0.0.2/24

# Fail-closed: drop traffic to tunneled CIDRs unless it goes via %i (this tunnel)
PostUp = iptables -I OUTPUT ! -o %i -d 1.1.1.0/24 -j REJECT
PostUp = iptables -I OUTPUT ! -o %i -d 8.8.8.0/24 -j REJECT
PostDown = iptables -D OUTPUT ! -o %i -d 1.1.1.0/24 -j REJECT
PostDown = iptables -D OUTPUT ! -o %i -d 8.8.8.0/24 -j REJECT

%i is replaced by the actual interface name (e.g. wg0). When the tunnel is up, traffic flows through it; when it goes down via wg-quick down, the rules are removed. If the tunnel crashes without running PostDown, those CIDRs stay blocked — which is the safe failure mode (block, don’t leak).

Advanced: Table = off

By default, wg-quick installs a route for every CIDR in AllowedIPs into the main routing table. Setting Table = off under [Interface] tells wg-quick to skip route installation entirely — you manage routing yourself via PostUp/PostDown. Useful when you need policy routing (route based on source IP, mark, or process), a custom routing table, or integration with frr/bird/quagga.

[Interface]
PrivateKey = ...
Address    = 10.0.0.2/24
Table      = off       # do not auto-install routes

# Manage your own routes — typical policy routing example:
PostUp = ip route add 1.1.1.0/24 dev %i table 100
PostUp = ip rule  add from 192.168.1.100 lookup 100
PostDown = ip rule  del from 192.168.1.100 lookup 100
PostDown = ip route flush table 100

Most users don’t need this — the default behaviour (auto-install routes from AllowedIPs) is what NetRoute Pro’s output expects.

Verify

Run sudo wg show — the peer should be listed with the new allowed ips values:

sudo wg show

You can also confirm routing with ip route (Linux/macOS) or route print (Windows) — the listed subnets should point through your WireGuard interface.

Common issues

Pages hang or only partially load (PMTU black hole)

Symptom: a page starts loading, the first few KB arrive, then it freezes; or some sites work fine while others stall. This is a classic path MTU black hole — large packets get fragmented along the path, ICMP “fragmentation needed” replies are dropped by an upstream firewall, and the sender keeps retransmitting blindly.

WireGuard’s default MTU is 1420 (or 1280 over IPv6). On PPPoE the underlying link is 1492; on 4G/LTE often 1400; some CGNAT paths are 1280. Lower the MTU under [Interface]:

[Interface]
MTU = 1380     # try 1380 first, drop to 1280 / 1200 if pages still hang

On routers that forward through the tunnel (e.g. WG client on a router serving a LAN), also clamp TCP MSS so downstream clients don’t blow past PMTU:

iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN \
    -j TCPMSS --clamp-mss-to-pmtu

Losing all network access

If you removed 0.0.0.0/0 but your new AllowedIPs doesn't cover the default route you intended to use, only the listed subnets will go through the tunnel — that's the whole point of split tunneling. Make sure your list contains exactly the subnets you want and nothing else is unintentionally missing.

Android tunnel stuck on "connecting"

Re-save the config explicitly: enter edit mode, tap out of the AllowedIPs field, and tap Save again. Some Android versions need this to commit the change.

Error: AllowedIPs has invalid format

Check for trailing commas, stray whitespace, or newline characters inside the value. AllowedIPs must be a single comma-separated list on one logical line.

Example Configuration File

Ready-to-edit template with inline comments. Replace the example routes with output from NetRoute Pro for your target sites.


# Example WireGuard peer config with split tunneling.
# Generated by NetRoute Pro: https://alexander2k.github.io/netroute-site/
#
# AllowedIPs in [Peer] section doubles as both an ACL and routing table.
# Only the listed networks are sent through the tunnel — everything else
# uses the default route. Replace placeholders with your real keys/addresses.

[Interface]
PrivateKey = YOUR_CLIENT_PRIVATE_KEY
Address    = 10.0.0.2/24
DNS        = 1.1.1.1

[Peer]
PublicKey           = YOUR_SERVER_PUBLIC_KEY
Endpoint            = your.vpn.server:51820
PersistentKeepalive = 25

# Networks to route via VPN — add/remove based on NetRoute Pro output.
AllowedIPs = 1.1.1.0/24, 8.8.8.0/24, 162.159.0.0/16

# To route everything via VPN, use: AllowedIPs = 0.0.0.0/0, ::/0
# Apply with: sudo wg-quick down wg0 && sudo wg-quick up wg0

Tip: Need a config without these comment lines? In NetRoute Pro options, uncheck “Include comments in exported files” — the extension will export only the route commands. Useful for routers that don’t tolerate comment lines.

View all example configs on GitHub →

Official Documentation

Ready to try?

NetRoute Pro — a free Chrome extension to generate routes from any website.

Install Extension