A split tunnel is defined by what you leave out, and WireGuard makes that decision in one field. The client peer's AllowedIPs both selects which destinations go through the tunnel and filters which inner source addresses are accepted, and wg-quick turns the same list into host routes. Get that list wrong and the tunnel either swallows everything or carries nothing.

Decide the prefix list first

Write down the destinations that must use the tunnel before touching a config file. Office subnets, a database range, a management network: each is a prefix with a reason. Everything not on the list stays on the physical path, which is the entire point of the design.

If the list contains 0.0.0.0/0 or ::/0, you have built a full tunnel and should say so, because the failure modes and DNS expectations differ.

Keep the list short enough that a reviewer can check it against the routing table later.

Client config: peer, AllowedIPs, DNS

The client's interface block holds its own tunnel address and private key. The peer block holds the server's public key, endpoint and the prefixes from step one:

[Interface]
Address = 10.9.0.2/32
PrivateKey = <client-private-key>
DNS = 10.20.0.53

[Peer]
PublicKey = <server-public-key>
Endpoint = vpn.example.net:51820
AllowedIPs = 10.20.0.0/16, 10.30.0.0/24
PersistentKeepalive = 25

AllowedIPs on the client is the set of remote destinations, not the client's own address. The DNS line only takes effect through wg-quick's resolver integration, so a host without resolvconf or systemd-resolved support will ignore it. PersistentKeepalive keeps a NAT mapping alive and is unnecessary on a direct path.

Comment each prefix with the service it serves, or the next edit will be guesswork.

Server config: the opposite viewpoint

On the server, the peer entry represents the client, so its AllowedIPs is the client's tunnel address, usually a /32. It is not the office subnet. Copying the client's list into the server entry is the most common split-tunnel mistake, and it either widens access or breaks the inner source check at handshake time.

The server's own interface address, and the routes it needs toward the office, are separate from any peer entry.

Two files, two viewpoints, one set of prefixes split between them.

Bring it up and read the routes

Start the interface with the supported manager, then look at what it installed rather than at what you intended. wg-quick derives routes from AllowedIPs; if the profile sets Table = off, nothing is installed and the routing is yours to write. Read the route for each prefix and confirm it points at the WireGuard interface. An empty route list usually means the profile that was applied is not the one you edited.

Check the handshake counters as well, since a peer with no handshake has a key, endpoint or reachability problem rather than a routing one.

Write the exact command you used, because the next person will run it under pressure.

Verify both sides, then record the rollback

Test a private address, its internal name, and a destination that must stay direct. If the private address works and the direct one now leaves through the tunnel, the prefix list is too wide. If the name fails while the address works, the DNS line did not take effect. Rollback is one command, and it belongs in the same note.

After a reconnect, confirm the routes are still there, because a manager that re-applies the profile can replace manual routes.

Keep one configuration owner, since two managers producing the same interface will disagree eventually. The wg-quick manual documents the route and DNS behaviour it provides.

Inyandiko zihuye