wireguard: support configuring policy routing to avoid routing loops

System Internals / NetworkManager - Thomas Haller [redhat.com] - 29 July 2019 18:45 EDT

For WireGuard (like for all IP-tunnels and IP-based VPNs), the IP addresses of the peers must be reached outside the tunnel/VPN itself.

For VPN connections, NetworkManager usually adds a direct /32 route to the external VPN gateway to the underlying device. For WireGuard that is not done, because injecting a route to another device is ugly and error prone. Worse: WireGuard with automatic roaming and multiple peers makes this more complicated.

This is commonly a problem when setting the default-route via the VPN, but there are also other subtle setups where special care must be taken to prevent such routing loops.

WireGuard's wg-quick provides a simple, automatic solution by adding two policy routing rules and relying on the WireGuard packets having a fwmark set (see [1]).

Let's also do that. Add new properties "wireguard.ip4-auto-default-route" and "wireguard.ip6-auto-default-route" to enable/disable this. Note that the default value lets NetworkManager automatically choose whether to enable it (depending on whether there are any peers that have a default route). This means, common scenarios should now work well without additional configuration.

Note that this is also a change in behavior and upon package upgrade NetworkManager may start adding policy routes (if there are peers that have a default-route). This is a change in behavior, as the user already clearly had this setup working and configured some working solution already.

The new automatism picks the rule priority automatically and adds the default-route to the routing table that has the same number as the fwmark. If any of this is unsuitable, then the user is free to disable this automatism. Note that since 1.18.0 NetworkManager supports policy routing (*). That means, what this automatism does can be also achieved via explicit configuration of the profile, which gives the user more flexibility to adjust all parameters explicitly).

(*) but only since 1.20.0 NetworkManager supports the "suppress_prefixlength" rule attribute, which makes it impossible to configure exactly this rule-based solution with 1.18.0 NetworkManager.

[1] https://www.wireguard.com/netns/#improved-rule-based-routing

10e05bf8a wireguard: support configuring policy routing to avoid routing loops
clients/common/nm-meta-setting-desc.c | 6 +
clients/common/settings-docs.h.in | 4 +-
libnm-core/nm-setting-sriov.c | 2 +-
libnm-core/nm-setting-wireguard.c | 92 +++++++
libnm-core/nm-setting-wireguard.h | 8 +
libnm/libnm.ver | 2 +
src/devices/nm-device-wireguard.c | 446 +++++++++++++++++++++++++++++++++-
src/devices/nm-device.c | 6 +
8 files changed, 559 insertions(+), 7 deletions(-)

Upstream: cgit.freedesktop.org

  • Share