diff --git a/flake.nix b/flake.nix index 905599b..85018e6 100644 --- a/flake.nix +++ b/flake.nix @@ -558,7 +558,7 @@ in makeServerConfig { inherit hostname; - + extraModules = sd-images.packages.${system}.RockPro64v2.modules ++ [ (networkModule { inherit macAddress selfIp; }) (if unlockMounts && mountVolumes then @@ -655,13 +655,13 @@ else { }; }) - (if unlockMounts && mountVolumes && enableJellyfin then { - services.jellyfin = { - enable = true; - openFirewall = true; - }; - users.users.asonix.extraGroups = [ "jellyfin" ]; - } else {}) + (if unlockMounts && mountVolumes && enableJellyfin then { + services.jellyfin = { + enable = true; + openFirewall = true; + }; + users.users.asonix.extraGroups = [ "jellyfin" ]; + } else { }) ]; }; diff --git a/modules/router/default.nix b/modules/router/default.nix index e332557..d6f2633 100644 --- a/modules/router/default.nix +++ b/modules/router/default.nix @@ -12,11 +12,17 @@ in { boot.kernel = { sysctl = { + "net.ipv6.conf.all.forwarding" = 1; + "net.ipv6.conf.${bridge}.accept_ra" = 2; + "net.ipv6.conf.${devices}.accept_ra" = 2; + "net.ipv6.conf.${wifi}.accept_ra" = 2; + "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; + "net.ipv4.conf.${devices}.rp_filter" = 0; + "net.ipv4.conf.${wifi}.rp_filter" = 0; }; }; @@ -27,14 +33,40 @@ in systemd.network = { wait-online.anyInterface = true; netdevs = { - "00-${devices}" = { + # Attempted hack for more ipv6 prefixes + # I got the prefixes but networkd wasn't smart enough to use them + # "00-vrrp-1" = { + # netdevConfig = { + # Name = "vrrp-1"; + # Kind = "macvlan"; + # MACAddress = "00:00:5e:00:01:05"; + # }; + # macvlanConfig.Mode = "bridge"; + # }; + # "00-vrrp-2" = { + # netdevConfig = { + # Name = "vrrp-2"; + # Kind = "macvlan"; + # MACAddress = "00:00:5e:00:02:05"; + # }; + # macvlanConfig.Mode = "bridge"; + # }; + # "00-vrrp-3" = { + # netdevConfig = { + # Name = "vrrp-3"; + # Kind = "macvlan"; + # MACAddress = "00:00:5e:00:03:05"; + # }; + # macvlanConfig.Mode = "bridge"; + # }; + "10-${devices}" = { netdevConfig = { Name = devices; Kind = "vlan"; }; vlanConfig.Id = 30; }; - "00-${wifi}" = { + "10-${wifi}" = { netdevConfig = { Name = wifi; Kind = "vlan"; @@ -49,16 +81,32 @@ in }; }; networks = { - "10-${wan}" = { + # "05-vrrp" = { + # matchConfig.Name = "vrrp-*"; + # linkConfig.RequiredForOnline = "routable"; + # networkConfig = { + # DHCP = "ipv6"; + # IPv6AcceptRA = true; + # DNSOverTLS = true; + # DNSSEC = true; + # IPv6PrivacyExtensions = true; + # IPForward = true; + # LinkLocalAddressing = "ipv6"; + # }; + # dhcpV6Config.PrefixDelegationHint = "::/64"; + # }; + "06-${wan}" = { matchConfig.Name = wan; linkConfig.RequiredForOnline = "routable"; networkConfig = { - DHCP = "ipv4"; + DHCP = true; IPv6AcceptRA = true; DNSOverTLS = true; DNSSEC = true; - IPv6PrivacyExtensions = false; + IPv6PrivacyExtensions = true; IPForward = true; + LinkLocalAddressing = "ipv6"; + # MACVLAN = [ "vrrp-1" "vrrp-2" "vrrp-3" ]; }; }; "30-${lan}" = { @@ -78,6 +126,9 @@ in ]; networkConfig = { ConfigureWithoutCarrier = true; + IPv6SendRA = true; + DHCPPrefixDelegation = true; + LinkLocalAddressing = "ipv6"; }; linkConfig.RequiredForOnline = "no"; }; @@ -89,6 +140,7 @@ in address = [ "192.168.30.1/24" ]; + networkConfig = { }; linkConfig.RequiredForOnline = "routable"; }; "50-${wifi}" = { @@ -99,6 +151,7 @@ in address = [ "192.168.40.1/24" ]; + networkConfig = { }; linkConfig.RequiredForOnline = "routable"; }; }; @@ -116,52 +169,155 @@ in enable = true; checkRuleset = false; ruleset = '' - define WAN=${wan} - define LAN=${lan} - define BRIDGE=${bridge} - define DEVICES=${devices} - define WIFI=${wifi} + define WAN=${wan} + define LAN=${lan} - table inet filter { + define BRIDGE=${bridge} - chain input { - type filter hook input priority 0; policy drop; + define DEVICES=${devices} - 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; + define WIFI=${wifi} - 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" - } - } + define HTTP_HOST=192.168.20.200 + define FORGEJO_HOST=192.168.20.201 + define FORGEJO_SSH_PORT=2222 + define DRAWPILE_HOST=192.168.20.202 + define DRAWPILE_TCP_PORT=27750 - 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 + table inet filter { + set hosted_services_tcp { + type inet_service; flags interval; + elements = { 22, 80, 443, $DRAWPILE_TCP_PORT } + } + + set internal_access_tcp { + type inet_service; flags interval; + elements = { 22, 3128 } + } + + set internal_access_udp { + type inet_service; flags interval; + elements = { 51820 } + } + + set network_required_udp { + type inet_service; flags interval; + elements = { 53, 67, 68, 546, 547 } + } + + set firewall_out_tcp_accepted { + type inet_service; flags interval; + elements = { 22, 53, 80, 443, 853 } + } + + set firewall_out_udp_accepted { + type inet_service; flags interval; + elements = { 53, 123, 67, 68, 546, 547 } + } + + chain global { + ct state { established, related } accept + ct state invalid drop + ip protocol icmp accept + ip6 nexthdr icmpv6 accept + } + + chain reject_politely { + reject with icmp type port-unreachable + } + + chain bridge_in { + tcp dport @hosted_services_tcp ct state new accept comment "Allow bridge access to router services" + } + chain bridge_out { + accept + } + + chain devices_in {} + chain devices_out { + udp dport 123 ct state new accept comment "Allow NTP from devices network" + tcp dport { 80, 443 } ct state new accept comment "Allow HTTP/S from devices network" + } + + chain wifi_in {} + chain wifi_out { + accept + } + + chain rate_limit { + flow table rate-limit-ftable { ip saddr limit rate 2/minute } accept comment "Allow rate limited" + } + + chain forward { + type filter hook forward priority filter; policy drop; + + jump global + + oifname vmap { + $BRIDGE : jump bridge_in, + $DEVICES : jump devices_in, + $WIFI : jump wifi_in + } + + oifname $WAN iifname vmap { + $BRIDGE : jump bridge_out, + $DEVICES : jump devices_out, + $WIFI : jump wifi_out + } + } + + chain input { + type filter hook input priority 0; policy drop; + + jump global + + iifname lo accept + + tcp dport @internal_access_tcp ct state new iifname vmap { + $BRIDGE : accept, + $DEVICES : jump reject_politely, + $WIFI : jump rate_limit, + $WAN : jump rate_limit + } + + udp dport @internal_access_udp ct state new iifname vmap { + $BRIDGE : accept, + $DEVICES : jump reject_politely, + $WIFI : jump rate_limit, + $WAN : jump rate_limit + } + + udp dport @network_required_udp ct state new accept comment "Allow internal network required stuff" + + jump reject_politely + } + + chain output { + type filter hook output priority 100; policy drop; + + jump global + + tcp dport @firewall_out_tcp_accepted ct state new accept + udp dport @firewall_out_udp_accepted ct state new accept + + jump reject_politely + } } - chain postrouting { - type nat hook postrouting priority 100; policy accept; - oifname $WAN masquerade - iifname $BRIDGE oifname $BRIDGE masquerade - iifname $WIFI oifname $BRIDGE masquerade + table ip nat { + chain prerouting { + type nat hook prerouting priority -100; policy accept; + fib daddr type local tcp dport { 80, 443 } dnat to $HTTP_HOST + fib daddr type local tcp dport 22 dnat to $FORGEJO_HOST:$FORGEJO_SSH_PORT + fib daddr type local tcp dport $DRAWPILE_TCP_PORT dnat to $DRAWPILE_HOST + } + + chain postrouting { + type nat hook postrouting priority 100; policy accept; + oifname $WAN masquerade + oifname $BRIDGE masquerade + } } - } ''; }; }; @@ -178,13 +334,20 @@ in bogus-priv = true; no-resolv = true; + # dhcpv6 stuff + # enable-ra = true; + # dhcp-authoritative = true; + # strict-order = 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" + # format TAG,START,END,?MASK,?options,LEASE + "${bridge},192.168.20.50,192.168.20.90,24h" + + "${devices},192.168.30.10,192.168.30.240,24h" + + "${wifi},192.168.40.10,192.168.40.240,24h" ]; interface = [ bridge devices wifi ]; dhcp-option = [ @@ -203,7 +366,9 @@ in expand-hosts = true; no-hosts = true; - address = "/router.lan/192.168.20.1"; + address = [ + "/router.lan/192.168.20.1" + ]; }; };