test-rules-min.nix (5337B)
1 let 2 drop = expr: "${expr} drop"; 3 accept = expr: "${expr} accept"; 4 mcast-scope = 8; 5 allow-incoming = false; 6 bogons-ip6 = { 7 type = "filter"; 8 family = "ip6"; 9 rules = [ 10 (drop "ip6 saddr ff00::/8") # multicast saddr is illegal 11 12 (drop "ip6 saddr ::/128") # unspecified address 13 (drop "ip6 daddr ::/128") 14 (drop "ip6 saddr 2001:db8::/32") # documentation addresses 15 (drop "ip6 daddr 2001:db8::/32") 16 17 # I think this means "check FIB for (saddr, iif) to see if we 18 # could route a packet to that address using that interface", 19 # and if we can't then it was an inapproppriate source address 20 # for packets received _from_ said interface 21 (drop "fib saddr . iif oif eq 0") 22 23 (drop "icmpv6 type router-renumbering") 24 (drop "icmpv6 type 139") # Node Information Query 25 (drop "icmpv6 type 140") # Node Information Response 26 (drop "icmpv6 type 100") 27 (drop "icmpv6 type 101") 28 (drop "icmpv6 type 200") 29 (drop "icmpv6 type 201") 30 (drop "icmpv6 type 127") 31 (drop "icmpv6 type 255") 32 (drop "icmpv6 type destination-unreachable ct state invalid,untracked") 33 ]; 34 }; 35 forward-ip6 = { 36 type = "filter"; 37 family = "ip6"; 38 policy = "drop"; 39 hook = "forward"; 40 rules = [ 41 "jump bogons-ip6" 42 (drop "ip6 saddr ::1/128") # loopback address [RFC4291] 43 (drop "ip6 daddr ::1/128") 44 (drop "ip6 saddr ::FFFF:0:0/96") # IPv4-mapped addresses 45 (drop "ip6 daddr ::FFFF:0:0/96") 46 (drop "ip6 saddr fe80::/10") # link-local unicast 47 (drop "ip6 daddr fe80::/10") 48 (drop "ip6 saddr fc00::/7") # unique-local addresses 49 (drop "ip6 daddr fc00::/7") 50 (drop "ip6 saddr 2001:10::/28") # ORCHID [RFC4843]. 51 (drop "ip6 daddr 2001:10::/28") 52 53 (drop "ip6 saddr fc00::/7") # unique local source 54 (drop "ip6 daddr fc00::/7") # and/or dst addresses [RFC4193] 55 56 # multicast with wrong scopes 57 (drop 58 # dest addr first byte 0xff, low nibble of second byte <= scope 59 # https://www.mankier.com/8/nft#Payload_Expressions-Raw_Payload_Expression 60 "@nh,192,8 eq 0xff @nh,204,4 le ${toString mcast-scope}" 61 ) 62 63 (accept "oifname \"int\" iifname \"ppp0\" meta l4proto udp ct state established,related") 64 (accept "iifname \"int\" oifname \"ppp0\" meta l4proto udp") 65 66 (accept "meta l4proto icmpv6") 67 (accept "meta l4proto ah") 68 (accept "meta l4proto esp") 69 70 # does this ever get used or does the preceding general udp accept 71 # already grab anything that might get here? 72 (accept "oifname \"ppp0\" udp dport 500") # IKE Protocol [RFC5996]. haha zyxel 73 (accept "ip6 nexthdr hip") 74 75 ## FIXME no support yet for recs 27-30 Mobility Header 76 77 (accept "oifname \"int\" iifname \"ppp0\" meta l4proto tcp ct state established,related") 78 (accept "iifname \"int\" oifname \"ppp0\" meta l4proto tcp") 79 80 (accept "oifname \"int\" iifname \"ppp0\" meta l4proto sctp ct state established,related") 81 (accept "iifname \"int\" oifname \"ppp0\" meta l4proto sctp") 82 83 (accept "oifname \"int\" iifname \"ppp0\" meta l4proto dccp ct state established,related") 84 (accept "iifname \"int\" oifname \"ppp0\" meta l4proto dccp") 85 86 # we can allow all reasonable inbound, or we can use an explicit 87 # allowlist to enumerate the endpoints that are allowed to 88 # accept inbound from the WAN 89 ( 90 if allow-incoming then 91 accept "oifname \"int\" iifname \"ppp0\"" 92 else 93 "oifname \"int\" iifname \"ppp0\" jump incoming-allowed-ip6" 94 ) 95 # allow all outbound and any inbound that's part of a 96 # recognised (outbound-initiated) flow 97 (accept "oifname \"int\" iifname \"ppp0\" ct state established,related") 98 (accept "iifname \"int\" oifname \"ppp0\" ") 99 ]; 100 }; 101 input-ip6 = { 102 type = "filter"; 103 family = "ip6"; 104 policy = "drop"; 105 hook = "input"; 106 rules = [ 107 "jump bogons-ip6" 108 (accept "meta l4proto icmpv6") 109 ( 110 if allow-incoming then 111 accept "oifname \"int\" iifname \"ppp0\"" 112 else 113 "oifname \"int\" iifname \"ppp0\" jump incoming-allowed-ip6" 114 ) 115 (accept "oifname \"int\" iifname \"ppp0\" ct state established,related") 116 (accept "iifname \"int\" oifname \"ppp0\" ") 117 ]; 118 }; 119 120 incoming-allowed-ip6 = { 121 type = "filter"; 122 family = "ip6"; 123 rules = [ 124 "oifname \"int\" ip6 daddr 2001:8b0:de3a:40de::e9d tcp dport 22" 125 ]; 126 }; 127 in 128 { 129 inherit 130 input-ip6 131 forward-ip6 132 bogons-ip6 133 incoming-allowed-ip6 134 ; 135 lan-set-ip = { 136 kind = "set"; 137 family = "ip"; 138 type = "ifname"; 139 elements = [ 140 "eth0" 141 "eth1" 142 ]; 143 144 }; 145 # honours timeout flags gc-interval size policy counter auto-merge 146 lan-set-ip6 = { 147 kind = "set"; 148 family = "ip6"; 149 type = "ifname"; 150 elements = [ 151 "eth0" 152 "eth1" 153 ]; 154 }; 155 156 map-intf-limits-ip6 = { 157 name = "intf-limits"; 158 kind = "map"; 159 family = "ip6"; 160 type = { 161 ifname = "bytes"; 162 }; 163 elements = { 164 # XXX keys need to be generated from interface outputs 165 ppp0 = builtins.floor (70 * 1000 * 1000 * 0.05); # 5% of 70MB fttp connection 166 lan = builtins.floor (1000 * 1000 * 1000 * 0.05); # GB ethernet 167 }; 168 }; 169 170 }