Systemd-networkd can't read wireguard key

Here’s the config of my wireguard interface:

{ ... }:
let
  wgIpv4 = "10.2.0.2";
  wgDns = "10.2.0.1";
  wgEndpoint = "146.70.198.2";
  wgPubkey = "aQ2NoOYEObG9tDMwdc4VxK6hjW+eA0PLfgbH7ffmagU=";
in
{
  networking.useNetworkd = true;
  services.resolved.enable = true;
  users.users."systemd-network".extraGroups = [ "keys" ];

  systemd.network = {
    enable = true;
    netdevs.wireguard = {
      netdevConfig = {
        Kind = "wireguard";
        Name = "wg0";
        MTUBytes = "1440";
      };
      wireguardConfig = {
        PrivateKeyFile = "/run/keys/wireguard-privkey";
      };
      wireguardPeers = [{
        PublicKey = wgPubkey;
        Endpoint = "${wgEndpoint}:51820";
        AllowedIPs = [ "0.0.0.0/0" "::/0" ];
        PersistentKeepalive = 25;
      }];
    };
    networks.wireguard = {
      matchConfig.Name = "wg0";
      address = [ "${wgIpv4}/32" ];
      dns = [ wgDns ];
      networkConfig.DNSDefaultRoute = true;
      routes = [
        {
          Gateway = wgDns;
          Destination = "0.0.0.0/0";
          GatewayOnLink = true;
        }
      ];
    };
  };
}

/run/keys is owned by root:keys (as per default) and has its access set to 750:

# ls -hdl /run/keys/
drwxr-x--- 2 root keys 0 Dec 15 12:52 /run/keys/

/run/keys/wireguard-privkey is set up as follows (root:keys ownership didn’t work, either):

# ls -hl /run/keys/
total 4.0K
-rw-r----- 1 systemd-network keys 46 Dec 15 12:52 wireguard-privkey

I verified that systemd-network can access the file:

$ sudo -u systemd-network stat /run/keys/wireguard-privkey
  File: /run/keys/wireguard-privkey
  Size: 46        	Blocks: 8          IO Block: 4096   regular file
Device: 0,26	Inode: 667834      Links: 1
Access: (0600/-rw-------)  Uid: (  152/systemd-network)   Gid: (   96/    keys)
Access: 2024-12-15 13:20:12.064103985 +0100
Modify: 2024-12-15 12:52:33.275369299 +0100
Change: 2024-12-15 13:20:07.988835817 +0100
 Birth: -

But no matter what I try, I keep getting this error:

systemd-networkd[34312]: wg0: Failed to read private key from /run/keys/wireguard-privkey. Ignoring network device.

Can anyone tell me why, or help me triage this?

Cheers

The issue should be fixed on the latest nixos-unstable channel: Nixpkgs PR #364078 ("nixos/wireguard-networkd: use systemd credentials for privateKeyFile and presharedKeyFile") progress

Alternatively, networking.wireguard.useNetworkd = false; should also help.

Edit: disregard that, you aren’t using wireguard module.

But yes, you can try networking.wireguard.interfaces option if you’re on nixos-unstable, it uses networkd as backend now when networking.useNetworkd = true; is set.

I’m on stable, though. What does it use then?

Which stable?​​​​​​​

Technically there’s only one stable version. The old ones are deprecated. I’m on 24.11.

What does it use then?

It’s a bunch of bash scripts started as root by systemd: nixpkgs/nixos/modules/services/networking/wireguard.nix at 314e12ba369ccdb9b352a4db26ff419f7c49fa84 · NixOS/nixpkgs · GitHub

This backend will probably be removed at some point once the migration to networkd is complete

It’s probably doesn’t have access to /run/keys because of ProtectSystem=strict. Maybe setting ReadOnlyPaths=/run/keys will help.

Oh, that sounds helpful. So I’d need to create an override for systemd-networkd. I don’t see anything helpful in the options and

  systemd.services."systemd-networkd".serviceConfig = { ReadOnlyPaths = "/run/keys"; };

did create an entry in the respective overrides.conf, but that didn’t do the trick.

Try systemd.services.systemd-networkd.serviceConfig.ReadOnlyPaths = "/run/keys";

Yea, just noticed I had addressed a different service. Edited my previous reply.

Tried

  systemd.services."systemd-networkd".serviceConfig.ReadOnlyPaths = "/run/keys/wireguard-privkey";

too, just to be sure, but keep getting the same error.

Weird… Maybe disabling ProtectSystem will help ensuring that it is actually a reason why it doesn’t work… Probably something like systemd.services.systemd-networkd.serviceConfig.ProtectSystem = lib.mkForce false;

Same error. I did not reboot with those values, btw. Only ran nixos-rebuild test. But since the override.conf was changed the effect should be the same. Even ran systemctl daemon-reload, just to be sure.

Then most likely it’s not ProtectSystem, but something else

I tried enabling debug logging, but it didn’t shed any additional light. Figured I might as well share the debug log up to the wireguard interface failing:

systemd-networkd[70405]: Bus bus-api-network: changing state UNSET → OPENING
systemd-networkd[70405]: sd-bus: starting bus bus-api-network by connecting to /run/dbus/system_bus_socket...
systemd-networkd[70405]: Bus bus-api-network: changing state OPENING → AUTHENTICATING
systemd-networkd[70405]: Registering bus object implementation for path=/org/freedesktop/network1 iface=org.freedesktop.network1.Manager
systemd-networkd[70405]: Registering bus object implementation for path=/org/freedesktop/network1/link iface=org.freedesktop.network1.Link
systemd-networkd[70405]: Registering bus object implementation for path=/org/freedesktop/network1/link iface=org.freedesktop.network1.DHCPServer
systemd-networkd[70405]: Registering bus object implementation for path=/org/freedesktop/network1/link iface=org.freedesktop.network1.DHCPv4Client
systemd-networkd[70405]: Registering bus object implementation for path=/org/freedesktop/network1/link iface=org.freedesktop.network1.DHCPv6Client
systemd-networkd[70405]: Registering bus object implementation for path=/org/freedesktop/network1/network iface=org.freedesktop.network1.Network
systemd-networkd[70405]: Registering bus object implementation for path=/org/freedesktop/LogControl1 iface=org.freedesktop.LogControl1
systemd-networkd[70405]: sd-device-monitor(n/a): Failed to stat PID1's netns, ignoring: No such file or directory
systemd-networkd[70405]: wg0: Failed to read private key from /run/keys/wireguard-privkey. Ignoring network device.

Turns out I had accidentally modified my private key. With it no longer decoding from base64 there was no way to make it work. New key did the trick.

1 Like