Personal Nix setup
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Clean up router rules

+70 -30
+6 -2
modules/router/kernel.nix
··· 60 60 "net.ipv6.conf.all.autoconf" = false; 61 61 "net.ipv6.conf.all.use_tempaddr" = false; 62 62 63 + "net.netfilter.nf_conntrack_tcp_timeout_established" = 7200; 64 + "net.netfilter.nf_conntrack_udp_timeout_stream" = 120; 65 + "net.netfilter.nf_conntrack_max" = 131072; 66 + 63 67 "kernel.kptr_restrict" = 2; 64 - "kernel.dmesg_restrict" = 0; 65 - "kernel.sysrq" = 4; 68 + "kernel.dmesg_restrict" = 1; 69 + "kernel.sysrq" = 0; 66 70 "kernel.unprivileged_bpf_disabled" = true; 67 71 "kernel.perf_event_paranoid" = 3; 68 72 "kernel.kexec_load_disabled" = true;
+5 -6
modules/router/network.nix
··· 75 75 extern = cfg.interfaces.external; 76 76 intern = cfg.interfaces.internal; 77 77 in { 78 - options.modules.router = let 79 - defaultAddress = if intern != null 80 - then ipv4.prettyIp (ipv4.cidrToIpAddress intern.cidr) 81 - else "127.0.0.1"; 82 - in { 78 + options.modules.router = { 83 79 address = mkOption { 84 80 type = types.str; 85 81 default = if intern != null ··· 242 238 IPv6SendRA = cfg.ipv6; 243 239 IPv6AcceptRA = mkIf cfg.ipv6 false; 244 240 }; 245 - fairQueueingControlledDelayConfig = { 241 + cakeConfig = { 246 242 Parent = "root"; 243 + NAT = true; 244 + FlowIsolationMode = "triple"; 245 + Wash = true; 247 246 }; 248 247 dhcpServerStaticLeases = builtins.map (lease: { 249 248 Address = lease.ipAddress;
+59 -22
modules/router/nftables.nix
··· 4 4 let 5 5 cfg = config.modules.router; 6 6 7 + extern = cfg.interfaces.external; 7 8 intern = cfg.interfaces.internal; 8 9 trustedInterfaces = config.networking.firewall.trustedInterfaces; 9 10 internalInterfaces = lists.remove "lo" trustedInterfaces; ··· 60 61 family = "inet"; 61 62 content = let 62 63 inherit (config.networking.firewall) allowedTCPPorts allowedUDPPorts; 63 - tcpAccept = optionalString (allowedTCPPorts != []) '' 64 - tcp dport {${concatMapStringsSep ", " (x: toString x) allowedTCPPorts}} ct state new accept 64 + tcpAccept = let 65 + tcpPorts = concatMapStringsSep ", " (x: toString x) allowedTCPPorts; 66 + in optionalString (allowedTCPPorts != []) '' 67 + tcp dport {${tcpPorts}} ct state new meter tcp-conncount { ip saddr . tcp dport ct count over 150 } counter drop 68 + tcp dport {${tcpPorts}} ct state new meter tcp6-conncount { ip6 saddr . tcp dport ct count over 150 } counter drop 69 + tcp dport {${tcpPorts}} ct state new accept 65 70 ''; 66 - udpAccept = optionalString (allowedTCPPorts != []) '' 67 - udp dport {${concatMapStringsSep ", " (x: toString x) allowedUDPPorts}} ct state new accept 71 + udpAccept = let 72 + udpPorts = concatMapStringsSep ", " (x: toString x) allowedUDPPorts; 73 + in optionalString (allowedUDPPorts != []) '' 74 + udp dport {${udpPorts}} ct state new meter udp-conncount { ip saddr . udp dport ct count over 150 } counter drop 75 + udp dport {${udpPorts}} ct state new meter udp6-conncount { ip6 saddr . udp dport ct count over 150 } counter drop 76 + udp dport {${udpPorts}} ct state new accept 68 77 ''; 69 78 in '' 70 79 chain prerouting { 71 - type nat hook prerouting priority 0; policy accept; 80 + type nat hook prerouting priority dstnat; policy accept; 72 81 ${capturePortsRules} 73 82 } 74 83 75 84 chain postrouting { 76 - type nat hook postrouting priority 0; policy accept; 85 + type nat hook postrouting priority srcnat; policy accept; 77 86 oifname != { ${concatIfnames trustedInterfaces} } meta protocol ip masquerade 78 87 } 79 88 80 89 chain input { 81 - type filter hook input priority 0; 90 + type filter hook input priority 0; policy drop; 82 91 ct state { established, related } accept 83 92 ct state invalid drop 93 + 84 94 iifname { ${concatIfnames trustedInterfaces} } accept 85 - iifname { ${concatIfnames trustedInterfaces} } pkttype { broadcast, multicast } accept 95 + 86 96 tcp flags & (fin|syn|rst|ack) != syn ct state new counter drop 87 97 tcp flags & (fin|syn|rst|psh|ack|urg) == fin|syn|rst|psh|ack|urg counter drop 88 98 tcp flags & (fin|syn|rst|psh|ack|urg) == 0x0 counter drop 99 + 89 100 ip protocol icmp \ 90 - icmp type { destination-unreachable, echo-reply, echo-request, source-quench, time-exceeded } \ 101 + icmp type { destination-unreachable, time-exceeded } \ 91 102 accept 92 - meta l4proto ipv6-icmp accept 93 - ip6 ecn not-ect accept 94 - udp dport dhcpv6-client ct state { new, untracked } accept 95 - udp dport 41641 ct state new accept 103 + 104 + ip protocol icmp \ 105 + icmp type { echo-reply, echo-request } \ 106 + limit rate 5/second burst 10 packets accept 107 + 108 + meta l4proto ipv6-icmp \ 109 + icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem, \ 110 + nd-neighbor-solicit, nd-neighbor-advert, nd-router-solicit, nd-router-advert } \ 111 + accept 112 + 113 + meta l4proto ipv6-icmp \ 114 + icmpv6 type { echo-request, echo-reply } \ 115 + limit rate 5/second burst 10 packets accept 116 + 117 + # Layer 1: Global cap on all new WAN connections (single counter, cheapest check) 118 + ct state new limit rate over 200/second burst 400 packets counter drop 119 + 120 + # Layer 2: Per-source-IP rate limit (hash lookup, bounded by layer 1) 121 + ct state new meter wan-limit { ip saddr limit rate over 30/second burst 60 packets } counter drop 122 + ct state new meter wan-limit6 { ip6 saddr limit rate over 30/second burst 60 packets } counter drop 123 + 124 + # Layer 3: Global TCP SYN limit (caps new TCP within the layer 1 budget) 125 + tcp flags syn ct state new limit rate over 100/second burst 200 packets counter drop 126 + 127 + iifname ${extern.name} udp dport dhcpv6-client ct state new accept 128 + 129 + # Layer 4: Per-source-IP per-port concurrent connection limit (ct count, most expensive) 96 130 ${tcpAccept} 97 131 ${udpAccept} 98 - reject with icmpx type port-unreachable 132 + 133 + # Limit reject responses to reduce scanner feedback; remainder dropped by policy 134 + limit rate 5/second burst 10 packets counter reject with icmpx type port-unreachable 99 135 } 100 136 101 137 chain forward { ··· 118 154 family = "arp"; 119 155 content = '' 120 156 chain input { 121 - type filter hook input priority 0; policy accept; 122 - iifname != { ${concatIfnames trustedInterfaces} } limit rate 1/second burst 2 packets accept 157 + type filter hook input priority 0; policy drop; 158 + iifname { ${concatIfnames trustedInterfaces} } accept 159 + limit rate 1/second burst 2 packets accept 123 160 } 124 161 125 162 chain output { ··· 128 165 ''; 129 166 }; 130 167 131 - tables.tagging = { 168 + tables.tagging = mkIf (intern != null) { 132 169 family = "netdev"; 133 170 content = '' 134 171 chain lan { 135 - type filter hook ingress priority -150; policy accept; 172 + type filter hook ingress device ${intern.name} priority -150; policy accept; 136 173 jump tags 137 174 } 138 175 ··· 148 185 udp dport 41641 ip dscp set cs4 149 186 udp dport {3478-3479, 19302-19309} ip dscp set cs4 150 187 udp sport {3478-3479, 19302-19309} ip dscp set cs4 151 - ip6 nexthdr udp udp dport {3478-3479, 19302-19309} ip6 dscp set cs4 152 - ip6 nexthdr udp udp sport {3478-3479, 19302-19309} ip6 dscp set cs4 188 + meta l4proto udp udp dport {3478-3479, 19302-19309} ip6 dscp set cs4 189 + meta l4proto udp udp sport {3478-3479, 19302-19309} ip6 dscp set cs4 153 190 udp dport {7000-9000, 27000-27200} ip dscp set cs4 154 191 udp sport {7000-9000, 27000-27200} ip dscp set cs4 155 - ip6 nexthdr udp udp dport {7000-9000, 27000-27200} ip6 dscp set cs4 156 - ip6 nexthdr udp udp sport {7000-9000, 27000-27200} ip6 dscp set cs4 192 + meta l4proto udp udp dport {7000-9000, 27000-27200} ip6 dscp set cs4 193 + meta l4proto udp udp sport {7000-9000, 27000-27200} ip6 dscp set cs4 157 194 } 158 195 ''; 159 196 };