Personal Nix setup
at main 5.1 kB view raw
1{ config, lib, ... }: 2 3with lib; 4let 5 cfg = config.modules.router; 6 7 intern = cfg.interfaces.internal; 8 trustedInterfaces = config.networking.firewall.trustedInterfaces; 9 internalInterfaces = lists.remove "lo" trustedInterfaces; 10 11 concatIfnames = strings.concatMapStringsSep ", " strings.escapeNixIdentifier; 12 13 capturePortsRules = 14 strings.concatStringsSep "\n" 15 (builtins.map (port: '' 16 iifname { ${concatIfnames internalInterfaces} } meta l4proto { tcp, udp } th dport ${toString port} redirect to ${toString port} 17 '') cfg.nftables.capturePorts); 18 19 blockForwardRules = 20 if intern != null then 21 strings.concatStringsSep "\n" 22 (builtins.map (mac: " iifname ${intern.name} oifname != ${intern.name} ether saddr == ${mac} drop") cfg.nftables.blockForward) 23 else ""; 24in { 25 options.modules.router = { 26 nftables = { 27 enable = mkOption { 28 default = cfg.enable; 29 description = "Whether to enable Router NFTables config"; 30 type = types.bool; 31 }; 32 33 capturePorts = mkOption { 34 default = [ 53 ]; 35 description = "Ports to capture and redirect to router"; 36 type = types.listOf types.int; 37 }; 38 39 blockForward = mkOption { 40 default = []; 41 description = "MAC Addresses of devices to block internet access for"; 42 type = types.listOf types.str; 43 }; 44 }; 45 }; 46 47 config = mkIf cfg.nftables.enable { 48 networking.useNetworkd = mkDefault true; 49 networking.firewall = { 50 enable = mkDefault true; 51 checkReversePath = "loose"; 52 }; 53 54 networking.nftables = { 55 enable = mkForce true; 56 checkRuleset = false; 57 flushRuleset = true; 58 59 tables.filter = { 60 family = "inet"; 61 content = '' 62 chain prerouting { 63 type nat hook prerouting priority 0; policy accept; 64 ${capturePortsRules} 65 } 66 67 chain postrouting { 68 type nat hook postrouting priority 0; policy accept; 69 oifname != { ${concatIfnames trustedInterfaces} } meta protocol ip masquerade 70 } 71 72 chain input { 73 type filter hook input priority 0; 74 ct state { established, related } accept 75 ct state invalid drop 76 iifname { ${concatIfnames trustedInterfaces} } accept 77 iifname { ${concatIfnames trustedInterfaces} } pkttype { broadcast, multicast } accept 78 tcp flags & (fin|syn|rst|ack) != syn ct state new counter drop 79 tcp flags & (fin|syn|rst|psh|ack|urg) == fin|syn|rst|psh|ack|urg counter drop 80 tcp flags & (fin|syn|rst|psh|ack|urg) == 0x0 counter drop 81 ip protocol icmp \ 82 icmp type { destination-unreachable, echo-reply, echo-request, source-quench, time-exceeded } \ 83 accept 84 meta l4proto ipv6-icmp accept 85 ip6 ecn not-ect accept 86 udp dport dhcpv6-client ct state { new, untracked } accept 87 udp dport 41641 ct state new accept 88 reject with icmpx type port-unreachable 89 } 90 91 chain forward { 92 type filter hook forward priority 0; policy drop; 93 ${blockForwardRules} 94 iifname { ${concatIfnames trustedInterfaces} } accept 95 oifname { ${concatIfnames trustedInterfaces} } ct state { established, related } accept 96 ct state invalid drop 97 } 98 99 chain output { 100 type filter hook output priority 0; policy accept; 101 iifname lo accept 102 ct state invalid drop 103 } 104 ''; 105 }; 106 107 tables.arp_filter = { 108 family = "arp"; 109 content = '' 110 chain input { 111 type filter hook input priority 0; policy accept; 112 iifname != { ${concatIfnames trustedInterfaces} } limit rate 1/second burst 2 packets accept 113 } 114 115 chain output { 116 type filter hook output priority 0; policy accept; 117 } 118 ''; 119 }; 120 121 tables.tagging = { 122 family = "netdev"; 123 content = '' 124 chain lan { 125 type filter hook ingress priority -150; policy accept; 126 jump tags 127 } 128 129 chain tags { 130 ip dscp set cs0 131 ip6 dscp set cs0 132 133 udp sport 53 ip dscp set cs5 134 tcp sport 853 ip dscp set cs5 135 udp sport 123 ip dscp set cs5 136 tcp dport {80, 443} ip dscp set cs3 137 138 udp dport 41641 ip dscp set cs4 139 udp dport {3478-3479, 19302-19309} ip dscp set cs4 140 udp sport {3478-3479, 19302-19309} ip dscp set cs4 141 ip6 nexthdr udp udp dport {3478-3479, 19302-19309} ip6 dscp set cs4 142 ip6 nexthdr udp udp sport {3478-3479, 19302-19309} ip6 dscp set cs4 143 udp dport {7000-9000, 27000-27200} ip dscp set cs4 144 udp sport {7000-9000, 27000-27200} ip dscp set cs4 145 ip6 nexthdr udp udp dport {7000-9000, 27000-27200} ip6 dscp set cs4 146 ip6 nexthdr udp udp sport {7000-9000, 27000-27200} ip6 dscp set cs4 147 } 148 ''; 149 }; 150 }; 151 }; 152}