Wireguard AllowedIPs caveats


I recently tried out wireguard. The AllowedIPs setting confused me a bit. The name, many blog posts and some parts of the documentation mention that this setting is some kind of source IP address filter.

But when you have 2 peers in a config that have all addresses allowed you will get errors. An example config for that could look like this (pls forgive me for only using legacy IP in this example):

PrivateKey = < priv key here >
ListenPort = 51820

Endpoint =
PublicKey = zfiU3b7CSyTiGZ9YIAOyvKgDHsFsL78Vij6kB9615ys=
AllowedIPs =

Endpoint =
PublicKey = X++p6RAoYuGE0GXiDI+bJbsS0kI9odzwIUpef5nVKRo=
AllowedIPs =

If the interface is running and you enter a wg show, the result has no AllowedIPs for the first peer.

interface: wg-p2p
  public key: EfGMYv8Vd3DPLzyAKeMtDe6FzU+EVangtMRnkC+urik=
  private key: (hidden)
  listening port: 51820

peer: zfiU3b7CSyTiGZ9YIAOyvKgDHsFsL78Vij6kB9615ys=
  allowed ips: (none)
  latest handshake: 1 minute, 59 seconds ago
  transfer: 180 B received, 284 B sent

peer: X++p6RAoYuGE0GXiDI+bJbsS0kI9odzwIUpef5nVKRo=
  allowed ips:
  transfer: 0 B received, 3.47 KiB sent

This is because the AllowedIPs setting is not only used as a source filter. It is also how wireguard decides to which peer a packet is send. A packet is send to the peer which has the destination address in its AllowedIPs.

The AllowedIPs of peers on an interface can not overlap because wireguard does not know which of the multiple peers it has to choose. Each address can only be used once for each interface. Wireguard does not do routing itself! Adding a longer prefix in the AllowedIPs does not mean that only this peer will receive the traffic. It means that you have overlapping addresses configured.

The routing is still done by the linux kernel. The regular routing table needs an entry to send some traffic via the wireguard interface. Only if the routing table decides to send traffic via the wireguard interface the peer config comes into play.

This also means that if you want to build point to point links with wireguard for e.g. for an encrypted, routed backbone you have to create one interface per link. (And not one interface with many peers.)