summaryrefslogtreecommitdiffstats
path: root/tests/shell/testcases/nft-f/sample-ruleset
blob: 763e41a1f721472710369452ab2d24f4715e7f02 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
#!/bin/bash

# NFT_TEST_REQUIRES(NFT_TEST_HAVE_chain_binding)

$NFT -f /dev/stdin <<"EOF"
define public_if = eth0
define trusted_if = eth1
define voip_if = eth2.10
define guest_if = eth2.20
define home_if = { $trusted_if, $voip_if, $guest_if }
define home_ipv6_if = { $trusted_if, $voip_if, $guest_if }

define masq_ip = { 192.168.1.0/24, 192.168.2.0/24, 192.168.3.0/24, 192.168.4.0/24 }
define masq_if = $public_if

define host1_ip = 192.168.1.10
define host2_ip = 192.168.2.20
define host3_ip = 192.168.3.30
define host4_ip = 192.168.4.40

define proxy_port = 8443

define private_ip = { 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8 }
define private_ip6 = { fe80::/64, fd00::/8 }
define bogons_ip = { 0.0.0.0/8, 10.0.0.0/8, 100.64.0.0/10, 127.0.0.0/8, 169.254.0.0/16, 172.16.0.0/12, 192.0.0.0/24, 192.0.2.0/24, 192.168.0.0/16, 198.18.0.0/15, 198.51.100.0/24, 203.0.113.0/24, 224.0.0.0/3 }
define bogons_ip6 = { ::/3, 2001:0002::/48, 2001:0003::/32, 2001:10::/28, 2001:20::/28, 2001::/32, 2001:db8::/32, 2002::/16, 3000::/4, 4000::/2, 8000::/1 }

define sip_whitelist_ip6 = { 2001:db8::1/128, 2001:db8::2/128 }
define smtps_whitelist_ip = 10.0.0.1
define protocol_whitelist = { tcp, udp, icmp, ipv6-icmp }

table inet filter {
	map if_input {
		type ifname : verdict;
		elements = { $public_if : jump public_input, $trusted_if : jump home_input, $voip_if : jump home_input, $guest_if : jump home_input }
	}
	map if_forward {
		type ifname : verdict;
		elements = { $public_if : jump public_forward, $trusted_if : jump trusted_forward, $voip_if : jump voip_forward, $guest_if : jump guest_forward }
	}
	map if_output {
		type ifname : verdict;
		elements = { $public_if : jump public_output, $trusted_if : jump home_output, $voip_if : jump home_output, $guest_if : jump home_output }
	}

	set ipv4_blacklist { type ipv4_addr; flags interval; auto-merge; }
	set ipv6_blacklist { type ipv6_addr; flags interval; auto-merge; }
	set limit_src_ip { type ipv4_addr; flags dynamic, timeout; size 1024; }
	set limit_src_ip6 { type ipv6_addr; flags dynamic, timeout; size 1024; }

	chain PREROUTING_RAW {
		type filter hook prerouting priority raw;

		meta l4proto != $protocol_whitelist counter drop
		tcp flags syn jump {
			tcp option maxseg size 1-500 counter drop
			tcp sport 0 counter drop
		}
		rt type 0 counter drop
	}

	chain PREROUTING_MANGLE {
		type filter hook prerouting priority mangle;

		ct state vmap { invalid : jump ct_invalid_pre, untracked : jump ct_untracked_pre, new : jump ct_new_pre, related : jump rpfilter }
	}
	chain ct_invalid_pre {
		counter drop
	}
	chain ct_untracked_pre {
		icmpv6 type { nd-router-solicit, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert, mld-listener-query, mld2-listener-report } return
		counter drop
	}
	chain ct_new_pre {
		jump rpfilter

		tcp flags & (fin|syn|rst|ack) != syn counter drop

		iifname $public_if meta nfproto vmap { ipv4 : jump blacklist_input_ipv4, ipv6 : jump blacklist_input_ipv6 }
	}
	chain rpfilter {
		ip saddr 0.0.0.0 ip daddr 255.255.255.255 udp sport bootpc udp dport bootps return
		ip6 saddr ::/128 ip6 daddr . icmpv6 type { ff02::1:ff00:0/104 . nd-neighbor-solicit, ff02::16 . mld2-listener-report } return

		fib saddr . iif oif eq 0 counter drop
	}
	chain blacklist_input_ipv4{
		ip saddr $bogons_ip counter drop
		ip saddr @ipv4_blacklist counter drop
	}
	chain blacklist_input_ipv6{
		icmpv6 type { nd-router-solicit, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } ip6 saddr fe80::/64 return
		udp sport dhcpv6-server ip6 saddr fe80::/64 return

		ip6 saddr $bogons_ip6 counter drop
		ip6 saddr @ipv6_blacklist counter drop
	}

	chain INPUT {
		type filter hook input priority filter; policy drop;

		iif lo accept

		ct state established,related accept

		iifname vmap @if_input

		log prefix "NFT REJECT IN " flags ether flags ip options limit rate 5/second burst 10 packets reject
	}
	chain public_input {
		icmpv6 type { nd-router-solicit, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } ip6 saddr fe80::/64 ip6 hoplimit 255 accept

		udp sport dhcpv6-server udp dport dhcpv6-client ip6 saddr fe80::/64 accept
		fib daddr type { broadcast, multicast, anycast } counter drop

		counter drop
	}
	chain home_input {
		icmpv6 type { nd-router-solicit, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } ip6 hoplimit 255 accept
		icmpv6 type { mld-listener-query, mld2-listener-report } ip6 hoplimit 1 accept

		udp sport bootpc udp dport bootps accept
		udp sport dhcpv6-client udp dport dhcpv6-server iifname $home_ipv6_if accept

		fib daddr type { broadcast, multicast, anycast } counter drop

		icmp type echo-request accept
		icmpv6 type echo-request accept

		tcp dport ssh iifname $trusted_if accept

		meta l4proto { tcp, udp } th dport domain jump {
			ip6 saddr != $private_ip6 counter reject
			accept
		}

		udp dport ntp accept

		tcp dport $proxy_port accept
	}

	chain FORWARD_MANGLE {
		type filter hook forward priority mangle;

		oifname $public_if jump {
			ct state new meta nfproto vmap { ipv4 : jump blacklist_output_ipv4, ipv6 : jump blacklist_output_ipv6 }
			tcp flags & (syn|rst) == syn tcp option maxseg size set rt mtu
		}
	}
	chain blacklist_output_ipv4 {
		ip daddr $bogons_ip goto log_blacklist
		ip daddr @ipv4_blacklist goto log_blacklist
	}
	chain blacklist_output_ipv6 {
		icmpv6 type . ip6 daddr { nd-router-solicit . ff02::2/128, nd-neighbor-solicit . ff02::1:ff00:0/104, nd-neighbor-advert . fe80::/64, nd-neighbor-advert . ff02::1/128, nd-neighbor-advert . ff02::1:ff00:0/104, mld2-listener-report . ff02::16/128 } return
		udp dport dhcpv6-server ip6 daddr ff02::1:2 return

		ip6 daddr $bogons_ip6 goto log_blacklist
		ip6 daddr @ipv6_blacklist goto log_blacklist
	}
	chain log_blacklist {
		log prefix "NFT BLACKLIST " flags ether flags ip options limit rate 5/minute burst 10 packets drop
		counter drop
	}

	chain FORWARD {
		type filter hook forward priority filter; policy drop;

		ct state established,related accept

		fib daddr type { broadcast, multicast, anycast } counter drop

		iifname vmap @if_forward

		log prefix "NFT REJECT FWD " flags ether flags ip options limit rate 5/second burst 10 packets reject
	}
	chain public_forward {
		udp dport { 5060, 7078-7097 } oifname $voip_if jump {
			ip6 saddr $sip_whitelist_ip6 accept
			meta nfproto ipv6 log prefix "NFT DROP SIP " flags ether flags ip options limit rate 5/second burst 10 packets drop
		}

		counter drop
	}
	chain trusted_forward {
		oifname $public_if accept

		icmp type echo-request accept
		icmpv6 type echo-request accept

		ip daddr { $host3_ip, $host4_ip } tcp dport vmap { ssh : accept, https : accept, http : drop }

		ip daddr $host2_ip jump {
			tcp dport { http, https, printer, ipp, 9100 } accept
			udp dport snmp accept
		}
	}
	chain voip_forward {
		icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem, echo-request } oifname $public_if accept

		ip6 daddr $sip_whitelist_ip6 jump {
			udp dport { 3478, 5060 } accept
			udp sport { 7078-7097 } accept
			tcp dport 5061 accept
		}

		tcp dport 587 ip daddr $smtps_whitelist_ip accept
		tcp dport http oifname $public_if counter reject
	}
	chain guest_forward {
		oifname $public_if accept
	}

	chain OUTPUT {
		type filter hook output priority filter; policy drop;

		oif lo accept

		ct state vmap { established : accept, related : accept, invalid : jump ct_invalid_out, untracked : jump ct_untracked_out }

		oifname vmap @if_output

		log prefix "NFT REJECT OUT " flags ether flags ip options limit rate 5/second burst 10 packets reject
	}
	chain ct_invalid_out {
		counter drop
	}
	chain ct_untracked_out {
		icmpv6 type { nd-router-solicit, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert, mld-listener-query, mld2-listener-report } return
		counter drop
	}
	chain public_output {
		ct state new meta nfproto vmap { ipv4 : jump blacklist_output_ipv4, ipv6 : jump blacklist_output_ipv6 }

		icmp type { destination-unreachable, time-exceeded, parameter-problem, echo-request } accept
		icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem, echo-request } accept
		icmpv6 type { nd-router-solicit, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } ip6 hoplimit 255 accept
		icmpv6 type { mld-listener-query, mld2-listener-report } ip6 hoplimit 1 accept

		udp dport dhcpv6-server ip6 saddr fe80::/64 ip6 daddr ff02::1:2 accept

		udp dport { domain, ntp } accept
		tcp dport { https, 587, domain-s } accept
	}
	chain home_output {
		icmp type { destination-unreachable, time-exceeded, parameter-problem, echo-request } accept
		icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem, echo-request } accept
		icmpv6 type { nd-router-solicit, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } ip6 hoplimit 255 accept
		icmpv6 type { mld-listener-query, mld2-listener-report } ip6 hoplimit 1 accept

		udp sport dhcpv6-server udp dport dhcpv6-client ip6 saddr fe80::/64 oifname $home_ipv6_if accept
		udp sport bootps udp dport bootpc ip saddr $private_ip accept
		tcp dport ssh ip daddr $host1_ip accept
	}

	chain POSTROUTING_SRCNAT {
		type nat hook postrouting priority srcnat;

		meta nfproto ipv4 ip saddr $masq_ip oifname $masq_if masquerade
	}
}
EOF