{ hostName }: { pkgs, ... }: let wan = "end0"; lan = "enp1s0"; bridge = "br-lan"; devices = "devices-vlan"; wifi = "wifi-vlan"; in { boot.kernel = { sysctl = { "net.ipv4.conf.all.forwarding" = true; "net.ipv6.conf.all.forwarding" = false; "net.ipv4.conf.default.rp_filter" = 1; "net.ipv4.conf.${wan}.rp_filter" = 1; "net.ipv4.conf.${bridge}.rp_filter" = 0; }; }; environment.systemPackages = with pkgs; [ arp-scan ]; systemd.network = { wait-online.anyInterface = true; netdevs = { "00-${devices}" = { netdevConfig = { Name = devices; Kind = "vlan"; }; vlanConfig.Id = 30; }; "00-${wifi}" = { netdevConfig = { Name = wifi; Kind = "vlan"; }; vlanConfig.Id = 40; }; "20-${bridge}" = { netdevConfig = { Kind = "bridge"; Name = bridge; }; }; }; networks = { "10-${wan}" = { matchConfig.Name = wan; linkConfig.RequiredForOnline = "routable"; networkConfig = { DHCP = "ipv4"; IPv6AcceptRA = true; DNSOverTLS = true; DNSSEC = true; IPv6PrivacyExtensions = false; IPForward = true; }; }; "30-${lan}" = { matchConfig.Name = lan; linkConfig.RequiredForOnline = "enslaved"; networkConfig = { Bridge = bridge; ConfigureWithoutCarrier = true; VLAN = [ devices wifi ]; }; }; "40-${bridge}" = { matchConfig.Name = bridge; bridgeConfig = { }; address = [ "192.168.20.1/24" ]; networkConfig = { ConfigureWithoutCarrier = true; }; linkConfig.RequiredForOnline = "no"; }; "50-${devices}" = { matchConfig = { Name = devices; Type = "vlan"; }; address = [ "192.168.30.1/24" ]; }; "50-${wifi}" = { matchConfig = { Name = wifi; Type = "vlan"; }; address = [ "192.168.40.1/24" ]; }; }; }; networking = { inherit hostName; useNetworkd = true; useDHCP = false; nat.enable = false; firewall.enable = false; nftables = { enable = true; checkRuleset = false; ruleset = '' define WAN=${wan} define LAN=${lan} define BRIDGE=${bridge} define DEVICES=${devices} define WIFI=${wifi} table inet filter { chain input { type filter hook input priority 0; policy drop; iifname $BRIDGE accept comment "Allow local network to access the router" iifname { $DEVICES, $WIFI } udp dport { 53, 67, 68 } accept comment "DHCP & DNS for vlans" iifname { $WAN, $DEVICES, $WIFI } ct state { established, related } accept comment "Allow established traffic" iifname $WAN icmp type { echo-request, destination-unreachable, time-exceeded } counter accept comment "icmp stuff" iifname { $WAN, $WIFI } tcp dport 3128 accept comment "Allow SSH in" iifname $WAN counter drop comment "Drop all other traffic from wan" iifname "lo" accept comment "Accept everything from loopback" } chain forward { type filter hook forward priority filter; policy drop; iifname $BRIDGE oifname $BRIDGE accept comment "Allow forwarding internal traffic" iifname { $WAN, $WIFI } oifname $BRIDGE tcp dport { 22, 80, 443, 27750 } accept comment "Allow forwarding external traffic to services" iifname $BRIDGE oifname $WIFI ct state { established, related } accept comment "Allow established traffic" iifname $WIFI oifname $BRIDGE ct state { established, related } accept comment "Allow established traffic" iifname { $BRIDGE, $DEVICES, $WIFI } oifname $WAN accept comment "Allow trusted LAN to WAN" iifname $WAN oifname { $BRIDGE, $DEVICES, $WIFI } ct state { established, related } accept comment "Allow established traffic" } } table ip nat { chain prerouting { type nat hook prerouting priority -100; policy accept; fib daddr type local tcp dport { 80, 443 } dnat to 192.168.20.200 fib daddr type local tcp dport 22 dnat to 192.168.20.201:2222 fib daddr type local tcp dport 27750 dnat to 192.168.20.202:27750 } chain postrouting { type nat hook postrouting priority 100; policy accept; oifname $WAN masquerade iifname $BRIDGE oifname $BRIDGE masquerade iifname $WIFI oifname $BRIDGE masquerade } } ''; }; }; services.openssh.ports = [ 22 3128 ]; services.resolved.enable = false; services.dnsmasq = { enable = true; settings = { server = [ "9.9.9.9" "9.9.9.10" ]; domain-needed = true; bogus-priv = true; no-resolv = true; cache-size = 1000; dhcp-range = [ # format TAG,START,END,MASK,LEASE "${bridge},192.168.20.50,192.168.20.90,255.255.255.0,24h" "${devices},192.168.30.10,192.168.30.240,255.255.255.0,24h" "${wifi},192.168.40.10,192.168.40.240,255.255.255.0,24h" ]; interface = [ bridge devices wifi ]; # dhcp-host = [ # "192.168.20.1,set:${bridge}" # "192.168.30.1,set:${devices}" # "192.168.40.1,set:${wifi}" # ]; dhcp-option = [ "${bridge},option:router,192.168.20.1" "${bridge},option:dns-server,192.168.20.1" "${devices},option:router,192.168.30.1" "${devices},option:dns-server,192.168.30.1" "${wifi},option:router,192.168.40.1" "${wifi},option:dns-server,192.168.40.1" ]; local = "/lan/"; domain = "lan"; expand-hosts = true; no-hosts = true; address = "/router.lan/192.168.20.1"; }; }; services.irqbalance.enable = false; }