diff --git a/hosts/zackbiene/hostapd.nix b/hosts/zackbiene/hostapd.nix index 8b02c0c..e314a78 100644 --- a/hosts/zackbiene/hostapd.nix +++ b/hosts/zackbiene/hostapd.nix @@ -14,19 +14,18 @@ enable = true; interfaces = { "wlan1" = { + logLevel = 0; ssid = "🍯🐝💨"; hwMode = "g"; - #wifi4.enable = true; - #wifi5.enable = true; countryCode = "DE"; - # Automatic Channel Selection (ACS) is unfortunately not implemented for mt7612u. - channel = 13; - - #wpa = 3; - # TODO dont adverttise! - - # TODO away - logLevel = 0; + channel = 13; # Automatic Channel Selection (ACS) is unfortunately not implemented for mt7612u. + macAcl = "deny"; + apIsolate = true; + authentication = { + saePasswordsFile = config.rekey.secrets.wifi-clients.path; + saeAddToMacAllow = true; + }; + wifi4.capabilities = ["LDPC" "HT40+" "HT40-" "GF" "SHORT-GI-20" "SHORT-GI-40" "TX-STBC" "RX-STBC1"]; }; }; }; diff --git a/hosts/zackbiene/secrets/wifi-clients.age b/hosts/zackbiene/secrets/wifi-clients.age index 747eca5..71baefc 100644 --- a/hosts/zackbiene/secrets/wifi-clients.age +++ b/hosts/zackbiene/secrets/wifi-clients.age @@ -1,11 +1,10 @@ age-encryption.org/v1 --> X25519 JEieTSfpgYVOG4jpaPU2Ixo5gzKfA2jADiVp2mDzo3o -9rqppLh1oDh5+9OOIULyRc6wO6xHtuMUWlD3Cdd92cc --> piv-p256 xqSe8Q AhmCYR/YwLhHnFGfM8ovMFKesiCRq3KZJHhCkZCjOI8U -JpsMBhEZSirrIhrJSrxzxoH3kMafZdnwSv6AqRZRqow --> 0-grease HqN8M8 ;L H9mxj ?vjE*x$[ -7V9ALzJ+IJAvP9aUkCaaGCCX/DKbqhJc7Ii/WWwhbX56NNXKAnMu+St1yfUdto86 -qhxQbDuVBB17Ls42W0gJxYlfwb0 ---- XFjv9Cuf8BHmKEgxH4g6CJaVjz0L7ojFgfWhFlHs884 -*.\&ϝۈ;?\"j`DSiwAՙj51 <_X"{Ipܫ:b=*  -~# \ No newline at end of file +-> X25519 qvpFDcOyatSXVl605QLiHsTSQglCTjw9RvEQtWJyZkM +5EDyHb8/v7UHfz3uvAUQmuZ6La/EN/Kdtx96WJdWQMo +-> piv-p256 xqSe8Q ApCZ9ehw2EwREOZND16+8iDrtqWfiHw48/kRMV5WphXT +99+R5fAwYia0GAFEq+Bo2Z/GQ7EoIuQYKOQgTEVYniU +-> 6?-grease _E ~ e?]# X +3UiNZDgFonwUPaWBPtFpRpFIQGc+5Mnz8ODw6YIF +--- Tw96qV9jp6FiMfHKbfrw1bY++E7Ej6AmrcNBFMRMa2w +uQ[l<-!ċُgƠv +!-6JdsaQVA ,$`D@P@ v \ No newline at end of file diff --git a/modules/hostapd.nix b/modules/hostapd.nix index 0ae50cc..df2a151 100644 --- a/modules/hostapd.nix +++ b/modules/hostapd.nix @@ -16,7 +16,6 @@ escapeShellArg filter literalExpression - mapAttrs mapAttrsToList mdDoc mkIf @@ -79,7 +78,7 @@ ##### IEEE 802.11 general configuration ####################################### ssid=${ifcfg.ssid} - utf8_ssid=${ifcfg.hwMode} + utf8_ssid=${bool01 ifcfg.utf8Ssid} ${optionalString (ifcfg.countryCode != null) '' country_code=${ifcfg.countryCode} # IEEE 802.11d: Limit to frequencies allowed in country @@ -92,19 +91,17 @@ noscan=${bool01 ifcfg.noScan} # Set the MAC-address access control mode macaddr_acl=${macaddrAclModes.${ifcfg.macAcl}} - ${optionalString (ifcfg.macAllow != [] || ifcfg.macAllowFile != null) '' + ${optionalString (ifcfg.macAllow != [] || ifcfg.macAllowFile != null || ifcfg.authentication.saeAddToMacAllow) '' accept_mac_file=/run/hostapd/${interface}.mac.allow ''} ${optionalString (ifcfg.macDeny != [] || ifcfg.macDenyFile != null) '' deny_mac_file=/run/hostapd/${interface}.mac.deny ''} - # Only allow WPA, disable WEP (insecure) + # Only allow WPA, disable insecure WEP auth_algs=1 - # Set ssid broadcasting mode (0=normal, 1=empty, 2=clear) ignore_broadcast_ssid=${ignoreBroadcastSsidModes.${ifcfg.ignoreBroadcastSsid}} - # Always enable QoS, which is required for 802.11n/ac/ax + # Always enable QoS, which is required for 802.11n and above wmm_enabled=1 - # Whether to disallow clients to communicate with each other ap_isolate=${bool01 ifcfg.apIsolate} ##### IEEE 802.11n (WiFi 4) related configuration ####################################### @@ -115,30 +112,28 @@ require_ht=${bool01 ifcfg.wifi4.require} ''} - ##### IEEE 802.11ac (WiFi 5) related configuration ##################################### - - ieee80211ac=${bool01 ifcfg.wifi5.enable} ${optionalString ifcfg.wifi5.enable '' + ##### IEEE 802.11ac (WiFi 5) related configuration ##################################### + + ieee80211ac=1 vht_capab=${concatMapStrings (x: "[${x}]") ifcfg.wifi5.capabilities} require_vht=${bool01 ifcfg.wifi5.require} vht_oper_chwidth=${operatingChannelWidth.${ifcfg.wifi5.operatingChannelWidth}} ''} - - ##### IEEE 802.11ax (WiFi 6) related configuration ##################################### - - ieee80211ax=${bool01 ifcfg.wifi6.enable} ${optionalString ifcfg.wifi6.enable '' + ##### IEEE 802.11ax (WiFi 6) related configuration ##################################### + + ieee80211ax=1 require_he=${bool01 ifcfg.wifi6.require} he_oper_chwidth=${operatingChannelWidth.${ifcfg.wifi6.operatingChannelWidth}} he_su_beamformer=${bool01 ifcfg.wifi6.singleUserBeamformer} he_su_beamformee=${bool01 ifcfg.wifi6.singleUserBeamformee} he_mu_beamformer=${bool01 ifcfg.wifi6.multiUserBeamformer} ''} - - ##### IEEE 802.11be (WiFi 7) related configuration ##################################### - - ieee80211be=${bool01 ifcfg.wifi7.enable} ${optionalString ifcfg.wifi7.enable '' + ##### IEEE 802.11be (WiFi 7) related configuration ##################################### + + ieee80211be=1 eht_oper_chwidth=${operatingChannelWidth.${ifcfg.wifi7.operatingChannelWidth}} eht_su_beamformer=${bool01 ifcfg.wifi7.singleUserBeamformer} eht_su_beamformee=${bool01 ifcfg.wifi7.singleUserBeamformee} @@ -185,7 +180,7 @@ makeInterfaceRuntimeFiles = interface: ifcfg: let # All MAC addresses from SAE entries that aren't the wildcard address - saeMacs = filter (mac: mac != null && (toLower mac) != "ff:ff:ff:ff:ff:ff") (mapAttrs (x: x.mac) ifcfg.authentication.saePasswords); + saeMacs = filter (mac: mac != null && (toLower mac) != "ff:ff:ff:ff:ff:ff") (map (x: x.mac) ifcfg.authentication.saePasswords); in pkgs.writeShellScript "make-hostapd-${interface}-files" ('' set -euo pipefail @@ -213,17 +208,17 @@ '' # Populate mac allow list from saePasswords ++ optional (ifcfg.authentication.saeAddToMacAllow && saeMacs != []) '' - cat >> "$mac_deny_file" <> "$mac_allow_file" <> "$mac_deny_file" + | sed 's|^mac=||' >> "$mac_allow_file" '' # Create combined mac.deny list from macDeny and macDenyFile ++ optional (ifcfg.macDeny != []) '' @@ -234,14 +229,16 @@ ++ optional (ifcfg.macDenyFile != null) '' grep -Eo '^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})' ${escapeShellArg ifcfg.macDenyFile} >> "$mac_deny_file" '' - # Depending on which password sources are defined, add corresponding definitions. + # Add WPA passphrase from file if necessary ++ optional (ifcfg.authentication.wpaPasswordFile != null) '' cat >> "$hostapd_config_file" <> "$hostapd_config_file" + grep -v '\s*#' ${escapeShellArg ifcfg.authentication.saePasswordsFile} \ + | sed 's/^/sae_password=/' >> "$hostapd_config_file" '' # Finally append extraConfig if necessary. ++ optional (ifcfg.extraConfig != "") '' @@ -276,19 +273,34 @@ in { # WiFi 4 (2.4GHz) "wlp2s0" = { ssid = "AP 1"; + # countryCode = "US"; authentication.saePasswords = [{ password = "a flakey password"; }]; # Use saePasswordsFile if possible. }; + # Hidden hotspot for IoT devices (MAC ACL list, invisible ssid, isolated traffic) + "wlp3s0" = { + ssid = "IoT Isolated AP"; + # countryCode = "US"; + macAcl = "deny"; + apIsolate = true; + authentication = { + saePasswords = [{ password = "a flakey password"; }]; # Use saePasswordsFile if possible. + saeAddToMacAllow = true; + }; + }; + # WiFi 5 (5GHz) "wlp4s0" = { ssid = "Open AP with WiFi5"; + # countryCode = "US"; hwMode = "a"; authentication.mode = "none"; }; # Legacy WPA2 example - "wlp3s0" = { + "wlp5s0" = { ssid = "AP 2"; + # countryCode = "US"; channel = 0; # Enables automatic channel selection ACS. Use only if your hardware support's it. authentication = { mode = "wpa2-sha256"; @@ -485,7 +497,9 @@ in { type = types.enum ["disabled" "empty" "clear"]; description = mdDoc '' Send empty SSID in beacons and ignore probe request frames that do not - specify full SSID, i.e., require stations to know SSID. + specify full SSID, i.e., require stations to know SSID. Note that this does + not increase security, since your clients will then broadcast the SSID instead, + which can increase congestion. - {var}`"disabled"`: Advertise ssid normally. - {var}`"empty"`: send empty (length=0) SSID in beacon and ignore probe request for broadcast SSID @@ -850,7 +864,10 @@ in { enable = mkOption { default = false; type = types.bool; - description = mdDoc "Enables support for IEEE 802.11be (WiFi 7, EHT)"; + description = mdDoc '' + Enables support for IEEE 802.11be (WiFi 7, EHT). This is currently experimental + and requires you to manually enable CONFIG_IEEE80211BE when building hostapd. + ''; }; singleUserBeamformer = mkOption { @@ -956,7 +973,7 @@ in { serviceConfig = { ExecStart = "${pkgs.hostapd}/bin/hostapd ${concatStringsSep " " runtimeConfigFiles}"; Restart = "always"; - ExecReload = "/bin/kill -HUP $MAINPID"; + ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; RuntimeDirectory = "hostapd"; # Hardening