What does wg-quick nftables rules do?

When I add a wireguard interface via wg-quick up wg0, wg-quick sets up the following nftable rules. What are these doing and why are they needed?

Here are some example rules for ipv4:

table ip wg-quick-wg0 {
    chain preraw {
        type filter hook prerouting priority raw; policy accept;
        iifname != "wg0" ip daddr 10.4.125.231 fib saddr type != local drop
    }
    chain premangle {
        type filter hook prerouting priority mangle; policy accept;
        meta l4proto 17 meta mark set ct mark
    }
    chain postmangle {
        type filter hook postrouting priority mangle; policy accept;
        meta l4proto 17 meta mark 0x0000ca6c ct mark set meta mark
    }
}

I am interested in these, because my virtual machine needs those to function properly, but my host does not need them to have a working wireguard interface. Sadly the script itself is not documented on why they are setup.


The wg-quick script sets up these rules only when you configure the AllowedIPs of a WireGuard peer to include /0 -- aka "all addresses" or the "default route" for an address family (0.0.0.0/0 for IPv4 and ::/0 for IPv6).

Using a tunnel like WireGuard for a default route requires some tricks to work correctly in most scenarios. The main trick wg-quick uses is to put the new default route into a custom routing table, while adding policy routing rules with a firewall mark to overide only the default route of the main table. This is the purpose for the route and policy rules you'll see wg-quick set up in this case:

[#] ip -4 route add 0.0.0.0/0 dev wg0 table 51820
[#] ip -4 rule add not fwmark 51820 table 51820
[#] ip -4 rule add table main suppress_prefixlength 0

The firewall rules listed in your question help with a few additional edge cases: The first rule prevents certain routing loops and other issues when packets are sent to the WireGuard interface's address outside of the tunnel; and the second and third rules fix up reverse-path lookups for packets received through the tunnel (allowing reverse-path filtering to work).

If you don't want wg-quick to do these things, you can set Table = off in the [Interface] section of your WireGuard configuration, and set up the appropriate routes yourself. For more details about these routing tricks, see the Routing All Your Traffic section of the routing guide on the WireGuard site, or the Understanding Modern Linux Routing article. See the Wg-quick Default Firewall Rules article for more details about these firewall rules specifically.