From 7d973a56d0a38b8b0bb7e1e715ca3e3ebcdb2ac3 Mon Sep 17 00:00:00 2001 From: Robin Gloster Date: Sat, 26 Dec 2015 01:09:00 +0000 Subject: [PATCH 1/6] wpa_supplicant module: remove obsolete option networking.WLANInterface has been obsolete for years --- .../services/networking/wpa_supplicant.nix | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/nixos/modules/services/networking/wpa_supplicant.nix b/nixos/modules/services/networking/wpa_supplicant.nix index 9e04bd40190..bef4b2bc0b9 100644 --- a/nixos/modules/services/networking/wpa_supplicant.nix +++ b/nixos/modules/services/networking/wpa_supplicant.nix @@ -3,14 +3,8 @@ with lib; let - cfg = config.networking.wireless; configFile = "/etc/wpa_supplicant.conf"; - - ifaces = - cfg.interfaces ++ - optional (config.networking.WLANInterface != "") config.networking.WLANInterface; - in { @@ -18,12 +12,6 @@ in ###### interface options = { - - networking.WLANInterface = mkOption { - default = ""; - description = "Obsolete. Use instead."; - }; - networking.wireless = { enable = mkOption { type = types.bool; @@ -95,8 +83,9 @@ in services.dbus.packages = [ pkgs.wpa_supplicant ]; # FIXME: start a separate wpa_supplicant instance per interface. - jobs.wpa_supplicant = - { description = "WPA Supplicant"; + jobs.wpa_supplicant = let + ifaces = cfg.interfaces; + in { description = "WPA Supplicant"; wantedBy = [ "network.target" ]; From 3a5f48844593fc129184d00a1ee32717b42e5e57 Mon Sep 17 00:00:00 2001 From: Robin Gloster Date: Sat, 26 Dec 2015 01:12:32 +0000 Subject: [PATCH 2/6] wpa_supplicant module: refactor --- .../services/networking/wpa_supplicant.nix | 75 ++++++++----------- 1 file changed, 32 insertions(+), 43 deletions(-) diff --git a/nixos/modules/services/networking/wpa_supplicant.nix b/nixos/modules/services/networking/wpa_supplicant.nix index bef4b2bc0b9..5979ab7fbe3 100644 --- a/nixos/modules/services/networking/wpa_supplicant.nix +++ b/nixos/modules/services/networking/wpa_supplicant.nix @@ -5,12 +5,7 @@ with lib; let cfg = config.networking.wireless; configFile = "/etc/wpa_supplicant.conf"; -in - -{ - - ###### interface - +in { options = { networking.wireless = { enable = mkOption { @@ -73,19 +68,17 @@ in }; }; + config = mkMerge [ + (mkIf cfg.enable { + environment.systemPackages = [ pkgs.wpa_supplicant ]; - ###### implementation + services.dbus.packages = [ pkgs.wpa_supplicant ]; - config = mkIf cfg.enable { - - environment.systemPackages = [ pkgs.wpa_supplicant ]; - - services.dbus.packages = [ pkgs.wpa_supplicant ]; - - # FIXME: start a separate wpa_supplicant instance per interface. - jobs.wpa_supplicant = let - ifaces = cfg.interfaces; - in { description = "WPA Supplicant"; + # FIXME: start a separate wpa_supplicant instance per interface. + systemd.services.wpa_supplicant = let + ifaces = cfg.interfaces; + in { + description = "WPA Supplicant"; wantedBy = [ "network.target" ]; @@ -101,37 +94,33 @@ in fi ''; - script = - '' - ${if ifaces == [] then '' - for i in $(cd /sys/class/net && echo *); do - DEVTYPE= - source /sys/class/net/$i/uevent - if [ "$DEVTYPE" = "wlan" -o -e /sys/class/net/$i/wireless ]; then - ifaces="$ifaces''${ifaces:+ -N} -i$i" - fi - done - '' else '' - ifaces="${concatStringsSep " -N " (map (i: "-i${i}") ifaces)}" - ''} - exec wpa_supplicant -s -u -D${cfg.driver} -c ${configFile} $ifaces - ''; + script = '' + ${if ifaces == [] then '' + for i in $(cd /sys/class/net && echo *); do + DEVTYPE= + source /sys/class/net/$i/uevent + if [ "$DEVTYPE" = "wlan" -o -e /sys/class/net/$i/wireless ]; then + ifaces="$ifaces''${ifaces:+ -N} -i$i" + fi + done + '' else '' + ifaces="${concatStringsSep " -N " (map (i: "-i${i}") ifaces)}" + ''} + exec wpa_supplicant -s -u -D${cfg.driver} -c ${configFile} $ifaces + ''; }; - powerManagement.resumeCommands = - '' + powerManagement.resumeCommands = '' ${config.systemd.package}/bin/systemctl try-restart wpa_supplicant ''; - assertions = [{ assertion = !cfg.userControlled.enable || cfg.interfaces != []; - message = "user controlled wpa_supplicant needs explicit networking.wireless.interfaces";}]; - - # Restart wpa_supplicant when a wlan device appears or disappears. - services.udev.extraRules = - '' + # Restart wpa_supplicant when a wlan device appears or disappears. + services.udev.extraRules = '' ACTION=="add|remove", SUBSYSTEM=="net", ENV{DEVTYPE}=="wlan", RUN+="${config.systemd.package}/bin/systemctl try-restart wpa_supplicant.service" ''; - - }; - + }) + { + meta.maintainers = with lib.maintainers; [ globin ]; + } + ]; } From d03b35f881941f57d5159ae0a58b10f7c3142682 Mon Sep 17 00:00:00 2001 From: Robin Gloster Date: Tue, 29 Dec 2015 10:21:38 +0000 Subject: [PATCH 3/6] wpa_supplicant module: add networks option --- nixos/doc/manual/configuration/wireless.xml | 14 +++- .../services/networking/wpa_supplicant.nix | 66 ++++++++++++------- 2 files changed, 56 insertions(+), 24 deletions(-) diff --git a/nixos/doc/manual/configuration/wireless.xml b/nixos/doc/manual/configuration/wireless.xml index 373a9168cc8..13e4283d241 100644 --- a/nixos/doc/manual/configuration/wireless.xml +++ b/nixos/doc/manual/configuration/wireless.xml @@ -18,8 +18,18 @@ NixOS will start wpa_supplicant for you if you enable this setting: networking.wireless.enable = true; -NixOS currently does not generate wpa_supplicant's -configuration file, /etc/wpa_supplicant.conf. You should edit this file +NixOS lets you specify networks for wpa_supplicant declaratively: + +networking.wireless.networks = { + echelon = { + psk = "abcdefgh"; + }; + "free.wifi" = {}; +} + + +When no networks are set it will default to using a configuration file at +/etc/wpa_supplicant.conf. You should edit this file yourself to define wireless networks, WPA keys and so on (see wpa_supplicant.conf(5)). diff --git a/nixos/modules/services/networking/wpa_supplicant.nix b/nixos/modules/services/networking/wpa_supplicant.nix index 5979ab7fbe3..1292ca7f08e 100644 --- a/nixos/modules/services/networking/wpa_supplicant.nix +++ b/nixos/modules/services/networking/wpa_supplicant.nix @@ -4,33 +4,29 @@ with lib; let cfg = config.networking.wireless; - configFile = "/etc/wpa_supplicant.conf"; + configFile = if cfg.networks != {} then pkgs.writeText "wpa_supplicant.conf" '' + ${optionalString cfg.userControlled.enable '' + ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=${cfg.userControlled.group} + update_config=1''} + ${concatStringsSep "\n" (mapAttrsToList (ssid: networkConfig: '' + network={ + ssid="${ssid}" + ${optionalString (networkConfig.psk != null) ''psk="${networkConfig.psk}"''} + ${optionalString (networkConfig.psk == null) ''key_mgmt=NONE''} + } + '') cfg.networks)} + '' else "/etc/wpa_supplicant.conf"; in { options = { networking.wireless = { - enable = mkOption { - type = types.bool; - default = false; - description = '' - Whether to start wpa_supplicant to scan for - and associate with wireless networks. Note: NixOS currently - does not manage wpa_supplicant's - configuration file, ${configFile}. You - should edit this file yourself to define wireless networks, - WPA keys and so on (see - wpa_supplicant.conf - 5), or use - networking.wireless.userControlled.* to allow users to add entries - through wpa_cli and wpa_gui. - ''; - }; + enable = mkEnableOption "wpa_supplicant"; interfaces = mkOption { type = types.listOf types.str; default = []; example = [ "wlan0" "wlan1" ]; description = '' - The interfaces wpa_supplicant will use. If empty, it will + The interfaces wpa_supplicant will use. If empty, it will automatically use all wireless interfaces. ''; }; @@ -41,6 +37,34 @@ in { description = "Force a specific wpa_supplicant driver."; }; + networks = mkOption { + type = types.attrsOf (types.submodule { + options = { + psk = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + The network's pre-shared key in plaintext defaulting + to being a network without any authentication. + ''; + }; + }; + }); + description = '' + The network definitions to automatically connect to when + wpa_supplicant is running. If this + parameter is left empty wpa_supplicant will use + /etc/wpa_supplicant.conf as the configuration file. + ''; + default = {}; + example = literalExample '' + echelon = { + psk = "abcdefgh"; + }; + "free.wifi" = {}; + ''; + }; + userControlled = { enable = mkOption { type = types.bool; @@ -51,10 +75,8 @@ in { to depend on a large package such as NetworkManager just to pick nearby access points. - When you want to use this, make sure ${configFile} doesn't exist. - It will be created for you. - - Currently it is also necessary to explicitly specify networking.wireless.interfaces. + When using a declarative network specification you cannot persist any + settings via wpa_gui or wpa_cli. ''; }; From 609457458e24b619b45a18666738b704077f434b Mon Sep 17 00:00:00 2001 From: Robin Gloster Date: Tue, 29 Dec 2015 10:22:03 +0000 Subject: [PATCH 4/6] wpa_supplicant module: remove preStart hack If the config file is managed imperatively we shouldn't touch it. --- nixos/modules/services/networking/wpa_supplicant.nix | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/nixos/modules/services/networking/wpa_supplicant.nix b/nixos/modules/services/networking/wpa_supplicant.nix index 1292ca7f08e..397811f9626 100644 --- a/nixos/modules/services/networking/wpa_supplicant.nix +++ b/nixos/modules/services/networking/wpa_supplicant.nix @@ -106,16 +106,6 @@ in { path = [ pkgs.wpa_supplicant ]; - preStart = '' - touch -a ${configFile} - chmod 600 ${configFile} - '' + optionalString cfg.userControlled.enable '' - if [ ! -s ${configFile} ]; then - echo "ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=${cfg.userControlled.group}" >> ${configFile} - echo "update_config=1" >> ${configFile} - fi - ''; - script = '' ${if ifaces == [] then '' for i in $(cd /sys/class/net && echo *); do From 391c33004242b17d41d9e15e8a0a7c416087c17a Mon Sep 17 00:00:00 2001 From: Robin Gloster Date: Wed, 6 Jan 2016 03:52:56 +0000 Subject: [PATCH 5/6] wpa_supplicant service: jobs -> systemd.services Fixes an occurence of `jobs` usage causing tests to fail to evaluate. thanks @domenkozar --- nixos/modules/profiles/installation-device.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nixos/modules/profiles/installation-device.nix b/nixos/modules/profiles/installation-device.nix index 946032781f4..669b6975c69 100644 --- a/nixos/modules/profiles/installation-device.nix +++ b/nixos/modules/profiles/installation-device.nix @@ -51,7 +51,7 @@ with lib; # Enable wpa_supplicant, but don't start it by default. networking.wireless.enable = mkDefault true; - jobs.wpa_supplicant.startOn = mkOverride 50 ""; + systemd.services.wpa_supplicant.wantedBy = mkOverride 50 []; # Tell the Nix evaluator to garbage collect more aggressively. # This is desirable in memory-constrained environments that don't From 246f0e91cda1357ef31708e414d4b697ec9a15a7 Mon Sep 17 00:00:00 2001 From: Robin Gloster Date: Wed, 6 Jan 2016 03:57:25 +0000 Subject: [PATCH 6/6] wpa_supplicant service: Warn about plaintext keys in docs --- nixos/doc/manual/configuration/wireless.xml | 4 +++- nixos/modules/services/networking/wpa_supplicant.nix | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/nixos/doc/manual/configuration/wireless.xml b/nixos/doc/manual/configuration/wireless.xml index 13e4283d241..e4560f2da36 100644 --- a/nixos/doc/manual/configuration/wireless.xml +++ b/nixos/doc/manual/configuration/wireless.xml @@ -28,7 +28,9 @@ networking.wireless.networks = { } -When no networks are set it will default to using a configuration file at +Be aware that keys will be written to the nix store in plaintext! + +When no networks are set, it will default to using a configuration file at /etc/wpa_supplicant.conf. You should edit this file yourself to define wireless networks, WPA keys and so on (see wpa_supplicant.conf(5)). diff --git a/nixos/modules/services/networking/wpa_supplicant.nix b/nixos/modules/services/networking/wpa_supplicant.nix index 397811f9626..1b655af6c82 100644 --- a/nixos/modules/services/networking/wpa_supplicant.nix +++ b/nixos/modules/services/networking/wpa_supplicant.nix @@ -46,6 +46,9 @@ in { description = '' The network's pre-shared key in plaintext defaulting to being a network without any authentication. + + Be aware that these will be written to the nix store + in plaintext! ''; }; };