Wg0: Failed to read private key

Hi,

I am using a very similar configuration to what is told on
https://nixos.wiki/wiki/WireGuard#Setting_up_WireGuard_with_systemd-networkd

I used nixos-infect on a system, so it uses the old networking.interfaces etc for the network configuration, but I added networking.useNetworkd = true; to get it working system working with systemd-networkd.

My wireguard config is:

wireguardConfig = {
          PrivateKeyFile = "/run/keys/wireguard-privkey";
          ListenPort = 51820;
        };

And I set up the keyfiles exactly as described in man systemd.netdev
so:

> ll /run/keys/wireguard-privkey
-rw-r----- 1 root systemd-network 45 Aug  8 19:51 /run/keys/wireguard-privkey

I generated the keys in the standard way:
wg genkey > /run/keys/wireguard-privkey

I see the kernel module is loaded:

lsmod | grep wire
wireguard              98304  0
curve25519_x86_64      36864  1 wireguard
libchacha20poly1305    16384  1 wireguard
libcurve25519_generic    49152  2 curve25519_x86_64,wireguard
ip6_udp_tunnel         16384  1 wireguard
udp_tunnel             20480  1 wireguard

But no matter what I do I always get:

...
Starting Network Configuration...
Aug 08 20:03:59 spalf systemd-networkd[27228]: wg0: Failed to read private key from /run/keys/wireguard-privkey. Ignoring network device.
Aug 08 20:03:59 spalf systemd-networkd[27228]: lo: Link UP
...

When restarting systemd-networkd
I can see the error must be coming from here:
https://git.progress-linux.org/packages/fuchur-backports/systemd/tree/src/network/netdev/wireguard.c?h=upstream/251_rc2&id=7dcba4b07ba9120262c2359248409dc459efb054#n1133

But does anyone have any clue what could be causing this?

Have you tried giving ownership of the key file to the systemd-networkd user?

Yes, I’ve also just tried chmod 777 with no avail

What are the permissions of /run/keys ?

ll /run | grep keys
drwxr-x---  2 root keys    0 Aug  8 19:46 keys

ah so yes, it seemed to be the parent directory.
next problem is my server seems to be unreachable after wireguard properly running xD

A user needs execute bit on a directory in order to access files inside of it.

@spalf I’m having the same problems with the key.
Could you explain exactly what the permissions need to be on the file/parent-directory?

Thank you.

Ok, looks like

chown root:systemd-network /run/keys

fixed it.

I’m a bit of a newbie, hope nothing else breaks :smiley:

This is the correct fix. The systemd-networkd user needs access to the key.

1 Like

For posterity: I ran into a similar issue with sops-nix. By adding the user systemd-network to the group keys (which is the group that sops-nix assigns to the directories that contain secrets), I was able to resolve it, without chown.

{
  users.users."systemd-network".extraGroups = [ "keys" ];
}
1 Like

For reference, from systemd 256 onwards (which is the version on nixos-unstable), you can set a credential on the systemd-networkd service with a specific name, pointing to the private key file, which will automatically be used for the private key of the corresponding wireguard interface. The credentials are loaded as root, so no need anymore to change permissions on the actual secret files.

This would look something like this:

systemd = {
  services.systemd-networkd.serviceConfig.LoadCredential =
    # See https://www.freedesktop.org/software/systemd/man/latest/systemd.netdev.html#PrivateKey=
    [ "network.wireguard.private.20-wg:${config.sops.secrets.wg-priv-key.path}" ]:

  network = {
    netdevs."20-wg" = {
      netdevConfig = {
        Name = "wg";
        Kind = "wireguard";
      };
      wireguardPeers = [ ... ];
  };
};
2 Likes

This didn’t seem to work for me. My permissions look like:

> ls -l /run/secrets
lrwxrwxrwx root root 16 B Tue Aug 20 18:26:02 2024  /run/secrets ⇒ /run/secrets.d/1

So /run/secrets does not have the keys group owner. However, /run/secrets.d does. I’m not sure how symlinks work w.r.t. ownership.