tasiaiso.vulpecula.zone/docs/posts/nixos-wifi-agenix.md
2024-08-07 16:03:11 +02:00

3.2 KiB

date unlisted
2024-08-07 false

NixOS: Declarative WiFi connections with agenix and NetworkManager

Here I'll show you how to declare WiFi connections for NetworkManager in NixOS, using agenix to store encrypted pre-shared keys. Thanks to @TLATER for the answer!

The agenix part

Here I'll assume you got agenix working. If not, follow this wiki article.

Create an age-encrypted environment file so that:

  $ agenix -d crypto/nm-secrets.age
  STARLINK_PSK=MyPSKHere

Tell your NixOS config to import it:

  age.secrets.nm-secrets = {
    file = ../../crypto/nm-secrets.age;
    owner = "root";
    group = "root";
  };

Import the secrets into NixOS

Now tell NetworkManager to ensure your profile is installed. To achieve this we'll be using networking.networkmanager.ensureProfiles.profiles and networking.networkmanager.ensureProfiles.environmentFiles:

  networking.networkmanager.ensureProfiles = {
    environmentFiles = [
      config.age.secrets.nm-secrets.path
    ];
  
    profiles = {
      Starlink = {
        connection = {
          id = "Starlink";
          type = "wifi";
        };
        ipv4 = {
          method = "auto";
        };
        ipv6 = {
          addr-gen-mode = "stable-privacy";
          method = "auto";
        };
        wifi = {
          mode = "infrastructure";
          ssid = "Starlink";
        };
        wifi-security = {
          key-mgmt = "wpa-psk";
          psk = "$STARLINK_PSK";
        };
      };
    };
  };

networking.networkmanager.ensureProfiles.profiles first builds a configuration file NetworkManager can understand from the attribute set we pass it, and networking.networkmanager.ensureProfiles.environmentFiles tells NixOS to take the configuration and to substitute variable identifiers by their value stored in the nm-secrets.age file.

Adjust this configuration as needed using this documentation. Rebuild and everything should just work!

Security considerations

DISCLAIMER: I'm pretty sure what I'm saying here is accurate, but I do not have the time nor skills to check this in depth. Take what I'm saying here with a grain of salt. If I'm wrong, please send me an email containing a minimum of 3 insults.

agenix stores your secrets in an encrypted format in the publicly-available Nix store (/nix/store/*-nm-secrets.age) and exposes them in plaintext at /run/agenix.d/*/nm-secrets to root only. After decryption, the password is stored in plaintext as part of the connection configuration at /run/NetworkManager/system-connections/'Starlink'.nmconnection in a tmpfs only available to root. Additionnally, NetworkManager exposes the PSK to all members of the networkmanager group.

To me this looks like a reasonably secure way to store WiFi credentials.