diff --git a/nixos/modules/services/networking/wpa_supplicant.nix b/nixos/modules/services/networking/wpa_supplicant.nix index f73622af3458..04cbe84308df 100644 --- a/nixos/modules/services/networking/wpa_supplicant.nix +++ b/nixos/modules/services/networking/wpa_supplicant.nix @@ -117,9 +117,24 @@ let path = [ pkgs.wpa_supplicant ]; serviceConfig = { + RuntimeDirectory = "wpa_supplicant"; + 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" + ]; + } + // lib.optionalAttrs cfg.enableHardening { User = "wpa_supplicant"; Group = "wpa_supplicant"; - RuntimeDirectory = "wpa_supplicant"; AmbientCapabilities = [ "CAP_NET_ADMIN" "CAP_NET_RAW" @@ -180,20 +195,6 @@ let ]; SystemCallArchitectures = "native"; UMask = "0077"; - - 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" - ]; }; script = '' @@ -598,6 +599,22 @@ in ''; }; + enableHardening = mkOption { + default = true; + description = '' + Whether to apply security hardening measures to wpa_supplicant. + These include limiting access to the filesystem, devices and network + capabilities. + + ::: {.note} + Disabling this will increase the potential attack surface if the + wpa_supplicant daemon becomes compromised, but it may be necessary + for more complex enterprise networks (for example requiring + access to mutable files, smart cards or TPM devices). + ::: + ''; + }; + extraConfig = mkOption { type = types.lines; default = ""; diff --git a/nixos/tests/wpa_supplicant.nix b/nixos/tests/wpa_supplicant.nix index 1adda72186f4..8b3321822b03 100644 --- a/nixos/tests/wpa_supplicant.nix +++ b/nixos/tests/wpa_supplicant.nix @@ -226,6 +226,19 @@ in machine.succeed(dbus_command) # as root machine.succeed(f"sudo -g wpa_supplicant {dbus_command}") # as wpa_supplicant group + with subtest("D-Bus auto-starting is working"): + # stop service + machine.systemctl("stop wpa_supplicant.service") + machine.require_unit_state("wpa_supplicant.service", "inactive") + + # send wake up + dbus_command = "dbus-send --system --print-reply --dest=fi.w1.wpa_supplicant1 " \ + "/fi/w1/wpa_supplicant1 fi.w1.wpa_supplicant1.GetInterface string:wlan0" + machine.succeed(dbus_command) + + # should be up again + machine.require_unit_state("wpa_supplicant.service", "active") + # generated configuration file config_file = "/etc/static/wpa_supplicant/nixos.conf" diff --git a/pkgs/os-specific/linux/wpa_supplicant/unprivileged-daemon.patch b/pkgs/os-specific/linux/wpa_supplicant/unprivileged-daemon.patch index e7105017b7c8..8df587722b79 100644 --- a/pkgs/os-specific/linux/wpa_supplicant/unprivileged-daemon.patch +++ b/pkgs/os-specific/linux/wpa_supplicant/unprivileged-daemon.patch @@ -1,22 +1,22 @@ -commit 4608dab78e6ac78be7ab625fb066861549daa37f +commit 47cc80d3056f8a783ce1caabeb0a8b5379cba3d1 Author: rnhmjoj -Date: Wed Dec 31 01:43:26 2025 +0100 +Date: Mon Feb 2 08:24:24 2026 +0100 Fixes for running wpa_supplicant unprivileged - 1. Change the dbus service user to "wpa_supplicant" - - 2. Ensure appropriate group ownership and permissions on the client sockets. + 1. Ensure appropriate group ownership and permissions on the client sockets. Motivation: clients communicate with the daemon by creating "client" sockets; by default this is owned by the user running the client, so it may be inaccessible by the daemon. - 3. Move the "control" sockets under a subdirectory of /run/wpa_supplicant. + 2. Move the "control" sockets under a subdirectory of /run/wpa_supplicant. Motivation: wpa_supplicant will try to adjust the ownership of the sockets directory, even if they are fine, and fail. - 4. Move the "client" under a subdirectory of /run/wpa_supplicant instead - of tmp. Motivation: this allows to unshare /tmp + 3. Move the "client" under a subdirectory of /run/wpa_supplicant instead + of tmp. Motivation: this allows to unshare /tmp. + + 4. Extend the dbus policy to allow the wpa_supplicant user/group. diff --git a/src/common/wpa_ctrl.c b/src/common/wpa_ctrl.c index 7e197f094..6bfb09111 100644 @@ -47,38 +47,23 @@ index 7e197f094..6bfb09111 100644 /* Set group even if we do not have privileges to change owner */ lchown(ctrl->local.sun_path, -1, AID_WIFI); diff --git a/wpa_supplicant/dbus/dbus-wpa_supplicant.conf b/wpa_supplicant/dbus/dbus-wpa_supplicant.conf -index e81b495f4..1ee5bc19a 100644 +index e81b495f4..c371dd11f 100644 --- a/wpa_supplicant/dbus/dbus-wpa_supplicant.conf +++ b/wpa_supplicant/dbus/dbus-wpa_supplicant.conf -@@ -2,9 +2,15 @@ - "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" - "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> +@@ -4,7 +4,12 @@ -- -+ + - -+ -+ + + + + + ++ -diff --git a/wpa_supplicant/dbus/fi.w1.wpa_supplicant1.service.in b/wpa_supplicant/dbus/fi.w1.wpa_supplicant1.service.in -index d97ff3921..367a7c670 100644 ---- a/wpa_supplicant/dbus/fi.w1.wpa_supplicant1.service.in -+++ b/wpa_supplicant/dbus/fi.w1.wpa_supplicant1.service.in -@@ -1,5 +1,5 @@ - [D-BUS Service] - Name=fi.w1.wpa_supplicant1 - Exec=@BINDIR@/wpa_supplicant -u --User=root -+User=wpa_supplicant - SystemdService=wpa_supplicant.service diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c index 03180a316..f5e22dee1 100644 --- a/wpa_supplicant/wpa_cli.c