From 6b0bc35f83a14ee9f9a34e1af782f1ef4c363d6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= Date: Wed, 17 Jan 2024 19:13:22 +0100 Subject: nixos/router: rework router to use networkd --- flake.lock | 6 +- nixos/machine/adm-omnia.nix | 18 ++- nixos/routers/router.nix | 349 ++++++++++++++++++++++++++++---------------- nixos/routers/wifi-adm.nix | 51 +++---- nixos/routers/wifi-spt.nix | 130 ++++++++++------- 5 files changed, 343 insertions(+), 211 deletions(-) diff --git a/flake.lock b/flake.lock index 0df9031..f3dbd84 100644 --- a/flake.lock +++ b/flake.lock @@ -377,11 +377,11 @@ }, "nixpkgs_4": { "locked": { - "lastModified": 1705341963, - "narHash": "sha256-B+hleatY+0EhKayVpjRDjX2lZM8Ywds2p+Cl9fV1Pzg=", + "lastModified": 1705429789, + "narHash": "sha256-7gQju9WiToi7wI6oahTXiqwJu2RZoV0cg8OGa9YhEvw=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "857390998c1975a34509fccd9f635acde935e1d0", + "rev": "cc3ab0e45687d15cb21663a95f5a53a05abd39e4", "type": "github" }, "original": { diff --git a/nixos/machine/adm-omnia.nix b/nixos/machine/adm-omnia.nix index 437831b..fd6d654 100644 --- a/nixos/machine/adm-omnia.nix +++ b/nixos/machine/adm-omnia.nix @@ -40,9 +40,21 @@ with lib; { }; #systemd.services."pppd-wan".after = ["sys-subsystem-net-devices-end2.device"]; - networking.bridges = { - brlan.interfaces = ["lan1" "lan2" "lan3" "lan4"]; - brguest.interfaces = ["lan0"]; + environment.systemPackages = [pkgs.tcpdump]; + + networking = { + useNetworkd = true; + useDHCP = false; + }; + systemd.network.networks = { + "lan-brlan" = { + matchConfig.Name = "lan[1-4]"; + networkConfig.Bridge = "brlan"; + }; + "lan0-brguest" = { + matchConfig.Name = "lan0"; + networkConfig.Bridge = "brguest"; + }; }; }; } diff --git a/nixos/routers/router.nix b/nixos/routers/router.nix index 50405dc..da625e4 100644 --- a/nixos/routers/router.nix +++ b/nixos/routers/router.nix @@ -40,143 +40,242 @@ in { }; config = mkIf cnf.enable { - networking = { - interfaces = { - brlan.ipv4.addresses = [ - { - address = cnf.lanIP; - prefixLength = cnf.lanPrefix; - } - ]; - brguest.ipv4.addresses = [ - { - address = "192.168.1.1"; - prefixLength = 24; - } - ]; - }; - vlans = { - "brlan.guest" = { - interface = "brlan"; - id = 100; + systemd.network = { + netdevs = { + "brlan".netdevConfig = { + Kind = "bridge"; + Name = "brlan"; + }; + "brguest".netdevConfig = { + Kind = "bridge"; + Name = "brguest"; }; }; - bridges = { - brlan.interfaces = []; - brguest.interfaces = ["brlan.guest"]; - }; - nat = { - enable = true; - externalInterface = cnf.wan; - internalInterfaces = ["brlan" "brguest"]; - }; - dhcpcd = { - allowInterfaces = [cnf.wan]; - extraConfig = '' - duid - noipv6rs - waitip 6 - - interface ${cnf.wan} - ipv6rs - iaid 1 - - ia_pd 1 brlan - #ia_pd 1/::/64 LAN/0/64 - ''; + networks = { + "${cnf.wan}" = { + matchConfig.Name = cnf.wan; + networkConfig = { + DHCP = "yes"; + DHCPPrefixDelegation = "yes"; + }; + dhcpPrefixDelegationConfig = { + UplinkInterface = ":self"; + SubnetId = 0; + Announce = "no"; + }; + linkConfig.RequiredForOnline = "routable"; + }; + "brlan" = { + matchConfig.Name = "brlan"; + networkConfig = { + Address = "${cnf.lanIP}/${toString cnf.lanPrefix}"; + IPForward = "yes"; + DHCPServer = "yes"; + DHCPPrefixDelegation = "yes"; + IPv6SendRA = "yes"; + IPv6AcceptRA = "no"; + VLAN = ["brlan.brguest"]; + }; + dhcpServerConfig = { + UplinkInterface = cnf.wan; + PoolOffset = cnf.dynIPStart; + PoolSize = cnf.dynIPCount; + EmitDNS = "yes"; + DNS = "1.1.1.1"; + }; + dhcpPrefixDelegationConfig = { + UplinkInterface = cnf.wan; + SubnetId = 1; + Announce = "yes"; + }; + }; + "brguest" = { + matchConfig.Name = "brguest"; + networkConfig = { + Address = "192.168.1.1/24"; + IPForward = "yes"; + DHCPServer = "yes"; + DHCPPrefixDelegation = "yes"; + IPv6SendRA = "yes"; + IPv6AcceptRA = "no"; + }; + dhcpServerConfig = { + UplinkInterface = cnf.wan; + PoolOffset = cnf.dynIPStart; + PoolSize = cnf.dynIPCount; + EmitDNS = "yes"; + DNS = "1.1.1.1"; + }; + dhcpPrefixDelegationConfig = { + UplinkInterface = cnf.wan; + SubnetId = 2; + Announce = "yes"; + }; + }; }; - nameservers = ["1.1.1.1" "8.8.8.8"]; + wait-online.anyInterface = true; }; - services = { - kea = { - dhcp4 = { - enable = true; - settings = { - lease-database = { - name = "/var/lib/kea/dhcp4.leases"; - persist = true; - type = "memfile"; - }; - valid-lifetime = 4000; - renew-timer = 1000; - rebind-timer = 2000; - interfaces-config = { - interfaces = ["brlan" "brguest"]; - service-sockets-max-retries = -1; - }; - option-data = [ - { - name = "domain-name-servers"; - data = "1.1.1.1, 8.8.8.8"; - } - ]; - subnet4 = [ - { - interface = "brlan"; - subnet = "${ipv4.prefix2ip cnf.lanIP cnf.lanPrefix}/${toString cnf.lanPrefix}"; - pools = let - ip_start = ipv4.ipAdd cnf.lanIP cnf.lanPrefix cnf.dynIPStart; - ip_end = ipv4.ipAdd cnf.lanIP cnf.lanPrefix (cnf.dynIPStart + cnf.dynIPCount); - in [{pool = "${ip_start} - ${ip_end}";}]; - option-data = [ - { - name = "routers"; - data = cnf.lanIP; - } - ]; - reservations = [ - { - duid = "e4:6f:13:f3:d5:be"; - ip-address = ipv4.ipAdd cnf.lanIP cnf.lanPrefix 60; - } - ]; - } - { - interface = "brguest"; - subnet = "192.168.1.0/24"; - pools = [{pool = "192.168.1.50 - 192.168.1.254";}]; - "option-data" = [ - { - name = "routers"; - data = "192.168.1.1"; - } - ]; - } - ]; + networking = { + nftables.enable = true; + firewall = { + interfaces = { + "brlan" = { + allowedUDPPorts = [53 67 68]; + allowedTCPPorts = [53]; + }; + "brguest" = { + allowedUDPPorts = [53 67 68]; + allowedTCPPorts = [53]; }; }; + filterForward = true; + extraForwardRules = '' + iifname "brguest" oifname != "${cnf.wan}" drop comment "prevent guest to access lan" + ''; }; - radvd = { + nat = { enable = true; - config = '' - interface brlan { - AdvSendAdvert on; - MinRtrAdvInterval 3; - MaxRtrAdvInterval 10; - prefix ::/64 { - AdvOnLink on; - AdvAutonomous on; - AdvRouterAddr on; - }; - RDNSS 2001:4860:4860::8888 2001:4860:4860::8844 { - }; - }; - ''; + externalInterface = cnf.wan; + internalInterfaces = ["brlan" "brguest"]; }; - kresd = {enable = false;}; }; - systemd.services.kea-dhcp4-server.after = [ - "sys-subsystem-net-devices-brlan.device" - "sys-subsystem-net-devices-brguest.device" - ]; - networking.nftables.enable = true; - networking.firewall = { - filterForward = true; - extraForwardRules = '' - iifname "brguest" oifname != "${cnf.wan}" drop comment "prevent guest to access lan" - ''; + services.resolved = { + enable = true; + dnssec = "true"; + fallbackDns = ["1.1.1.1" "8.8.8.8"]; }; + + #networking = { + # interfaces = { + # brlan.ipv4.addresses = [ + # { + # address = cnf.lanIP; + # prefixLength = cnf.lanPrefix; + # } + # ]; + # brguest.ipv4.addresses = [ + # { + # address = "192.168.1.1"; + # prefixLength = 24; + # } + # ]; + # }; + # vlans = { + # "brlan.guest" = { + # interface = "brlan"; + # id = 100; + # }; + # }; + # bridges = { + # brlan.interfaces = []; + # brguest.interfaces = ["brlan.guest"]; + # }; + # nat = { + # enable = true; + # externalInterface = cnf.wan; + # internalInterfaces = ["brlan" "brguest"]; + # }; + # dhcpcd = { + # allowInterfaces = [cnf.wan]; + # extraConfig = '' + # duid + # noipv6rs + # waitip 6 + + # interface ${cnf.wan} + # ipv6rs + # iaid 1 + + # ia_pd 1 brlan + # #ia_pd 1/::/64 LAN/0/64 + #toString ''; + # }; + #nameservers = ["1.1.1.1" "8.8.8.8"]; + #}; + + #services = { + # kea = { + # dhcp4 = { + # enable = true; + # settings = { + # lease-database = { + # name = "/var/lib/kea/dhcp4.leases"; + # persist = true; + # type = "memfile"; + # }; + # valid-lifetime = 4000; + # renew-timer = 1000; + # rebind-timer = 2000; + # interfaces-config = { + # interfaces = ["brlan" "brguest"]; + # service-sockets-max-retries = -1; + # }; + # option-data = [ + # { + # name = "domain-name-servers"; + # data = "1.1.1.1, 8.8.8.8"; + # } + # ]; + # subnet4 = [ + # { + # interface = "brlan"; + # subnet = "${ipv4.prefix2ip cnf.lanIP cnf.lanPrefix}/${toString cnf.lanPrefix}"; + # pools = let + # ip_start = ipv4.ipAdd cnf.lanIP cnf.lanPrefix cnf.dynIPStart; + # ip_end = ipv4.ipAdd cnf.lanIP cnf.lanPrefix (cnf.dynIPStart + cnf.dynIPCount); + # in [{pool = "${ip_start} - ${ip_end}";}]; + # option-data = [ + # { + # name = "routers"; + # data = cnf.lanIP; + # } + # ]; + # reservations = [ + # { + # duid = "e4:6f:13:f3:d5:be"; + # ip-address = ipv4.ipAdd cnf.lanIP cnf.lanPrefix 60; + # } + # ]; + # } + # { + # interface = "brguest"; + # subnet = "192.168.1.0/24"; + # pools = [{pool = "192.168.1.50 - 192.168.1.254";}]; + # "option-data" = [ + # { + # name = "routers"; + # data = "192.168.1.1"; + # } + # ]; + # } + # ]; + # }; + # }; + # }; + # radvd = { + # enable = true; + # config = '' + # interface brlan { + # AdvSendAdvert on; + # MinRtrAdvInterval 3; + # MaxRtrAdvInterval 10; + # prefix ::/64 { + # AdvOnLink on; + # AdvAutonomous on; + # AdvRouterAddr on; + # }; + # RDNSS 2001:4860:4860::8888 2001:4860:4860::8844 { + # }; + # }; + # ''; + # }; + # kresd = {enable = false;}; + #}; + #systemd.services.kea-dhcp4-server.after = [ + # "sys-subsystem-net-devices-brlan.device" + # "sys-subsystem-net-devices-brguest.device" + #]; }; } diff --git a/nixos/routers/wifi-adm.nix b/nixos/routers/wifi-adm.nix index 9869e3e..26a5e15 100644 --- a/nixos/routers/wifi-adm.nix +++ b/nixos/routers/wifi-adm.nix @@ -107,33 +107,30 @@ in { }; }; }; - networking = { - # TODO wlanInterface doesn't work right now because it uses invalid - # command and seems to just configure only first interface. It is just - # wrong. - #wlanInterfaces = { - # "${cnf.ar9287.interface}.nela" = { - # device = "${cnf.ar9287.interface}"; - # mac = "06:f0:21:23:2b:00"; - # }; - # "${cnf.ar9287.interface}.milan" = { - # device = "${cnf.ar9287.interface}"; - # mac = "0a:f0:21:23:2b:00"; - # }; - #}; - bridges = { - brlan.interfaces = filter (v: v != null) [ - cnf.ar9287.interface - cnf.qca988x.interface - ]; - brguest.interfaces = optionals (cnf.ar9287.interface != null) [ - "${cnf.ar9287.interface}.nela" - "${cnf.ar9287.interface}.milan" - ]; - # ++ (optionals (cnf.qca988x.interface != null) [ - # "${cnf.qca988x.interface}.nela" - # "${cnf.qca988x.interface}.milan" - # ]); + systemd.network.networks = { + "lan-${cnf.ar9287.interface}" = { + matchConfig.Name = cnf.ar9287.interface; + networkConfig.Bridge = "brlan"; + }; + "lan-${cnf.ar9287.interface}.nela" = { + matchConfig.Name = "${cnf.ar9287.interface}.nela"; + networkConfig.Bridge = "brguest"; + }; + "lan-${cnf.ar9287.interface}.milan" = { + matchConfig.Name = "${cnf.ar9287.interface}.milan"; + networkConfig.Bridge = "brguest"; + }; + "lan-${cnf.qca988x.interface}" = { + matchConfig.Name = cnf.qca988x.interface; + networkConfig.Bridge = "brlan"; + }; + "lan-${cnf.qca988x.interface}.nela" = { + matchConfig.Name = "${cnf.qca988x.interface}.nela"; + networkConfig.Bridge = "brguest"; + }; + "lan-${cnf.qca988x.interface}.milan" = { + matchConfig.Name = "${cnf.qca988x.interface}.milan"; + networkConfig.Bridge = "brguest"; }; }; }; diff --git a/nixos/routers/wifi-spt.nix b/nixos/routers/wifi-spt.nix index e726b84..87cbd14 100644 --- a/nixos/routers/wifi-spt.nix +++ b/nixos/routers/wifi-spt.nix @@ -30,60 +30,84 @@ in { config = mkIf cnf.enable { services.hostapd = { - #enable = true; - #countryCode = "CZ"; - #interfaces = - # (optionalAttrs (cnf.ar9287.interface != null) { - # "${cnf.ar9287.interface}" = hostapd.qualcomAtherosAR9287 { - # inherit (cnf.ar9287) channel; - # bssid = "@BSSID_AR9287_0@"; - # ssid = "TurrisRules"; - # wpa = 2; - # wpaPassphrase = "@PASS_TURRIS_RULES@"; - # bridge = "brlan"; - # bss = { - # "${cnf.ar9287.interface}.guest" = { - # bssid = "@BSSID_AR9287_1@"; - # ssid = "Kocovi"; - # wpa = 2; - # wpaPassphrase = "@PASS_KOCOVI@"; - # bridge = "brguest"; - # }; - # }; - # }; - # }) - # // (optionalAttrs (cnf.qca988x.interface != null) { - # "${cnf.qca988x.interface}" = hostapd.qualcomAtherosQCA988x { - # inherit (cnf.qca988x) channel; - # bssid = "@BSSID_QCA988X_0@"; - # ssid = "TurrisRules5"; - # wpa = 2; - # wpaPassphrase = "@PASS_TURRIS_RULES@"; - # bridge = "brlan"; - # bss = { - # "${cnf.qca988x.interface}.guest" = { - # bssid = "@BSSID_QCA988X_1@"; - # ssid = "Kocovi"; - # wpa = 2; - # wpaPassphrase = "@PASS_KOCOVI@"; - # bridge = "brguest"; - # }; - # }; - # }; - # }); + enable = true; + radios = { + "${cnf.ar9287.interface}" = mkIf (cnf.ar9287.interface != null) { + countryCode = "CZ"; + inherit (cnf.ar9287) channel; + wifi4 = { + enable = true; + inherit (hostapd.qualcomAtherosAR9287.wifi4) capabilities; + }; + networks = { + "${cnf.ar9287.interface}" = { + bssid = "02:f0:21:23:2b:00"; + ssid = "TurrisRules"; + authentication = { + mode = "wpa2-sha256"; + wpaPasswordFile = "/run/secrets/hostapd-TurrisRules.pass"; + }; + }; + "${cnf.ar9287.interface}.guest" = { + bssid = "0a:f0:21:23:2b:00"; + ssid = "Kocovi"; + authentication = { + mode = "wpa2-sha256"; + wpaPasswordFile = "/run/secrets/hostapd-Kocovi.pass"; + }; + }; + }; + }; + "${cnf.qca988x.interface}" = mkIf (cnf.qca988x.interface != null) { + countryCode = "CZ"; + inherit (cnf.qca988x) channel; + band = "5g"; + wifi4 = { + enable = true; + inherit (hostapd.qualcomAtherosQCA988x.wifi4) capabilities; + }; + wifi5 = { + enable = true; + inherit (hostapd.qualcomAtherosQCA988x.wifi5) capabilities; + }; + networks = { + "${cnf.qca988x.interface}" = { + bssid = "04:f0:21:24:24:d2"; + ssid = "TurrisRules5"; + authentication = { + mode = "wpa2-sha256"; + wpaPasswordFile = "/run/secrets/hostapd-TurrisRules.pass"; + }; + }; + "${cnf.qca988x.interface}.guest" = { + bssid = "0a:f0:21:24:24:d2"; + ssid = "Kocovi"; + authentication = { + mode = "wpa2-sha256"; + wpaPasswordFile = "/run/secrets/hostapd-Kocovi.pass"; + }; + }; + }; + }; + }; }; - networking.bridges = { - brlan.interfaces = filter (v: v != null) [ - cnf.ar9287.interface - cnf.qca988x.interface - ]; - brguest.interfaces = - (optionals (cnf.ar9287.interface != null) [ - "${cnf.ar9287.interface}.guest" - ]) - ++ (optionals (cnf.qca988x.interface != null) [ - "${cnf.qca988x.interface}.guest" - ]); + systemd.network.networks = { + "lan-${cnf.ar9287.interface}" = { + matchConfig.Name = cnf.ar9287.interface; + networkConfig.Bridge = "brlan"; + }; + "lan-${cnf.ar9287.interface}.guest" = { + matchConfig.Name = "${cnf.ar9287.interface}.guest"; + networkConfig.Bridge = "brguest"; + }; + "lan-${cnf.qca988x.interface}" = { + matchConfig.Name = cnf.qca988x.interface; + networkConfig.Bridge = "brlan"; + }; + "lan-${cnf.qca988x.interface}.guest" = { + matchConfig.Name = "${cnf.qca988x.interface}.guest"; + networkConfig.Bridge = "brguest"; + }; }; }; } -- cgit v1.2.3