Can't get usable wireguard interface with networkd

I want to set up a wireguard client to connect to ProtonVPN. With wg-quick it works and I get a usable interface. With networkd, my preferred solution, I get an interface I can’t even send a ping over. My current configuration was informed by wg2nd and looks like this:

{ ... }:
let
  wgIpv4 = "10.2.0.2";
  wgDns = "10.2.0.1";
  wgEndpoint = "79.135.105.1";
  wgPubkey = "RY8jot0tZvug/zGd4SDBa5yFlMvhzYEto55QfMPSTG0=";
  wgFwMark = 4084113581;
  wgTable = 4084113581;
in
{
  networking.useNetworkd = true;
  services.resolved.enable = true;
  systemd.network = {
    enable = true;
    netdevs."80-wireguard" = {
      netdevConfig = {
        Kind = "wireguard";
        Name = "wg0";
        MTUBytes = "1420";
      };
      wireguardConfig = {
        FirewallMark = wgFwMark;
      };
      wireguardPeers = [{
        PublicKey = wgPubkey;
        Endpoint = "${wgEndpoint}:51820";
        AllowedIPs = [ "0.0.0.0/0" "::/0" ];
      }];
    };
    networks."80-wireguard" = {
      matchConfig.Name = "wg0";
      address = [ "${wgIpv4}/32" ];
      dns = [ wgDns ];
      networkConfig.DNSDefaultRoute = true;
      domains = [ "~." ];
      routes = [
        {
          Gateway = wgDns;
          Destination = "0.0.0.0/0";
          Table = wgTable;
          GatewayOnLink = true;
        }
      ];
      routingPolicyRules = [
        {
          SuppressPrefixLength = 0;
          Family = "ipv4";
          Table = "main";
          Priority = 32764;
        }
        {
          FirewallMark = wgFwMark;
          InvertRule = true;
          Table = wgTable;
          Family = "ipv4";
          Priority = 32765;
        }
      ];
    };
  };
  boot.kernel.sysctl = { "net.ipv4.conf.all.src_valid_mark" = 1; };
}

And should, as far as I can tell, be identical to the configuration and interface wg-quick produces.
Here is the stdout of wg-quick for reference:

$ sudo wg-quick up Code/nixos/wg-AF-2.conf 
Warning: `/home/chais/Code/nixos/wg-AF-2.conf' is world accessible
[#] ip link add wg-AF-2 type wireguard
[#] wg setconf wg-AF-2 /dev/fd/63
[#] ip -4 address add 10.2.0.2/32 dev wg-AF-2
[#] ip link set mtu 1420 up dev wg-AF-2
[#] resolvconf -a wg-AF-2 -m 0 -x
[#] wg set wg-AF-2 fwmark 51820
[#] ip -4 route add 0.0.0.0/0 dev wg-AF-2 table 51820
[#] ip -4 rule add not fwmark 51820 table 51820
[#] ip -4 rule add table main suppress_prefixlength 0
[#] sysctl -q net.ipv4.conf.all.src_valid_mark=1
[#] iptables-restore -n

Except, of course, it doesn’t actually work, but doesn’t throw an obvious error.
Here are the logs of wg-quick up and wg-quick down:

---< wg-quick up >---
Dec 17 13:31:20 nufta systemd-networkd[164898]: wg-AF-2: Saved new link: ifindex=5, iftype=NONE(65534), kind=wireguard
Dec 17 13:31:20 nufta systemd-networkd[164898]: wg-AF-2: Saved original MTU 1420 (min: 0, max: 2147483552)
Dec 17 13:31:20 nufta systemd-networkd[164898]: wg-AF-2: Saved IPv6 link-local address generation mode: eui64
Dec 17 13:31:20 nufta systemd-networkd[164898]: wg-AF-2: Flags change: +POINTOPOINT +NOARP
Dec 17 13:31:20 nufta systemd-networkd[164898]: Sent message type=signal sender=n/a destination=n/a path=/org/freedesktop/network1/link/_35 interface=org.freedesktop.DBus.Properties member=PropertiesChanged cookie=34 reply_cookie=0 signature=sa{sv}as error-name=n/a error-message=n/a
Dec 17 13:31:20 nufta systemd-networkd[164898]: wg-AF-2: link pending udev initialization...
Dec 17 13:31:20 nufta systemd-networkd[164898]: wg-AF-2: Received new foreign address (configured): 10.2.0.2/32 (valid forever, preferred forever), flags: permanent, scope: global, label: n/a
Dec 17 13:31:20 nufta systemd-networkd[164898]: Sent message type=signal sender=n/a destination=n/a path=/org/freedesktop/network1/link/_35 interface=org.freedesktop.DBus.Properties member=PropertiesChanged cookie=35 reply_cookie=0 signature=sa{sv}as error-name=n/a error-message=n/a
Dec 17 13:31:20 nufta systemd-networkd[164898]: wg-AF-2: link_check_ready(): link is in pending state.
Dec 17 13:31:20 nufta systemd-networkd[164898]: wg-AF-2: Received new foreign route (configured): dst: 10.2.0.2/32, src: n/a, gw: n/a, prefsrc: 10.2.0.2, table: local(255), priority: 0, proto: kernel, scope: host, type: local, flags: n/a
Dec 17 13:31:20 nufta systemd-networkd[164898]: wg-AF-2: IPv6 link-local address generation mode is changed: eui64 -> none
Dec 17 13:31:20 nufta systemd-networkd[164898]: wg-AF-2: Flags change: +UP +LOWER_UP +RUNNING
Dec 17 13:31:20 nufta systemd-networkd[164898]: Sent message type=signal sender=n/a destination=n/a path=/org/freedesktop/network1/link/_35 interface=org.freedesktop.DBus.Properties member=PropertiesChanged cookie=36 reply_cookie=0 signature=sa{sv}as error-name=n/a error-message=n/a
Dec 17 13:31:20 nufta systemd-networkd[164898]: wg-AF-2: Link UP
Dec 17 13:31:20 nufta systemd-networkd[164898]: wg-AF-2: Gained carrier
Dec 17 13:31:20 nufta systemd-networkd[164898]: wg-AF-2: Received new foreign route (configured): dst: ff00::/8, src: n/a, gw: n/a, prefsrc: n/a, table: local(255), priority: 256, proto: kernel, scope: global, type: multicast, flags: n/a
Dec 17 13:31:20 nufta systemd-networkd[164898]: wg-AF-2: udev initialized link
Dec 17 13:31:20 nufta systemd-networkd[164898]: wg-AF-2: Found driver: wireguard
Dec 17 13:31:20 nufta systemd-networkd[164898]: wg-AF-2: Link state is up-to-date
Dec 17 13:31:20 nufta systemd-networkd[164898]: wg-AF-2: State changed: pending -> initialized
Dec 17 13:31:20 nufta systemd-networkd[164898]: Sent message type=signal sender=n/a destination=n/a path=/org/freedesktop/network1/link/_35 interface=org.freedesktop.DBus.Properties member=PropertiesChanged cookie=37 reply_cookie=0 signature=sa{sv}as error-name=n/a error-message=n/a
Dec 17 13:31:20 nufta systemd-networkd[164898]: wg-AF-2: Unmanaging interface.
Dec 17 13:31:20 nufta systemd-networkd[164898]: wg-AF-2: State changed: initialized -> unmanaged
Dec 17 13:31:20 nufta systemd-networkd[164898]: Sent message type=signal sender=n/a destination=n/a path=/org/freedesktop/network1/link/_35 interface=org.freedesktop.DBus.Properties member=PropertiesChanged cookie=38 reply_cookie=0 signature=sa{sv}as error-name=n/a error-message=n/a
Dec 17 13:31:20 nufta systemd-networkd[164898]: wg-AF-2: Received new foreign route (configured): dst: n/a, src: n/a, gw: n/a, prefsrc: n/a, table: 51820, priority: 0, proto: boot, scope: link, type: unicast, flags: n/a
Dec 17 13:31:20 nufta systemd-networkd[164898]: Remembering foreign routing policy rule (configured): priority: 32765, 0.0.0.0/0 -> 0.0.0.0/0, iif: n/a, oif: n/a, table: 51820
Dec 17 13:31:20 nufta systemd-networkd[164898]: Remembering foreign routing policy rule (configured): priority: 32764, 0.0.0.0/0 -> 0.0.0.0/0, iif: n/a, oif: n/a, table: main(254)
---< wg-quick down >---
Dec 17 13:36:06 nufta systemd-networkd[164898]: Forgetting foreign routing policy rule (n/a): priority: 32765, 0.0.0.0/0 -> 0.0.0.0/0, iif: n/a, oif: n/a, table: 51820
Dec 17 13:36:06 nufta systemd-networkd[164898]: Forgetting foreign routing policy rule (n/a): priority: 32764, 0.0.0.0/0 -> 0.0.0.0/0, iif: n/a, oif: n/a, table: main(254)
Dec 17 13:36:06 nufta systemd-networkd[164898]: wg-AF-2: Flags change: -UP -LOWER_UP -RUNNING
Dec 17 13:36:06 nufta systemd-networkd[164898]: Sent message type=signal sender=n/a destination=n/a path=/org/freedesktop/network1/link/_35 interface=org.freedesktop.DBus.Properties member=PropertiesChanged cookie=39 reply_cookie=0 signature=sa{sv}as error-name=n/a error-message=n/a
Dec 17 13:36:06 nufta systemd-networkd[164898]: wg-AF-2: Link DOWN
Dec 17 13:36:06 nufta systemd-networkd[164898]: wg-AF-2: Lost carrier
Dec 17 13:36:06 nufta systemd-networkd[164898]: wg-AF-2: Forgetting removed foreign route (n/a): dst: ff00::/8, src: n/a, gw: n/a, prefsrc: n/a, table: local(255), priority: 256, proto: kernel, scope: global, type: multicast, flags: n/a
Dec 17 13:36:06 nufta systemd-networkd[164898]: wg-AF-2: Forgetting removed foreign address (n/a): 10.2.0.2/32 (valid forever, preferred forever), flags: permanent, scope: global, label: n/a
Dec 17 13:36:06 nufta systemd-networkd[164898]: Sent message type=signal sender=n/a destination=n/a path=/org/freedesktop/network1/link/_35 interface=org.freedesktop.DBus.Properties member=PropertiesChanged cookie=40 reply_cookie=0 signature=sa{sv}as error-name=n/a error-message=n/a
Dec 17 13:36:06 nufta systemd-networkd[164898]: wg-AF-2: link_check_ready(): link is in unmanaged state.
Dec 17 13:36:06 nufta systemd-networkd[164898]: wg-AF-2: Forgetting removed foreign route (n/a): dst: 10.2.0.2/32, src: n/a, gw: n/a, prefsrc: 10.2.0.2, table: local(255), priority: 0, proto: kernel, scope: host, type: local, flags: n/a
Dec 17 13:36:06 nufta systemd-networkd[164898]: wg-AF-2: State changed: unmanaged -> linger
Dec 17 13:36:06 nufta systemd-networkd[164898]: Sent message type=signal sender=n/a destination=n/a path=/org/freedesktop/network1/link/_35 interface=org.freedesktop.DBus.Properties member=PropertiesChanged cookie=41 reply_cookie=0 signature=sa{sv}as error-name=n/a error-message=n/a
Dec 17 13:36:06 nufta systemd-networkd[164898]: wg-AF-2: Failed to get link from ifindex 5, ignoring: No such device

and the logs of networkd

---< systemctl restart systemd-networkd >---
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: Found driver: wireguard
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: Link state is up-to-date
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: State changed: pending -> initialized
Dec 17 13:53:47 nufta systemd-networkd[169912]: Sent message type=signal sender=n/a destination=n/a path=/org/freedesktop/network1/link/_34 interface=org.freedesktop.DBus.Properties member=PropertiesChanged cookie=13 reply_cookie=0 signature=sa{sv}as error-name=n/a error-message=n/a
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: found matching network '/etc/systemd/network/80-wireguard.network'.
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: Configuring with /etc/systemd/network/80-wireguard.network.
Dec 17 13:53:47 nufta systemd-networkd[169912]: Sent message type=signal sender=n/a destination=n/a path=/org/freedesktop/network1/link/_34 interface=org.freedesktop.DBus.Properties member=PropertiesChanged cookie=14 reply_cookie=0 signature=sa{sv}as error-name=n/a error-message=n/a
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: State changed: initialized -> configuring
Dec 17 13:53:47 nufta systemd-networkd[169912]: Sent message type=signal sender=n/a destination=n/a path=/org/freedesktop/network1/link/_34 interface=org.freedesktop.DBus.Properties member=PropertiesChanged cookie=15 reply_cookie=0 signature=sa{sv}as error-name=n/a error-message=n/a
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: link_check_ready(): link is not activated.
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: link_check_ready(): link is not activated.
Dec 17 13:53:47 nufta systemd-networkd[169912]: Setting '/proc/sys/net/ipv6/conf/wg0/use_tempaddr' to '0'
Dec 17 13:53:47 nufta systemd-networkd[169912]: No change in value '0', suppressing write
Dec 17 13:53:47 nufta systemd-networkd[169912]: Setting '/proc/sys/net/ipv6/conf/wg0/accept_ra' to '0'
Dec 17 13:53:47 nufta systemd-networkd[169912]: No change in value '0', suppressing write
Dec 17 13:53:47 nufta systemd-networkd[169912]: Setting '/proc/sys/net/ipv6/conf/wg0/proxy_ndp' to '0'
Dec 17 13:53:47 nufta systemd-networkd[169912]: No change in value '0', suppressing write
Dec 17 13:53:47 nufta systemd-networkd[169912]: Setting '/proc/sys/net/ipv4/conf/wg0/promote_secondaries' to '1'
Dec 17 13:53:47 nufta systemd-networkd[169912]: No change in value '1', suppressing write
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: link_check_ready(): link is not activated.
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: Requested to activate link
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: Requesting static address (n/a): 10.2.0.2/32 (valid forever, preferred forever), flags: n/a, scope: global, label: n/a
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: Setting addresses
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: link_check_ready(): link is not activated.
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: link_check_ready(): link is not activated.
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: link_check_ready(): link is not activated.
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: link_check_ready(): link is not activated.
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: link_check_ready(): link is not activated.
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: link_check_ready(): link is not activated.
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: Requesting static route (n/a): dst: n/a, src: n/a, gw: 10.2.0.1, prefsrc: n/a, table: main(254), priority: 0, proto: static, scope: global, type: unicast, flags: onlink
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: Requesting routes
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: link_check_ready(): link is not activated.
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: Bringing link up
---< other interfaces initialising >---
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: Flags change: +UP +LOWER_UP +RUNNING
Dec 17 13:53:47 nufta systemd-networkd[169912]: Sent message type=signal sender=n/a destination=n/a path=/org/freedesktop/network1/link/_34 interface=org.freedesktop.DBus.Properties member=PropertiesChanged cookie=16 reply_cookie=0 signature=sa{sv}as error-name=n/a error-message=n/a
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: Link UP
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: Gained carrier
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: found matching network '/etc/systemd/network/80-wireguard.network'.
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: Setting addresses
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: link_check_ready(): link is not activated.
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: link_check_ready(): link is not activated.
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: link_check_ready(): link is not activated.
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: link_check_ready(): link is not activated.
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: link_check_ready(): link is not activated.
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: link_check_ready(): link is not activated.
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: Requesting static route (n/a): dst: n/a, src: n/a, gw: 10.2.0.1, prefsrc: n/a, table: main(254), priority: 0, proto: static, scope: global, type: unicast, flags: onlink
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: Requesting routes
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: link_check_ready(): link is not activated.
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: found matching network '/etc/systemd/network/80-wireguard.network'.
Dec 17 13:53:47 nufta systemd-networkd[169912]: enp13s0: Received remembered foreign route (configured): dst: ff00::/8, src: n/a, gw: n/a, prefsrc: n/a, table: local(255), priority: 256, proto: kernel, scope: global, type: multicast, flags: n/a
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: link_check_ready(): static addresses are not configured.
---< other interfaces coming up >---
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: Configuring static address (requesting): 10.2.0.2/32 (valid forever, preferred forever), flags: n/a, scope: global, label: n/a
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: Configuring static route (requesting): dst: n/a, src: n/a, gw: 10.2.0.1, prefsrc: n/a, table: main(254), priority: 0, proto: static, scope: global, type: unicast, flags: onlink
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: Received new static address (configured): 10.2.0.2/32 (valid forever, preferred forever), flags: permanent, scope: global, label: n/a
Dec 17 13:53:47 nufta systemd-networkd[169912]: Using nftables as firewall backend.
Dec 17 13:53:47 nufta systemd-networkd[169912]: Sent message type=signal sender=n/a destination=n/a path=/org/freedesktop/network1/link/_34 interface=org.freedesktop.DBus.Properties member=PropertiesChanged cookie=18 reply_cookie=0 signature=sa{sv}as error-name=n/a error-message=n/a
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: link_check_ready(): static addresses are not configured.
Dec 17 13:53:47 nufta systemd-networkd[169912]: Sent message type=signal sender=n/a destination=n/a path=/org/freedesktop/network1 interface=org.freedesktop.DBus.Properties member=PropertiesChanged cookie=19 reply_cookie=0 signature=sa{sv}as error-name=n/a error-message=n/a
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: Received new foreign route (configured): dst: 10.2.0.2/32, src: n/a, gw: n/a, prefsrc: 10.2.0.2, table: local(255), priority: 0, proto: kernel, scope: host, type: local, flags: n/a
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: Addresses set
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: link_check_ready(): static routes are not configured.
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: Received new static route (configured): dst: n/a, src: n/a, gw: 10.2.0.1, prefsrc: n/a, table: main(254), priority: 0, proto: static, scope: global, type: unicast, flags: onlink
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: Routes set
Dec 17 13:53:47 nufta systemd-networkd[169912]: wg0: State changed: configuring -> configured
---< networkctl down wg0 >---
Dec 17 13:58:11 nufta systemd-networkd[169912]: wg0: Flags change: -UP -LOWER_UP -RUNNING
Dec 17 13:58:11 nufta systemd-networkd[169912]: Sent message type=signal sender=n/a destination=n/a path=/org/freedesktop/network1/link/_34 interface=org.freedesktop.DBus.Properties member=PropertiesChanged cookie=31 reply_cookie=0 signature=sa{sv}as error-name=n/a error-message=n/a
Dec 17 13:58:11 nufta systemd-networkd[169912]: wg0: Link DOWN
Dec 17 13:58:11 nufta systemd-networkd[169912]: wg0: Lost carrier
Dec 17 13:58:11 nufta systemd-networkd[169912]: wg0: Removing static route (configured,marked): dst: n/a, src: n/a, gw: 10.2.0.1, prefsrc: n/a, table: main(254), priority: 0, proto: static, scope: global, type: unicast, flags: onlink
Dec 17 13:58:11 nufta systemd-networkd[169912]: wg0: Removing static address (configured): 10.2.0.2/32 (valid forever, preferred forever), flags: permanent, scope: global, label: n/a
Dec 17 13:58:11 nufta systemd-networkd[169912]: Sent message type=signal sender=n/a destination=n/a path=/org/freedesktop/network1/link/_34 interface=org.freedesktop.DBus.Properties member=PropertiesChanged cookie=32 reply_cookie=0 signature=sa{sv}as error-name=n/a error-message=n/a
Dec 17 13:58:11 nufta systemd-networkd[169912]: wg0: found matching network '/etc/systemd/network/80-wireguard.network'.
Dec 17 13:58:11 nufta systemd-networkd[169912]: enp13s0: Forgetting removed foreign route (n/a): dst: ff00::/8, src: n/a, gw: n/a, prefsrc: n/a, table: local(255), priority: 256, proto: kernel, scope: global, type: multicast, flags: n/a
Dec 17 13:58:11 nufta systemd-networkd[169912]: Could not drop route, ignoring: No such process
Dec 17 13:58:11 nufta systemd-networkd[169912]: wg0: Forgetting static route (configured,removing): dst: n/a, src: n/a, gw: 10.2.0.1, prefsrc: n/a, table: main(254), priority: 0, proto: static, scope: global, type: unicast, flags: onlink
Dec 17 13:58:11 nufta systemd-networkd[169912]: wg0: Forgetting removed static address (n/a): 10.2.0.2/32 (valid forever, preferred forever), flags: permanent, scope: global, label: n/a
Dec 17 13:58:11 nufta systemd-networkd[169912]: wg0: Forgetting removed foreign route (n/a): dst: 10.2.0.2/32, src: n/a, gw: n/a, prefsrc: 10.2.0.2, table: local(255), priority: 0, proto: kernel, scope: host, type: local, flags: n/a

The only thing that stands out to me are the messages about static routes not being configured.

1 Like