feat: init AP management via Colmena and Liminix #110
1 changed files with 76 additions and 57 deletions
|
@ -5,12 +5,17 @@
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
|
inherit (pkgs.liminix.services) oneshot;
|
||||||
|
inherit (pkgs.pseudofile) symlink dir;
|
||||||
|
inherit (pkgs) serviceFns;
|
||||||
svc = config.system.service;
|
svc = config.system.service;
|
||||||
secrets-1 = {
|
# secrets-1 = {
|
||||||
ssid = "DGNum 2G prototype (N)";
|
# ssid = "DGNum 2G prototype (N)";
|
||||||
};
|
# # wpa_passphrase = "diamond dogs";
|
||||||
|
# };
|
||||||
secrets-2 = {
|
secrets-2 = {
|
||||||
ssid = "DGNum 5G prototype (AX)";
|
ssid = "DGNum 5G prototype (AX)";
|
||||||
|
# wpa_passphrase = "diamond dogs";
|
||||||
};
|
};
|
||||||
baseParams = {
|
baseParams = {
|
||||||
country_code = "FR";
|
country_code = "FR";
|
||||||
|
@ -57,57 +62,31 @@ let
|
||||||
vlan_tagged_interface = "lan";
|
vlan_tagged_interface = "lan";
|
||||||
};
|
};
|
||||||
|
|
||||||
serverRadius = {
|
externalRadius = {
|
||||||
radius_server_clients = pkgs.writeText "clients" ''
|
# TODO: when we have proper IPAM, set the right value here.
|
||||||
0.0.0.0/0 dgnum
|
own_ip_addr = "127.0.0.1";
|
||||||
'';
|
nas_identifier = "ap01.dgnum.eu";
|
||||||
radius_server_auth_port = 1812;
|
|
||||||
radius_server_ipv6 = 1;
|
# 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 =
|
mkWifiSta =
|
||||||
params: interface: secrets:
|
params: interface: secrets:
|
||||||
svc.hostapd.build {
|
svc.hostapd.build {
|
||||||
inherit interface;
|
inherit interface;
|
||||||
package = pkgs.hostapd-radius;
|
package = pkgs.hostapd-radius;
|
||||||
params = params // secrets;
|
params = params // secrets;
|
||||||
|
dependencies = [ config.services.jitter ];
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
rec {
|
rec {
|
||||||
imports = [
|
imports = [
|
||||||
"${modulesPath}/wlan.nix"
|
"${modulesPath}/wlan.nix"
|
||||||
"${modulesPath}/network"
|
"${modulesPath}/network"
|
||||||
|
"${modulesPath}/dhcp6c"
|
||||||
"${modulesPath}/hostapd"
|
"${modulesPath}/hostapd"
|
||||||
"${modulesPath}/ssh"
|
"${modulesPath}/ssh"
|
||||||
"${modulesPath}/ntp"
|
"${modulesPath}/ntp"
|
||||||
|
@ -122,10 +101,8 @@ rec {
|
||||||
|
|
||||||
hostname = "ap01-prototype";
|
hostname = "ap01-prototype";
|
||||||
|
|
||||||
security.pki = {
|
# Get moar random please
|
||||||
installCACerts = true;
|
services.jitter = svc.jitter-rng.build { };
|
||||||
certificateFiles = [ ../../keys/certs/dgnum-test-ap-ca.crt ];
|
|
||||||
};
|
|
||||||
|
|
||||||
# SSH keys are handled by the access control module.
|
# SSH keys are handled by the access control module.
|
||||||
dgn-access-control.enable = true;
|
dgn-access-control.enable = true;
|
||||||
|
@ -136,25 +113,66 @@ rec {
|
||||||
passwd = "$6$jVXFFOp8HBYmgINR$lutB4kvw.W1jlXRby9ZYAgBitQ32RxQdYAGN.s2x4ris8J07vM6tzlRBQoeLELOIEMClDzbciQV0itfHQnTqd1";
|
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 {
|
services.bridge = svc.bridge.members.build {
|
||||||
primary = services.int;
|
primary = services.int;
|
||||||
members = with config.hardware.networkInterfaces; [
|
members = with config.hardware.networkInterfaces; [
|
||||||
lan
|
lan
|
||||||
wlan0
|
# wlan0
|
||||||
wlan1
|
wlan1
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
services.dhcpv4 =
|
services.resolvconf = oneshot rec {
|
||||||
let
|
name = "resolvconf";
|
||||||
iface = services.int;
|
up = ''
|
||||||
in
|
. ${serviceFns}
|
||||||
svc.network.dhcp.client.build { interface = iface; };
|
( 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 {
|
services.defaultroute4 = svc.network.route.build {
|
||||||
via = "$(output ${services.dhcpv4} address)";
|
via = "$(output ${services.dhcpv4} router)";
|
||||||
target = "default";
|
target = "default";
|
||||||
dependencies = [ services.dhcpv4 ];
|
dependencies = [ services.dhcpv4 ];
|
||||||
};
|
};
|
||||||
|
@ -166,6 +184,8 @@ rec {
|
||||||
pools = {
|
pools = {
|
||||||
"pool.ntp.org" = [ "iburst" ];
|
"pool.ntp.org" = [ "iburst" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
dependencies = [ config.services.jitter ];
|
||||||
};
|
};
|
||||||
|
|
||||||
boot.tftp = {
|
boot.tftp = {
|
||||||
|
@ -174,17 +194,16 @@ rec {
|
||||||
};
|
};
|
||||||
|
|
||||||
# wlan0 is the 2.4GHz interface.
|
# wlan0 is the 2.4GHz interface.
|
||||||
services.hostap-1 = mkWifiSta (
|
# services.hostap-1 = mkWifiSta (
|
||||||
baseParams // clientRadius // localRadius // serverRadius // radiusKeyMgmt
|
# baseParams // radiusKeyMgmt
|
||||||
) config.hardware.networkInterfaces.wlan0 secrets-1;
|
# ) config.hardware.networkInterfaces.wlan0 secrets-1;
|
||||||
# wlan1 is the 5GHz interface, e.g. AX capable.
|
# wlan1 is the 5GHz interface, e.g. AX capable.
|
||||||
services.hostap-2 = mkWifiSta (
|
services.hostap-2 = mkWifiSta (
|
||||||
baseParams // clientRadius // localRadius // serverRadius // radiusKeyMgmt // modernParams
|
baseParams // clientRadius // externalRadius // radiusKeyMgmt // modernParams
|
||||||
) config.hardware.networkInterfaces.wlan1 secrets-2;
|
) config.hardware.networkInterfaces.wlan1 secrets-2;
|
||||||
|
|
||||||
defaultProfile.packages = with pkgs; [
|
defaultProfile.packages = with pkgs; [
|
||||||
zyxel-bootconfig
|
zyxel-bootconfig
|
||||||
iw
|
|
||||||
min-collect-garbage
|
min-collect-garbage
|
||||||
mtdutils
|
mtdutils
|
||||||
];
|
];
|
||||||
|
|
Loading…
Reference in a new issue