skip to content

In WireGuard, what is cryptokey routing, and how does one peer's allowed-IPs list govern both outgoing and incoming packets?

level: middleimportance: must knowfreq 36%

answer

  1. one list, two directions
  2. the destination picks the key
  3. the source must map back
  4. an authentic source on the tunnel
  5. like reverse-path filtering

basics

~20 s

Cryptokey routing binds each peer's public key to its allowed IPs. Outbound, a packet's destination picks the peer whose session encrypts it. Inbound, the decrypted packet's source must map back to the peer that sent it, or the packet is dropped.

solid answer

~50 s

A WireGuard interface holds a table with one row per peer: its public key, a list of **allowed IPs** and, optionally, an endpoint. When a packet leaves through the interface, its **destination** is looked up in that table like a route. The matching peer's session encrypts the packet, which goes over UDP to that peer's endpoint, and a packet that matches no peer is dropped. When a packet arrives, WireGuard authenticates and decrypts it and then looks up the inner **source** address. If the table maps that address to a different peer, or to none, the packet is dropped. Because one list does both jobs, the paper compares it to reverse-path filtering. A firewall rule can trust that a packet from `10.66.0.11` on the tunnel interface really came from the key that owns that address. Allowed IPs are a routing and filtering rule, not an address assignment.

go deeper

for a junior

Remember the pairing: each peer's public key comes with a list of addresses, and that list is used both to send to the peer and to check what it sends.

for a middle

Walk through both lookups: destination selects the peer and session outbound, and the decrypted source must map back to the same peer inbound, or the packet is dropped.

for a senior

Draw the consequences: authentic source addresses for firewall rules, why a wide prefix on a laptop is a spoofing grant, and why allowed IPs are separate from the learned endpoint.

for a principal

Treat the allowed-IPs table as the access-control list of the whole VPN: it should come from one address inventory, never from hand-edited copies.

## The table every WireGuard interface holds The WireGuard paper names its central idea **cryptokey routing**. It starts from one principle: a secure VPN is an association between **peers** and **the IP addresses each one may use as a source**. In WireGuard a peer is identified by its static public key, so the association is a table from public keys to address lists. The paper calls these **allowed IPs**. Take a company gateway that replaced its IPsec remote access with WireGuard. Each engineer's laptop gets one tunnel address in `10.66.0.0/24`, and one branch router sits behind `10.20.0.0/16`: | Peer (public key) | Allowed IPs | Endpoint | |---|---|---| | laptop A's key | `10.66.0.11/32` | learned from its packets | | laptop B's key | `10.66.0.12/32` | learned from its packets | | branch router's key | `10.66.0.2/32`, `10.20.0.0/16` | `198.51.100.7`, configured | The interface also has its own private key and a listening UDP port. Apart from optional per-peer settings such as a pre-shared key or a persistent keepalive, that is the whole configuration model: there are no tunnels to define and no traffic selectors. ## Sending: the destination chooses the key The paper's send flow, for a packet routed into the WireGuard interface: 1. The packet reaches the interface in plaintext. 2. Its **destination address** is looked up among the allowed IPs. A packet for `10.20.4.9` matches the branch router's row. 3. If **no** peer matches, the packet is dropped, and the paper's implementation tells the local sender with an ICMP "no route to host". 4. The matching peer's current session key and nonce counter encrypt the packet with ChaCha20-Poly1305, and a WireGuard header is prepended. 5. The result goes out as a UDP datagram to that peer's **endpoint**. If no endpoint is known yet, the packet is dropped. ## Receiving: the source must belong to the key For a UDP datagram arriving on the listening port: 1. The header identifies the session. WireGuard checks the message counter and authenticates and decrypts the packet. If it fails, the packet is dropped. 2. Because the packet authenticated, its **outer** source address and port become that peer's endpoint. This is how roaming works. 3. The decrypted inner packet must be IP, and its **source address** is looked up in the same table. 4. If that lookup does not return **the same peer** whose session decrypted it, the packet is dropped. Otherwise it is delivered to the interface's receive queue. Step 4 asks a global question. It does not ask "is this source in the sender's list?". It asks "which peer would this source address route to, and is that the sender?". The paper notes that this enforces a **one-to-one mapping**: replies to an address always go to the same peer that may send from it. ## One list, two jobs The paper says the two directions could have used two lists, and that keeping one gives *something similar to reverse-path filtering*. The operational payoff is large: - Any packet the WireGuard interface delivers to the host has an **authentic inner source address**, so ordinary firewall rules on that interface can key on addresses. - A laptop cannot claim another laptop's tunnel address, because that address maps to someone else's key. - The path back is symmetric by construction. ## What allowed IPs are not - **Not the endpoint.** Allowed IPs are *inner* addresses. The endpoint is the *outer* address, and it is learned from authenticated packets, so it changes freely when a laptop moves networks. - **Not address assignment.** WireGuard hands out nothing. The operator sets the laptop's tunnel address on its interface and writes the matching `/32` on the gateway. - **Not part of the handshake.** The handshake authenticates keys. Allowed IPs act only on transport data. - **Not just a gateway setting.** On the laptop, the gateway's row decides what enters the tunnel. `0.0.0.0/0` sends every IPv4 destination to the gateway, and a narrower list sends only the office networks. Choosing between those is a split-tunnelling decision. ## Mistakes that follow from misreading it - Treating allowed IPs as an inbound filter only, then wondering why outbound traffic goes to the wrong peer. - Giving a laptop's row a wide prefix "to be safe", which lets that laptop source any address in it. - Putting a peer's public address in its allowed IPs, which confuses outer and inner addresses.

  • On a laptop, what does giving the WireGuard gateway peer allowed IPs of 0.0.0.0/0 do?
    Every IPv4 destination now matches the gateway's row, so any packet routed into the WireGuard interface is encrypted to the gateway. Inbound, the gateway may send packets with any source address. That is the paper's own example of routing all traffic through one peer. The host must still route the gateway's outer endpoint outside the tunnel, or the encrypted packets would loop back into it.
  • What happens to a packet sent into a WireGuard interface whose destination matches no peer?
    It is dropped, because no public key owns that destination and so there is no session to encrypt it with. In the paper's implementation the local sender gets an ICMP "no route to host". The same drop happens when a peer matches but no endpoint is known yet.

saying these in an interview costs you the question

  • Allowed IPs only filter what a peer may send; they play no part in choosing the peer.
  • Allowed IPs are the pool the gateway hands tunnel addresses out from, like DHCP.
  • A WireGuard packet is accepted once it decrypts, whatever inner source address it carries.
  • A peer's public endpoint address must be listed in its allowed IPs.
  • Two peers can share an allowed prefix and WireGuard load-balances between them.