== Understanding WireGuard's _AllowedIPs_ setting (and a bit of tcpdump) [[WireGuard https://www.wireguard.com/]] is usually described as a VPN, but it's really a secure IP tunnel system with VPNs as the most common use; I've been using WireGuard on Linux [[for a while WireGuardWhyISwitched]]. One of the settings you configure for WireGuard peers is _AllowedIPs_, which [[back in 2017 WireGuardEarlyNotes]] I described vaguely as that it '[...] controls which traffic is allowed to flow inside the secure tunnel'. Recently [[I had an opportunity to discover that my understanding of _AllowedIPs_ was incomplete https://twitter.com/thatcks/status/1349520500972777477]], so here is a more precise and verbose version. I'll start by quoting the current [[wg(8) https://git.zx2c4.com/wireguard-tools/about/src/man/wg.8]] manpage: > AllowedIPs — a comma-separated list of IP (v4 or v6) addresses with > CIDR masks from which incoming traffic for this peer is allowed and to > which outgoing traffic for this peer is directed. As the manual page says, _AllowedIPs_ affects both incoming traffic from your peers and outgoing traffic to your peers. For incoming traffic from a peer, the _AllowedIPs_ setting determines what source IP addresses the traffic can have. Packets from a peer that have an IP source address that's not in the peer's _AllowedIPs_ will be silently dropped by WireGuard. (WireGuard knows which peer an incoming packet is from because of the cryptography involved.) For outgoing traffic, the _AllowedIPs_ setting determines which peer a packet will be sent to, based on the packet's destination address. If there is no peer that matches the destination address, the WireGuard interface will reject the packet at the IP level, possibly generating an ICMP message to that effect that it sends to the source IP. If you're using _ping_ on the same machine, it will probably report '_ping: sendmsg: Required key not available_'. How _AllowedIPs_ affects incoming traffic is basically a safety feature; I see it as a form of firewalling. How _AllowedIPs_ affects outgoing traffic is essential, since you can have multiple peers attached to a single WireGuard interface and thus have to pick which peer a given packet will be sent to. I believe that _AllowedIPs_ can't overlap between peers on the same WireGuard interface, but I haven't tested it. (You can have multiple WireGuard interfaces, each with different peers, and I believe you can duplicate _AllowedIPs_ ranges between peers on different WireGuard interfaces. Getting the right traffic to the right WireGuard interface is up to you; you may need [[policy based routing DualIdentityRouting]] or perhaps network namespaces.) By itself, configuring _AllowedIPs_ for a peer on a particular WireGuard interface doesn't cause the Linux kernel to actually route traffic for that IP address range to the WireGuard interface; where traffic for an IP address range is routed is separate from what peers are configured. You can route traffic to a WireGuard interface without peers configured to handle it, and configure a wider _AllowedIPs_ for a peer than you route traffic to the WireGuard interface. If you're receiving WireGuard traffic, your _AllowedIPs_ doesn't restrict what destination IP addresses the traffic can have. If your peer configured its peer entry for you with an _AllowedIPs_ of 0.0.0.0/0, it can send you traffic with any random destination IP it feels like. Similarly, if you're sending WireGuard traffic to a peer, that traffic can have any source IP address you want, although the peer will drop it if it's not in their _AllowedIPs_ for you. If you use '_tcpdump_' on a WireGuard interface to test all of this, the traffic you see is conceptually outside WireGuard itself. For outgoing packets, what you see is before WireGuard has picked which peer the packet will be sent to or rejected it because no peer matches. For incoming packets, what you see is after WireGuard has dropped packets for having a source IP that doesn't match the peer's _AllowedIPs_. This means that outgoing packets may not actually be sent, but incoming packets have definitely been accepted (well, by WireGuard). (I don't know if there's any easy way to see if WireGuard has dropped some incoming packets because they don't match the peer's _AllowedIPs_. I suppose you could try to correlate the arrival of encrypted WireGuard packets from a peer's current IP with a lack of packets showing up on the WireGuard interface.)