feat(ap01): external RADIUS + DHCPv4 + jitterRNGd + stable bridge + default route

Signed-off-by: Ryan Lahfa <ryan@dgnum.eu>
This commit is contained in:
Ryan Lahfa 2024-09-01 18:03:18 +02:00
parent 4fb39070bb
commit 0b94fb5ba7

View file

@ -5,12 +5,17 @@
...
}:
let
inherit (pkgs.liminix.services) oneshot;
inherit (pkgs.pseudofile) symlink dir;
inherit (pkgs) serviceFns;
svc = config.system.service;
secrets-1 = {
ssid = "DGNum 2G prototype (N)";
};
# secrets-1 = {
# ssid = "DGNum 2G prototype (N)";
# # wpa_passphrase = "diamond dogs";
# };
secrets-2 = {
ssid = "DGNum 5G prototype (AX)";
# wpa_passphrase = "diamond dogs";
};
baseParams = {
country_code = "FR";
@ -57,57 +62,31 @@ let
vlan_tagged_interface = "lan";
};
serverRadius = {
radius_server_clients = pkgs.writeText "clients" ''
0.0.0.0/0 dgnum
'';
radius_server_auth_port = 1812;
radius_server_ipv6 = 1;
externalRadius = {
# TODO: when we have proper IPAM, set the right value here.
own_ip_addr = "127.0.0.1";
nas_identifier = "ap01.dgnum.eu";
# No DNS here, hostapd do not support this mode.
auth_server_addr = "129.199.195.129";
auth_server_port = 1812;
auth_server_shared_secret = "read it online";
};
localRadius = {
eap_server = 1;
eap_user_file = pkgs.writeText "user.db" ''
# anonymous login in phase 1
* PEAP
# password based in the secure tunnel in phase 2
"test" MSCHAPV2 "diamond dogs" [2]
'';
# DGNum CA certificate.
ca_cert = builtins.toFile "dgnum-test-ap-ca" (
builtins.readFile ../../keys/certs/dgnum-test-ap-ca.crt
);
# Server certificate for this AP.
server_cert = builtins.toFile "dgnum-ap-server" (
builtins.readFile ../../keys/certs/dgnum-ap-server.crt
);
private_key = builtins.toFile "dgnum-ap-server-pkey" (
builtins.readFile ../../keys/certs/dgnum-ap-server.key.pem
);
};
# externalRadius = {
# own_ip_addr = "";
# nas_identifier = "";
# auth_server_addr = "";
# auth_server_port = 1812;
# auth_server_shared_secret = "dgnum";
# };
mkWifiSta =
params: interface: secrets:
svc.hostapd.build {
inherit interface;
package = pkgs.hostapd-radius;
params = params // secrets;
dependencies = [ config.services.jitter ];
};
in
rec {
imports = [
"${modulesPath}/wlan.nix"
"${modulesPath}/network"
"${modulesPath}/dhcp6c"
"${modulesPath}/hostapd"
"${modulesPath}/ssh"
"${modulesPath}/ntp"
@ -122,10 +101,8 @@ rec {
hostname = "ap01-prototype";
security.pki = {
installCACerts = true;
certificateFiles = [ ../../keys/certs/dgnum-test-ap-ca.crt ];
};
# Get moar random please
services.jitter = svc.jitter-rng.build { };
# SSH keys are handled by the access control module.
dgn-access-control.enable = true;
@ -136,25 +113,66 @@ rec {
passwd = "$6$jVXFFOp8HBYmgINR$lutB4kvw.W1jlXRby9ZYAgBitQ32RxQdYAGN.s2x4ris8J07vM6tzlRBQoeLELOIEMClDzbciQV0itfHQnTqd1";
};
services.int = svc.bridge.primary.build { ifname = "int"; };
services.int = svc.bridge.primary.build {
ifname = "int";
macAddressFromInterface = config.hardware.networkInterfaces.lan;
};
services.bridge = svc.bridge.members.build {
primary = services.int;
members = with config.hardware.networkInterfaces; [
lan
wlan0
# wlan0
wlan1
];
};
services.dhcpv4 =
let
iface = services.int;
in
svc.network.dhcp.client.build { interface = iface; };
services.resolvconf = oneshot rec {
name = "resolvconf";
up = ''
. ${serviceFns}
( in_outputs ${name}
for i in $(output ${services.dhcpv4} dns); do
echo "nameserver $i" >> resolv.conf
done
)
'';
dependencies = [
config.services.dhcpv4
];
};
filesystem = dir {
etc = dir {
"resolv.conf" = symlink "${config.services.resolvconf}/.outputs/resolv.conf";
};
};
services.dhcpv4 = svc.network.dhcp.client.build {
interface = config.services.int;
dependencies = [
config.services.hostname
config.services.bridge
];
};
services.dhcpv6 = svc.dhcp6c.client.build {
interface = config.services.int;
dependencies = [
config.services.hostname
config.services.bridge
];
};
services.ipv6 = svc.dhcp6c.address.build {
interface = config.services.int;
client = config.services.dhcpv6;
dependencies = [ config.services.hostname ];
};
services.defaultroute4 = svc.network.route.build {
via = "$(output ${services.dhcpv4} address)";
via = "$(output ${services.dhcpv4} router)";
target = "default";
dependencies = [ services.dhcpv4 ];
};
@ -166,6 +184,8 @@ rec {
pools = {
"pool.ntp.org" = [ "iburst" ];
};
dependencies = [ config.services.jitter ];
};
boot.tftp = {
@ -174,17 +194,16 @@ rec {
};
# wlan0 is the 2.4GHz interface.
services.hostap-1 = mkWifiSta (
baseParams // clientRadius // localRadius // serverRadius // radiusKeyMgmt
) config.hardware.networkInterfaces.wlan0 secrets-1;
# services.hostap-1 = mkWifiSta (
# baseParams // radiusKeyMgmt
# ) config.hardware.networkInterfaces.wlan0 secrets-1;
# wlan1 is the 5GHz interface, e.g. AX capable.
services.hostap-2 = mkWifiSta (
baseParams // clientRadius // localRadius // serverRadius // radiusKeyMgmt // modernParams
baseParams // clientRadius // externalRadius // radiusKeyMgmt // modernParams
) config.hardware.networkInterfaces.wlan1 secrets-2;
defaultProfile.packages = with pkgs; [
zyxel-bootconfig
iw
min-collect-garbage
mtdutils
];