Wireless network configuration parameters hidding

After updating my config to the latest unstable nixpkgs, I saw that there were a few changes required for the networking.wireless.networks option.

Before updating, I was able to store the SSID, password/passphrase and EAP identity of my networks through the environmentFile option. But since the update, this option has been replaced by the secretsFile option. The issue here is that with this option, intead of referencing a secret with the following string:

@secret_name@

We must use:

ext:secret_name

And it doesn’t work for the network names (SSID), neither for EAP identities.

Before the update

networking.wireless = {
  environmentFile = config.sops.secrets.wifi.path;

  networks = {
    "@home_ssid@" = {
      psk = "@home_psk@";
    };

    "@company_ssid@" = {
      auth = ''
        eap=PEAP
        identity="@company_identity@"
        password="@company_pass@"
      '';
    };
  };
};

After the update

networking.wireless = {
  secretsFile = config.sops.secrets.wifi.path;

  networks = {
    "Home" = {
      pskRaw = "ext:home_psk";
    };

    "Company" = {
      auth = ''
        eap=PEAP
        identity="email@company.com"
        password="ext:company_pass"
      '';
    };
  };
};

Since my config is public, I’d like to avoid comitting my company email if possible. Does anyone know how to do it? Same goes for the SSIDs.

Thanks!

1 Like

Best practice is probably to keep this module in a non-public repo (or using something like git-crypt). The data won’t do harm in the nix store, it’s just sensitive.

Indeed it won’t do harm in the store and I don’t mind having it there. I’m just sad to have a degraded user experience with this update. But maybe this is an issue with wpa_supplicant and not NixOS, after all.

Thanks for your answer!

Not exactly, wpa_supplicant just gained a feature to substitute variables, so instead of hand-rolling it (and having to maintain it) NixOS now uses it. Agreed it’s a lil’ annoying.

Indeed it won’t do harm in the store and I don’t mind having it there. I’m just sad to have a degraded user experience with this update. But maybe this is an issue with wpa_supplicant and not NixOS, after all.

It was my decision to switch from the existing mechanism to the one built into wpa_supplicant. The main motivation is that correctly reading from the environment and splicing secrets into a text file is pretty tricky, and in fact the previous implementation was buggy. Even with the bugs fixed (that I know of), escaping the special characters in secrets to conform to the systemd EnvironmentFile= syntax is still a pretty bad UX.

I honestly did not think that people would use it to splice the SSIDs and arbitrary values besides secrets, so yeah, sorry about that.

3 Likes

I guess then I would have to write custom code to get back the EAP identity masking. I don’t really care about SSIDs, but the EAP identity masking is quite an issue to me. I’ll check the old code to get some inspiration and will share my findings here.

Thanks for letting us know :slightly_smiling_face:

1 Like

Revisiting this nearly 6 months later…

After trying several things I ended up bringing back the substitution in the service script.

I created a custom wpa_supplicant module (based on the current one in nixpkgs) which:

  • disables the one builtin in NixOS using the disabledModules option
  • brings back two things from before the switch:
    • final config location in service runtime dir (ie. /run/wpa_supplicant/wpa_supplicant.conf)
    • secrets substitution in service script

I’m not very fond of awk (but yes, that’s because I lack knowledge of it) so I rewrote the substitution part in plain bash. It may not be very optimized but at least I understand the code and it works for my use case.

This is implemented in my repository here.

1 Like

If I understood it right, you can store any kind of secrets this way:

networking.wireless = {
  secretsFile = config.sops.secrets.wifi.path;

  networks = {
    "Home" = {
      pskRaw = "ext:home_psk";
    };

    "Company" = {
      auth = ''
        eap=PEAP
        identity="ext:company_email"
        password="ext:company_pass"
      '';
    };
  };
};

If there’s no restriction to store only passwords, then it is basically the same functionality with a different syntax.
But still that’s great you found your own way of doing the thing and that you shared it! I love open source.

There is indeed a restriction to only passwords-like fields: that’s the crux of this and other threads.

1 Like