Skip to content

Commit e93e3e8

Browse files
hostapd basic
1 parent 1e14ebf commit e93e3e8

File tree

8 files changed

+274
-94
lines changed

8 files changed

+274
-94
lines changed

desktop/l/hosts.nix

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,17 @@
22

33
{
44
networking.hosts = {
5-
"172.16.40.198" = ["hp0" "hp0eth"]; # adi's room
6-
"172.16.40.141" = ["hp0wifi"];
7-
"172.16.40.142" = ["hp1" "hp1eth"];
8-
"172.16.40.212" = ["hp2" "hp2eth"];
9-
"172.16.40.146" = ["hp3" "hp3eth"]; # savi's room
10-
"172.16.40.130" = ["hp3wifi"];
11-
"172.16.50.232" = ["hp4" "hp4eth"]; # rack
12-
"172.16.40.70" = ["hp5" "hp5eth"];
13-
"172.16.40.122" = ["pi5-1" "pi5-1-eth"];
14-
"172.16.40.62" = ["chromebox3" "chromebox3-eth"];
15-
"127.0.0.1" = ["redpanda-0"];
5+
"172.16.40.198" = [ "hp0" "hp0eth" ]; # adi's room
6+
"172.16.40.141" = [ "hp0wifi" ];
7+
"172.16.40.142" = [ "hp1" "hp1eth" ];
8+
"172.16.40.212" = [ "hp2" "hp2eth" ];
9+
"172.16.40.146" = [ "hp3" "hp3eth" ]; # savi's room
10+
"172.16.40.130" = [ "hp3wifi" ];
11+
"172.16.50.232" = [ "hp4" "hp4eth" ]; # rack
12+
"172.16.40.70" = [ "hp5" "hp5eth" ];
13+
"172.16.40.122" = [ "pi5-1" "pi5-1-eth" ];
14+
"172.16.40.62" = [ "chromebox3" "chromebox3-eth" ];
15+
"172.16.40.46" = [ "l2" ];
16+
"127.0.0.1" = ["redpanda-0" ];
1617
};
1718
}

desktop/l2/Makefile

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@ update:
3434
sudo nix flake update;
3535

3636
sync:
37-
rsync -av /home/das/nixos/desktop/"${EXPECTED_HOSTNAME}"/ "${EXPECTED_HOSTNAME}":/home/das/nixos/desktop/"${EXPECTED_HOSTNAME}"/
38-
#rsync -av /home/das/nixos/modules/ hp1:/home/das/nixos/modules/
37+
rsync -avz /home/das/nixos/ "${EXPECTED_HOSTNAME}":/home/das/nixos/
3938

4039
rebuild_old:
4140
# sudo cp ./flake.nix /etc/nixos/

desktop/l2/flake.nix

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,13 @@
2121
outputs = { self, nixpkgs, home-manager, hyprland, ... }:
2222
let
2323
system = "x86_64-linux";
24+
overlays = [
25+
(final: prev: {
26+
hostapd = import ./hostapd-80211r.nix { pkgs = prev; };
27+
})
28+
];
2429
pkgs = import nixpkgs {
25-
inherit system;
30+
inherit system overlays;
2631
config = {
2732
allowUnfree = true;
2833
allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [
@@ -35,6 +40,7 @@
3540
];
3641
};
3742
};
43+
3844
lib = nixpkgs.lib;
3945
in {
4046
nixosConfigurations = {
@@ -63,5 +69,10 @@
6369
];
6470
};
6571
};
72+
packages = {
73+
x86_64-linux = {
74+
hostapd = pkgs.hostapd;
75+
};
76+
};
6677
};
6778
}

desktop/l2/hostapd-80211r.nix

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#
2+
# hostapd-80211r.nix
3+
#
4+
5+
{ pkgs ? import <nixpkgs> {} }:
6+
7+
pkgs.hostapd.override {
8+
extraConfig = ''
9+
CONFIG_DRIVER_NL80211=y
10+
CONFIG_IEEE80211R=y
11+
CONFIG_IEEE80211W=y
12+
CONFIG_IEEE80211N=y
13+
CONFIG_IEEE80211AC=y
14+
CONFIG_IEEE80211AX=y
15+
CONFIG_ACS=y
16+
CONFIG_SAE=y
17+
CONFIG_FULL_DYNAMIC_VLAN=y
18+
CONFIG_VLAN_NETLINK=y
19+
CONFIG_RADIUS_SERVER=y
20+
CONFIG_HS20=y
21+
CONFIG_WNM=y
22+
CONFIG_MBO=y
23+
CONFIG_FST=y
24+
CONFIG_FST_TEST=y
25+
CONFIG_CTRL_IFACE=y
26+
'';
27+
}

desktop/l2/hostapd.nix

Lines changed: 79 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -2,81 +2,91 @@
22
# hostapd.nix
33
#
44

5-
{ config, pkgs, ... }:
5+
#
6+
# NOT using service.hostapd, because it has limited configuration capabilities
7+
# https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/networking/hostapd.nix
8+
#
9+
# Using custom systemd services to run hostapd per interface
10+
#
11+
# systemctl status hostapd-wlp35s0
12+
# systemctl status hostapd-wlp65s0
13+
# systemctl status hostapd-wlp70s0
14+
#
15+
# nix pkgs source
16+
# https://github.com/NixOS/nixpkgs/blob/master/pkgs/by-name/ho/hostapd/package.nix
17+
# https://w1.fi/hostapd/
18+
# https://github.com/latelee/hostapd
19+
#
20+
# Giant NixPkgs PR: https://github.com/NixOS/nixpkgs/pull/222536
21+
#
22+
#
23+
{ config, pkgs, lib, ... }:
624

725
let
8-
interface1 = "wlp35s0"; # e.g. 2.4GHz channel 6
9-
interface2 = "wlp65s0"; # e.g. 5GHz channel 100
10-
interface3 = "wlp70s0"; # e.g. 5GHz channel 149
26+
radios = {
27+
wlp35s0 = {
28+
channel = 6;
29+
hwMode = "g";
30+
};
31+
wlp65s0 = {
32+
channel = 100;
33+
hwMode = "a";
34+
};
35+
wlp70s0 = {
36+
channel = 149;
37+
hwMode = "a";
38+
};
39+
};
1140

12-
commonHostapdSettings = ''
13-
ssid=myssid
14-
wpa=2
15-
wpa_key_mgmt=SAE
16-
rsn_pairwise=CCMP
17-
sae_require_mfp=1
18-
ieee80211w=2
19-
ieee80211n=1
20-
ieee80211ac=1
21-
ieee80211ax=1
22-
wmm_enabled=1
41+
mkHostapdConf = iface: cfg:
2342

24-
# WMM tuning for Best Effort (AC_BE)
25-
wmm_ac_be_aifs=1
26-
wmm_ac_be_cwmin=4
27-
wmm_ac_be_cwmax=4
28-
wmm_ac_be_txop_limit=32
29-
wmm_ac_be_acm=0
43+
pkgs.writeText "hostapd-${iface}.conf" ''
44+
driver=nl80211
45+
ssid=myssid
46+
hw_mode=${cfg.hwMode}
47+
channel=${toString cfg.channel}
48+
ctrl_interface=/run/hostapd-${iface}
49+
ctrl_interface_group=0
3050
31-
# 802.11r (Fast BSS Transition)
32-
ieee80211r=1
33-
mobility_domain=4f57
34-
ft_over_ds=1
35-
ft_psk_generate_local=1
36-
nas_identifier=myssid-ap
37-
'';
38-
in
39-
{
40-
services.hostapd = {
41-
enable = true;
42-
radios = {
43-
"${interface1}" = {
44-
config = pkgs.writeText "hostapd-1.conf" (''
45-
interface=${interface1}
46-
hw_mode=g
47-
channel=6
48-
${commonHostapdSettings}
49-
'');
50-
};
51-
"${interface2}" = {
52-
config = pkgs.writeText "hostapd-2.conf" (''
53-
interface=${interface2}
54-
hw_mode=a
55-
channel=100
56-
${commonHostapdSettings}
57-
'');
58-
};
59-
"${interface3}" = {
60-
config = pkgs.writeText "hostapd-3.conf" (''
61-
interface=${interface3}
62-
hw_mode=a
63-
channel=149
64-
${commonHostapdSettings}
65-
'');
66-
};
67-
};
68-
};
51+
# WPA3 (SAE) configuration
52+
wpa=2
53+
wpa_key_mgmt=SAE
54+
rsn_pairwise=CCMP
55+
sae_require_mfp=1
56+
ieee80211w=2
57+
wpa_passphrase=mysecurepassword
6958
70-
# Disable DHCP on all interfaces, use static IP or bridge later
71-
networking.interfaces.${interface1}.useDHCP = false;
72-
networking.interfaces.${interface2}.useDHCP = false;
73-
networking.interfaces.${interface3}.useDHCP = false;
59+
# Enable 802.11n/ac/ax
60+
ieee80211n=1
61+
ieee80211ac=1
62+
ieee80211ax=1
7463
75-
networking.interfaces.${interface1}.ipv4.addresses = [ { address = "192.168.30.1"; prefixLength = 24; } ];
76-
networking.interfaces.${interface2}.ipv4.addresses = [ { address = "192.168.31.1"; prefixLength = 24; } ];
77-
networking.interfaces.${interface3}.ipv4.addresses = [ { address = "192.168.32.1"; prefixLength = 24; } ];
64+
wmm_enabled=1
7865
79-
networking.firewall.enable = true;
80-
networking.nat.enable = true;
81-
networking.nat.externalInterface = "enp1s0";
66+
# Optional WMM tuning
67+
wmm_ac_be_aifs=1
68+
wmm_ac_be_cwmin=4
69+
wmm_ac_be_cwmax=4
70+
wmm_ac_be_txop_limit=32
71+
wmm_ac_be_acm=0
72+
'';
73+
74+
hostapdConfigs = lib.mapAttrs (iface: cfg: mkHostapdConf iface cfg) radios;
75+
76+
in {
77+
systemd.services = lib.mapAttrs' (iface: confPath: {
78+
name = "hostapd-${iface}";
79+
value = {
80+
description = "Hostapd on ${iface}";
81+
wantedBy = [ "multi-user.target" ];
82+
after = [ "network.target" ];
83+
serviceConfig = {
84+
ExecStart = "${pkgs.hostapd}/bin/hostapd -i ${iface} ${confPath}";
85+
Restart = "on-failure";
86+
RuntimeDirectory = "hostapd-${iface}";
87+
};
88+
};
89+
}) hostapdConfigs;
8290
}
91+
92+
# end

desktop/l2/hostapd.notes

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
#
2+
# hostapd.nix
3+
#
4+
5+
#
6+
# NOT using service.hostapd, because it has limited configuration capabilities
7+
# https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/networking/hostapd.nix
8+
#
9+
# Using custom systemd services to run hostapd per interface
10+
#
11+
# systemctl status hostapd-wlp35s0
12+
# systemctl status hostapd-wlp65s0
13+
# systemctl status hostapd-wlp70s0
14+
#
15+
# nix pkgs source
16+
# https://github.com/NixOS/nixpkgs/blob/master/pkgs/by-name/ho/hostapd/package.nix
17+
# https://w1.fi/hostapd/
18+
# https://github.com/latelee/hostapd
19+
#
20+
{ config, pkgs, lib, ... }:
21+
22+
let
23+
radios = {
24+
wlp35s0 = {
25+
channel = 6;
26+
hwMode = "g";
27+
mac = "8E:37:6C:2E:40:FA";
28+
};
29+
wlp65s0 = {
30+
channel = 100;
31+
hwMode = "a";
32+
mac = "F6:FB:A4:06:06:82";
33+
};
34+
wlp70s0 = {
35+
channel = 149;
36+
hwMode = "a";
37+
mac = "AA:72:0E:90:28:4A";
38+
};
39+
};
40+
41+
# # 🔐 Secure unique R1KH keys per destination MAC
42+
# r1khSecrets = {
43+
# "8E:37:6C:2E:40:FA" = "fdeadbeef00000000000000000000001";
44+
# "F6:FB:A4:06:06:82" = "cafef00dbabe00000000000000000002";
45+
# "AA:72:0E:90:28:4A" = "facefeedfeed00000000000000000003";
46+
# };
47+
48+
# normalizeMac = mac: builtins.replaceStrings [":"]
49+
# [""] (lib.strings.toLower mac);
50+
51+
# safeNASID = mac: "ap-${normalizeMac mac}";
52+
53+
# r0khLines = lib.concatStringsSep "\n" (
54+
# lib.mapAttrsToList (_iface: cfg:
55+
# let mac = normalizeMac cfg.mac;
56+
# in "r0kh=${normalizeMac peer.mac},${safeNASID peer.mac},${r1khSecrets.${peer.mac}}"
57+
# ) radios
58+
# );
59+
60+
# mkHostapdConf = iface: cfg: let
61+
# r1khLines = lib.concatStringsSep "\n" (
62+
# lib.mapAttrsToList (_peerIface: peerCfg:
63+
# if peerCfg.mac != cfg.mac then
64+
# "r1kh=${normalizeMac peerCfg.mac},${r1khSecrets.${peerCfg.mac}}"
65+
# else
66+
# ""
67+
# ) radios
68+
# );
69+
#\${r0khLines}
70+
#\${r1khLines}
71+
72+
in
73+
pkgs.writeText "hostapd-${iface}.conf" ''
74+
driver=nl80211
75+
ssid=myssid
76+
hw_mode=${cfg.hwMode}
77+
channel=${toString cfg.channel}
78+
ctrl_interface=/run/hostapd-${iface}
79+
ctrl_interface_group=0
80+
81+
wpa=2
82+
wpa_key_mgmt=SAE
83+
rsn_pairwise=CCMP
84+
sae_require_mfp=1
85+
ieee80211w=2
86+
ieee80211n=1
87+
ieee80211ac=1
88+
ieee80211ax=1
89+
wmm_enabled=1
90+
91+
# Fast BSS Transition with push mode
92+
#ieee80211r=1
93+
pmk_r1_push=1
94+
mobility_domain=4f57
95+
ft_over_ds=1
96+
ft_psk_generate_local=1
97+
nas_identifier=myssid-ap
98+
99+
#r0khLines
100+
#r1khLines
101+
102+
# WMM tuning
103+
wmm_ac_be_aifs=1
104+
wmm_ac_be_cwmin=4
105+
wmm_ac_be_cwmax=4
106+
wmm_ac_be_txop_limit=32
107+
wmm_ac_be_acm=0
108+
'';
109+
110+
hostapdConfigs = lib.mapAttrs (iface: cfg: mkHostapdConf iface cfg) radios;
111+
112+
in {
113+
systemd.services = lib.mapAttrs' (iface: confPath: {
114+
name = "hostapd-${iface}";
115+
value = {
116+
description = "Hostapd on ${iface}";
117+
wantedBy = [ "multi-user.target" ];
118+
after = [ "network.target" ];
119+
serviceConfig = {
120+
ExecStart = "${pkgs.hostapd}/bin/hostapd -i ${iface} ${confPath}";
121+
Restart = "on-failure";
122+
RuntimeDirectory = "hostapd-${iface}";
123+
};
124+
};
125+
}) hostapdConfigs;
126+
}
127+
128+
129+
# end

0 commit comments

Comments
 (0)