diff options
author | Karel Kočí <cynerd@email.cz> | 2022-08-12 11:51:10 +0200 |
---|---|---|
committer | Karel Kočí <cynerd@email.cz> | 2022-08-12 11:51:10 +0200 |
commit | 5d49d78d9612ed23947a6c963ad71f441abeac8d (patch) | |
tree | 86c5c12dd141406d5cd6ea52cbe14056a4a673cb | |
parent | 6ba14c1b7f39ecf86ab710ad93734b331b319b4d (diff) | |
download | nixturris-5d49d78d9612ed23947a6c963ad71f441abeac8d.tar.gz nixturris-5d49d78d9612ed23947a6c963ad71f441abeac8d.tar.bz2 nixturris-5d49d78d9612ed23947a6c963ad71f441abeac8d.zip |
nixos: improve hostapd
-rw-r--r-- | flake.lock | 6 | ||||
-rw-r--r-- | nixos/modules/hostapd.nix | 113 |
2 files changed, 80 insertions, 39 deletions
@@ -16,11 +16,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1659868656, - "narHash": "sha256-LINDS957FYzOb412t/Zha44LQqGniMpUIUz4Pi+fvSs=", + "lastModified": 1660227034, + "narHash": "sha256-bXMlG/YU0IjAod6M625XT1YbUG+/3L9ypk9llYpKeuM=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "80fc83ad314fe701766ee66ac8286307d65b39e3", + "rev": "964d60ff2e6bc76c0618962da52859603784fa78", "type": "github" }, "original": { diff --git a/nixos/modules/hostapd.nix b/nixos/modules/hostapd.nix index 0dc6f95..de3035b 100644 --- a/nixos/modules/hostapd.nix +++ b/nixos/modules/hostapd.nix @@ -11,7 +11,7 @@ with lib; let - cfg = config.networking.hostapd; + cfg = config.networking.wirelessAP; options_bss = { @@ -434,8 +434,8 @@ let }; - configFile = interface: let - icfg = cfg."${interface}"; + mkConfig = iface: let + icfg = cfg.interfaces."${iface}"; in '' ctrl_interface=/run/hostapd ctrl_interface_group=${icfg.group} @@ -446,7 +446,7 @@ let logger_stdout=-1 logger_stdout_level=${toString icfg.logLevel} - interface=${interface} + interface=${iface} driver=${icfg.driver} hw_mode=${icfg.hwMode} channel=${toString icfg.channel} @@ -496,11 +496,6 @@ let ''} ''; - etcConfigs = listToAttrs (map - (n: nameValuePair "hostapd/${n}.conf" {text = configFile n;}) - (attrNames (filterAttrs (n: v: v.enable) cfg)) - ); - in { @@ -510,30 +505,59 @@ in ###### interface options = { - networking.hostapd = mkOption { - type = with types; attrsOf (submodule {options = options_interface;}); - default = { }; - example = literalExpression '' - { "wlan0" = { - hw_mode = "a"; - channel = 11; - ssid = "MyNetwork"; - wpaPassphrase = "SecretPassword"; - }; - } - ''; - description = '' - Interface for which to start <command>hostapd</command>. + networking.wirelessAP = { + + enable = mkOption { + type = types.bool; + default = false; + description = "Whether to enable hostapd."; + }; + + environmentFile = mkOption { + type = types.nullOr types.path; + default = null; + example = "/run/secrets/wirelessAP.env"; + description = '' + File consisting of lines of the form <literal>varname=value</literal> + to define variables for the wireless access point configuration. + + See section "EnvironmentFile=" in <citerefentry> + <refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum> + </citerefentry> for a syntax reference. + + Secrets (PSKs, passwords, etc.) can be provided without adding them to + the world-readable Nix store by defining them in the environment file and + referring to them in option <option>networking.wirelessAP</option> + with the syntax <literal>@varname@</literal>. ''; + }; + + interfaces = mkOption { + type = with types; attrsOf (submodule {options = options_interface;}); + default = { }; + example = literalExpression '' + { "wlan0" = { + hw_mode = "a"; + channel = 11; + ssid = "MyNetwork"; + wpaPassphrase = "SecretPassword"; + }; + } + ''; + description = '' + Interface for which to start <command>hostapd</command>. + ''; + }; + }; }; ###### implementation - config = mkIf (any (val: val.enable) (attrValues cfg)) { + config = mkIf (cfg.enable && (any (val: val.enable) (attrValues cfg.interfaces))) { assertions = [{ - assertion = all (val: ! val.enable or val.countryCode != null) (attrValues cfg); + assertion = all (val: ! val.enable or val.countryCode != null) (attrValues cfg.interfaces); message = "Country code has to be specified to prevent violation of the law."; }]; ## TODO mkRenamedOptionModule @@ -541,25 +565,42 @@ in environment.systemPackages = [ pkgs.hostapd ]; services.udev.packages = [ pkgs.crda ]; - environment.etc = etcConfigs; - systemd.services.hostapd = let - interfaces = map utils.escapeSystemdPath (attrNames (filterAttrs (n: v: v.enable) cfg)); - links = interfaces ++ (map utils.escapeSystemdPath (concatMap attrNames (catAttrs "bss" (attrValues (filterAttrs (n: v: v.enable) cfg))))); + interfaces = map utils.escapeSystemdPath (attrNames (filterAttrs (n: v: v.enable) cfg.interfaces)); + links = interfaces ++ (map utils.escapeSystemdPath (concatMap attrNames (catAttrs "bss" (attrValues (filterAttrs (n: v: v.enable) cfg.interfaces))))); devices = map (ifc: "sys-subsystem-net-devices-${ifc}.device") interfaces; services = map (ifc: "network-link-${ifc}.service") links; in { - description = "hostapd wireless AP"; - path = [ pkgs.hostapd ]; + description = "Hostapd wireless AP"; after = devices; bindsTo = devices; requiredBy = services; wantedBy = [ "multi-user.target" ]; - serviceConfig = - { ExecStart = "${pkgs.hostapd}/bin/hostapd ${toString (map (v: "/etc/${v}") (attrNames etcConfigs))}"; - Restart = "always"; - }; - }; + path = [ pkgs.hostapd ]; + serviceConfig = { + RuntimeDirectory = "hostapd"; + RuntimeDirectoryMode = "700"; + EnvironmentFile = mkIf (cfg.environmentFile != null) (builtins.toString cfg.environmentFile); + Restart = "always"; + }; + script = + '' + # substitute environment variables + ${concatStrings (forEach (attrNames cfg.interfaces) (iface: let + configFile = pkgs.writeText "hostapd_${iface}.conf" (mkConfig iface); + finalConfig = ''"$RUNTIME_DIRECTORY"/${iface}.conf''; + in '' + ${pkgs.gawk}/bin/awk '{ + for(varname in ENVIRON) + gsub("@"varname"@", ENVIRON[varname]) + print + }' "${configFile}" > "${finalConfig}" + ''))} + + # run hostapd + exec hostapd ${concatStringsSep " " (forEach (attrNames cfg.interfaces) (iface: ''"$RUNTIME_DIRECTORY"/${iface}.conf''))} + ''; + }; }; } |