Skip to content

nixos/wireless: add enableHardening option#484382

Merged
sternenseemann merged 1 commit intoNixOS:masterfrom
rnhmjoj:pr-wpa-toggle
Feb 7, 2026
Merged

nixos/wireless: add enableHardening option#484382
sternenseemann merged 1 commit intoNixOS:masterfrom
rnhmjoj:pr-wpa-toggle

Conversation

@rnhmjoj
Copy link
Contributor

@rnhmjoj rnhmjoj commented Jan 27, 2026

This may be necessary for more complex enterprise networks (for example requiring access to mutable files, smart cards or TPM devices), as pointed out in #480355 (comment).

Things done

  • Built on platform:
    • x86_64-linux
    • aarch64-linux
    • x86_64-darwin
    • aarch64-darwin
  • Tested, as applicable:
  • Ran nixpkgs-review on this PR. See nixpkgs-review usage.
  • Tested basic functionality of all binary files, usually in ./result/bin/.
  • Nixpkgs Release Notes
    • Package update: when the change is major or breaking.
  • NixOS Release Notes
    • Module addition: when adding a new NixOS module.
    • Module update: when the change is significant.
  • Fits CONTRIBUTING.md, pkgs/README.md, maintainers/README.md and other READMEs.

@nixpkgs-ci nixpkgs-ci bot added 10.rebuild-linux: 1-10 This PR causes between 1 and 10 packages to rebuild on Linux. 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin. 9.needs: reviewer This PR currently has no reviewers requested and needs attention. 6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 8.has: module (update) This PR changes an existing module in `nixos/` labels Jan 27, 2026
@nixpkgs-ci nixpkgs-ci bot removed the 9.needs: reviewer This PR currently has no reviewers requested and needs attention. label Jan 27, 2026
@theCapypara
Copy link
Member

theCapypara commented Jan 27, 2026

Should this maybe be off by default based on the stateVersion?
(stateVersion <= "25.11" -> off, else on?)

@rnhmjoj
Copy link
Contributor Author

rnhmjoj commented Jan 27, 2026

Should this maybe be off by default based on the stateVersion?

There's no need: I intentionally postponed merging the hardening changes after 25.11 and I will not backport them, of course.

@rnhmjoj
Copy link
Contributor Author

rnhmjoj commented Jan 30, 2026

All the nixosTests.wpa_supplicant tests are passing with enableHardening = false, so the capabilities trick seems to work.
If someone could confirm this unbreaks the enterprisey setup, I will merge this now.

@rnhmjoj
Copy link
Contributor Author

rnhmjoj commented Jan 30, 2026

@tazjin, please check the new version of the PR.

Comment on lines +130 to +142
ExecStartPre =
lib.optionals (cfg.allowAuxiliaryImperativeNetworks || !hasDeclarative) [
# set up imperative config file
"+${pkgs.coreutils}/bin/touch /etc/wpa_supplicant/imperative.conf"
"+${pkgs.coreutils}/bin/chmod 664 /etc/wpa_supplicant/imperative.conf"
"+${pkgs.coreutils}/bin/chown -R wpa_supplicant:wpa_supplicant /etc/wpa_supplicant"
]
++ lib.optionals cfg.userControlled [
# set up client sockets directory
"+${pkgs.coreutils}/bin/mkdir /run/wpa_supplicant/client"
"+${pkgs.coreutils}/bin/chown wpa_supplicant:wpa_supplicant /run/wpa_supplicant/client"
"+${pkgs.coreutils}/bin/chmod g=u /run/wpa_supplicant/client"
];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those should really be in tmpfiles 😓

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I get that systemd-tmpfiles has a neater syntax and was made for this sort of thing, but it provides less guarantees. If the files permissions gets messed up or they get deleted, wpa_supplicant will fails to start until you reboot; with the setup in ExecStartPre it just works.

Comment on lines +127 to +128
"CAP_SYS_ADMIN"
"CAP_DAC_OVERRIDE"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add a TODO to revisit those in the future?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now the daemon runs with full previleges again if enableHardening = false. I don't think we should try to make it more balanced: the setups that break under enableHardening are rare and complicated to reason about.

@tazjin
Copy link
Member

tazjin commented Jan 30, 2026

@tazjin, please check the new version of the PR.

Doesn't work, in fact it triggered new kinds of errors I haven't seen before which also prevented wpa_supplicant from starting:

янв 30 16:02:13 khamovnik systemd[1]: Starting WPA Supplicant instance...
янв 30 16:02:13 khamovnik systemd[1]: Started WPA Supplicant instance.
янв 30 16:02:13 khamovnik wpa_supplicant[1244868]: dbus: Could not request service name: org.freedesktop.DBus.Error.AccessDenied Connection ":1.2340" is not allowed to own the service "fi.w1.wpa_supplicant1" due to security policies in the configuration file
янв 30 16:02:13 khamovnik wpa_supplicant[1244868]: Failed to initialize wpa_supplicant
янв 30 16:02:13 khamovnik systemd[1]: wpa_supplicant.service: Main process exited, code=exited, status=255/EXCEPTION

Here is my own commit which properly disables the hardening changes and makes things work again: tazjin@4f18477

@rnhmjoj
Copy link
Contributor Author

rnhmjoj commented Jan 31, 2026

is not allowed to own the service "fi.w1.wpa_supplicant1" due to security policies in the configuration file

There's something strange going on here: the dbus interface is tested in nixosTest.wpa_supplicant.basic and the test is passing with enableHardening = false. The policy being referred by the error message is this bit:

<policy user="wpa_supplicant">
    <allow own="fi.w1.wpa_supplicant1"/>
</policy>

It looks like you're running not running wpa_supplicant with the right user, or did not apply unprivileged patch.
Can you share your configuration for testing?

Here is my own commit which properly disables the hardening changes and makes things work again: tazjin@4f18477

Well, this is problematic: the unprivileged patch moves the location of the socket dir, so enableHardening = false will break wpa_cli and wpa_gui. That's why I wasn't doing it.

@tazjin
Copy link
Member

tazjin commented Jan 31, 2026

Well, this is problematic: the unprivileged patch moves the location of the socket dir, so enableHardening = false will break wpa_cli and wpa_gui. That's why I wasn't doing it.

This would be fixed by also making the path in the config depending on the toggle, no? I don't use userControlled fwiw. My take is that disabling hardening should ... disable hardening, including all the changes that were made to enable it.

};

enableHardening = mkOption {
default = false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't forget to add a line that assigns this to true in nixos/modules/profiles/hardened.nix

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually this was a left-over from testing. It's supposed to be on by default.

This may be necessary for more complex enterprise networks (for example
requiring access to mutable files, smart cards or TPM devices), as
pointed out in NixOS#480355 (comment).
@rnhmjoj
Copy link
Contributor Author

rnhmjoj commented Feb 2, 2026

Ok, I think I have a solution.

It turns out the patch works regardless of which user the daemon is running as. The only thing that depends on the user is the dbus auto-start mechanism, however wpa_supplicant is a systemd service, so the User= property is actually ignored.

So, I left User=root in the dbus service file, and just updated the dbus policy to allow either root or wpa_supplicant to own the interface.

I tested all nixosTests.wpa_supplicant and nixosTests.networking.networkmanager with or without enableHardening and everything looks ok. I also added a subtest for the dbus autostarting.

@tazjin
Copy link
Member

tazjin commented Feb 7, 2026

@rnhmjoj Sorry for the delay, didn't get around to testing it during the week ...

With your commit, the diff to my previous unit is minimal:

image

and the connection works, so from my perspective this resolves the issue. I'm fine with keeping the default enabled, people with these kinds of complex network setups will probably find the toggle.

Code looks fine, and I support your explicit use of ExecStartPre over more systemd magic.

@nixpkgs-ci nixpkgs-ci bot added the 12.approvals: 1 This PR was reviewed and approved by one person. label Feb 7, 2026
@sternenseemann
Copy link
Member

I support your explicit use of ExecStartPre over more systemd magic.

I don't think this should be a point of discussion here anyway, that code is unchanged and has just been moved around for this change.

@sternenseemann
Copy link
Member

So, I left User=root in the dbus service file, and just updated the dbus policy to allow either root or wpa_supplicant to own the interface.

Does this mean that some things will run as root when activated via dbus? Maybe we should override the setting if enableHardening is on which should be possible using systemd.services.….

@nixpkgs-ci nixpkgs-ci bot added 12.approvals: 2 This PR was reviewed and approved by two persons. and removed 12.approvals: 1 This PR was reviewed and approved by one person. labels Feb 7, 2026
@rnhmjoj
Copy link
Contributor Author

rnhmjoj commented Feb 7, 2026

Does this mean that some things will run as root when activated via dbus?

No, the service runs with the correct user even when activated by dbus, because in this case dbus simply starts our systemd service. It would be a problem if it were to run the command specified in the dbus service file, but it's not the case.

Maybe we should override the setting if enableHardening is on which should be possible using systemd.services.….

Note that the file in question is a dbus service: it looks like a systemd unit file, but it's a different thing and can't be modified from NixOS. But in this case it doesn't matter.

@sternenseemann sternenseemann added this pull request to the merge queue Feb 7, 2026
Merged via the queue into NixOS:master with commit c03cfff Feb 7, 2026
37 of 39 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 8.has: module (update) This PR changes an existing module in `nixos/` 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin. 10.rebuild-linux: 1-10 This PR causes between 1 and 10 packages to rebuild on Linux. 12.approvals: 2 This PR was reviewed and approved by two persons.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants