Most people read AllowedIPs as a permission list, the set of addresses that may connect to a peer, rather like a firewall rule written for a tunnel. It is not that. The field is a routing table working in both directions: it chooses a peer for an outgoing packet and it validates the source of an incoming one. Reading it as an access list produces configurations that route traffic nobody asked for.

One Field, Two Readers: Outbound Choice and Source Check

At a client, the prefixes decide which destinations travel to that peer and which stay on the ordinary network. An entry for 0.0.0.0/0 therefore captures every IPv4 destination, which is why importing a full-tunnel profile sends ordinary browsing through the remote machine. Narrow entries do the opposite, routing only the networks you listed and leaving everything else where it was. The cryptokey routing section of the WireGuard documentation states both jobs in one place, outbound peer selection and inbound source validation.

On the server, the same field describes which source addresses each peer may use. That is a cryptographic check rather than a packet filter: a packet whose inner source does not match the peer's list is dropped inside WireGuard, before any host firewall sees it. Both jobs share one list, which is exactly why a list copied from somewhere else misbehaves in a place you did not consider.

The client block is where most of this confusion starts. A split tunnel names the remote networks, and a full tunnel is the same field holding a default prefix:

[Peer]
# split tunnel: only these networks
AllowedIPs = 10.77.0.0/24, 192.168.30.0/24

[Peer]
# full tunnel: everything, both families
AllowedIPs = 0.0.0.0/0, ::/0

Both forms are complete on their own, and they are alternatives rather than steps. The first sends only those two networks through the tunnel; the second sends every destination, with the ::/0 entry adding IPv6 to the IPv4 default. Whichever you choose, those prefixes are the entire routing decision for that peer once wg-quick starts installing routes.

The Hub Needs a Different List

A hub lists each client's tunnel address as a host prefix, plus any network genuinely behind that client. Copying a client's broad list onto every hub peer tells the hub that many peers may source the same addresses, which is not an address plan. The Endpoint field belongs to another layer entirely: it names the peer's outer address and port, never a destination inside the tunnel.

[Peer]
# laptop: tunnel address 10.77.0.2, office LAN behind it
AllowedIPs = 10.77.0.2/32, 192.168.30.0/24

The host prefix carries the tunnel address and the network prefix carries what sits behind the client, and both are needed. Without the host prefix the hub cannot return the client's own traffic, and without the network prefix the LAN behind it stays unreachable; a peer with nothing behind it gets only the host prefix.

Skipping Route Installation Leaves a Gap

wg-quick, the helper that brings an interface up from a configuration file, installs interface addresses and routes as part of that job. Setting Table = off tells the helper to skip the route work, which does not install replacements and does not make the private network reachable. When automatic routes already do the job, naming the prefixes you need is the clearer configuration. Turning route management off and leaving the replacement unwritten is not a design, it is an omission.

The base wg tool behaves differently: it configures the interface and never touches routes, so a setup built directly on it needs route commands of its own. Instructions written for one tool can look wrong when followed against the other. A successful ping is weak evidence too, since it exercises one path rather than every application path you need.

DNS and IPv6 Are Decided Separately

Check the DNS server address the tunnel advertises, and confirm that a route to that address exists through the prefixes you chose. A resolver setting does not make the resolver reachable, and narrowing a tunnel can quietly remove the route that used to reach it. Inspect IPv6 on its own as well, because a correct IPv4 split says nothing about an IPv6 default route that still points at the physical link. Three separate decisions can change at once when you edit one peer block.

Then open one private resource and one ordinary website from a known starting configuration. If the resource answers and browsing still leaves through the local connection, the split does what you asked. If browsing breaks at the same moment, the tunnel took the default route and the prefix list is where to look.

Ebitabo ebifaananyi