]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tests/sys/netpfil/pf/killstate.sh
pf tests: Test killing states by gateway
[FreeBSD/FreeBSD.git] / tests / sys / netpfil / pf / killstate.sh
1 # $FreeBSD$
2 #
3 # SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 #
5 # Copyright (c) 2021 Rubicon Communications, LLC (Netgate)
6 #
7 # Redistribution and use in source and binary forms, with or without
8 # modification, are permitted provided that the following conditions
9 # are met:
10 # 1. Redistributions of source code must retain the above copyright
11 #    notice, this list of conditions and the following disclaimer.
12 # 2. Redistributions in binary form must reproduce the above copyright
13 #    notice, this list of conditions and the following disclaimer in the
14 #    documentation and/or other materials provided with the distribution.
15 #
16 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 # ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 # SUCH DAMAGE.
27
28 . $(atf_get_srcdir)/utils.subr
29
30 common_dir=$(atf_get_srcdir)/../common
31
32 atf_test_case "v4" "cleanup"
33 v4_head()
34 {
35         atf_set descr 'Test killing states by IPv4 address'
36         atf_set require.user root
37         atf_set require.progs scapy
38 }
39
40 v4_body()
41 {
42         pft_init
43
44         epair=$(vnet_mkepair)
45         ifconfig ${epair}a 192.0.2.1/24 up
46
47         vnet_mkjail alcatraz ${epair}b
48         jexec alcatraz ifconfig ${epair}b 192.0.2.2/24 up
49         jexec alcatraz pfctl -e
50
51         pft_set_rules alcatraz "block all" \
52                 "pass in proto icmp"
53
54         # Sanity check & establish state
55         # Note: use pft_ping so we always use the same ID, so pf considers all
56         # echo requests part of the same flow.
57         atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \
58                 --sendif ${epair}a \
59                 --to 192.0.2.2 \
60                 --replyif ${epair}a
61
62         # Change rules to now deny the ICMP traffic
63         pft_set_rules noflush alcatraz "block all"
64
65         # Established state means we can still ping alcatraz
66         atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \
67                 --sendif ${epair}a \
68                 --to 192.0.2.2 \
69                 --replyif ${epair}a
70
71         # Killing with the wrong IP doesn't affect our state
72         jexec alcatraz pfctl -k 192.0.2.3
73
74         # So we can still ping
75         atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \
76                 --sendif ${epair}a \
77                 --to 192.0.2.2 \
78                 --replyif ${epair}a
79
80         # Killing with one correct address and one incorrect doesn't kill the state
81         jexec alcatraz pfctl -k 192.0.2.1 -k 192.0.2.3
82
83         # So we can still ping
84         atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \
85                 --sendif ${epair}a \
86                 --to 192.0.2.2 \
87                 --replyif ${epair}a
88
89         # Killing with correct address does remove the state
90         jexec alcatraz pfctl -k 192.0.2.1
91
92         # Now the ping fails
93         atf_check -s exit:1 -o ignore ${common_dir}/pft_ping.py \
94                 --sendif ${epair}a \
95                 --to 192.0.2.2 \
96                 --replyif ${epair}a
97 }
98
99 v4_cleanup()
100 {
101         pft_cleanup
102 }
103
104 atf_test_case "label" "cleanup"
105 label_head()
106 {
107         atf_set descr 'Test killing states by label'
108         atf_set require.user root
109         atf_set require.progs scapy
110 }
111
112 label_body()
113 {
114         pft_init
115
116         epair=$(vnet_mkepair)
117         ifconfig ${epair}a 192.0.2.1/24 up
118
119         vnet_mkjail alcatraz ${epair}b
120         jexec alcatraz ifconfig ${epair}b 192.0.2.2/24 up
121         jexec alcatraz pfctl -e
122
123         pft_set_rules alcatraz "block all" \
124                 "pass in proto tcp label bar" \
125                 "pass in proto icmp label foo"
126
127         # Sanity check & establish state
128         # Note: use pft_ping so we always use the same ID, so pf considers all
129         # echo requests part of the same flow.
130         atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \
131                 --sendif ${epair}a \
132                 --to 192.0.2.2 \
133                 --replyif ${epair}a
134
135         # Change rules to now deny the ICMP traffic
136         pft_set_rules noflush alcatraz "block all"
137
138         # Established state means we can still ping alcatraz
139         atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \
140                 --sendif ${epair}a \
141                 --to 192.0.2.2 \
142                 --replyif ${epair}a
143
144         # Killing a label on a different rules keeps the state
145         jexec alcatraz pfctl -k label -k bar
146         atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \
147                 --sendif ${epair}a \
148                 --to 192.0.2.2 \
149                 --replyif ${epair}a
150
151         # Killing a non-existing label keeps the state
152         jexec alcatraz pfctl -k label -k baz
153         atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \
154                 --sendif ${epair}a \
155                 --to 192.0.2.2 \
156                 --replyif ${epair}a
157
158         # Killing the correct label kills the state
159         jexec alcatraz pfctl -k label -k foo
160         atf_check -s exit:1 -o ignore ${common_dir}/pft_ping.py \
161                 --sendif ${epair}a \
162                 --to 192.0.2.2 \
163                 --replyif ${epair}a
164 }
165
166 label_cleanup()
167 {
168         pft_cleanup
169 }
170
171 atf_test_case "multilabel" "cleanup"
172 multilabel_head()
173 {
174         atf_set descr 'Test killing states with multiple labels by label'
175         atf_set require.user root
176         atf_set require.progs scapy
177 }
178
179 multilabel_body()
180 {
181         pft_init
182
183         epair=$(vnet_mkepair)
184         ifconfig ${epair}a 192.0.2.1/24 up
185
186         vnet_mkjail alcatraz ${epair}b
187         jexec alcatraz ifconfig ${epair}b 192.0.2.2/24 up
188         jexec alcatraz pfctl -e
189
190         pft_set_rules alcatraz "block all" \
191                 "pass in proto icmp label foo label bar"
192
193         # Sanity check & establish state
194         # Note: use pft_ping so we always use the same ID, so pf considers all
195         # echo requests part of the same flow.
196         atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \
197                 --sendif ${epair}a \
198                 --to 192.0.2.2 \
199                 --replyif ${epair}a
200
201         # Change rules to now deny the ICMP traffic
202         pft_set_rules noflush alcatraz "block all"
203
204         # Established state means we can still ping alcatraz
205         atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \
206                 --sendif ${epair}a \
207                 --to 192.0.2.2 \
208                 --replyif ${epair}a
209
210         # Killing a label on a different rules keeps the state
211         jexec alcatraz pfctl -k label -k baz
212         atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \
213                 --sendif ${epair}a \
214                 --to 192.0.2.2 \
215                 --replyif ${epair}a
216
217         # Killing the state with the last label works
218         jexec alcatraz pfctl -k label -k bar
219         atf_check -s exit:1 -o ignore ${common_dir}/pft_ping.py \
220                 --sendif ${epair}a \
221                 --to 192.0.2.2 \
222                 --replyif ${epair}a
223
224         pft_set_rules alcatraz "block all" \
225                 "pass in proto icmp label foo label bar"
226
227         # Reestablish state
228         atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \
229                 --sendif ${epair}a \
230                 --to 192.0.2.2 \
231                 --replyif ${epair}a
232
233         # Change rules to now deny the ICMP traffic
234         pft_set_rules noflush alcatraz "block all"
235
236         # Killing with the first label works too
237         jexec alcatraz pfctl -k label -k foo
238         atf_check -s exit:1 -o ignore ${common_dir}/pft_ping.py \
239                 --sendif ${epair}a \
240                 --to 192.0.2.2 \
241                 --replyif ${epair}a
242 }
243
244 multilabel_cleanup()
245 {
246         pft_cleanup
247 }
248
249 atf_test_case "gateway" "cleanup"
250 gateway_head()
251 {
252         atf_set descr 'Test killing states by route-to/reply-to address'
253         atf_set require.user root
254         atf_set require.progs scapy
255 }
256
257 gateway_body()
258 {
259         pft_init
260
261         epair=$(vnet_mkepair)
262         ifconfig ${epair}a 192.0.2.1/24 up
263
264         vnet_mkjail alcatraz ${epair}b
265         jexec alcatraz ifconfig ${epair}b 192.0.2.2/24 up
266         jexec alcatraz pfctl -e
267
268         pft_set_rules alcatraz "block all" \
269                 "pass in reply-to (${epair}b 192.0.2.1) proto icmp"
270
271         # Sanity check & establish state
272         # Note: use pft_ping so we always use the same ID, so pf considers all
273         # echo requests part of the same flow.
274         atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \
275                 --sendif ${epair}a \
276                 --to 192.0.2.2 \
277                 --replyif ${epair}a
278
279         # Change rules to now deny the ICMP traffic
280         pft_set_rules noflush alcatraz "block all"
281
282         # Established state means we can still ping alcatraz
283         atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \
284                 --sendif ${epair}a \
285                 --to 192.0.2.2 \
286                 --replyif ${epair}a
287
288         # Killing with a different gateway does not affect our state
289         jexec alcatraz pfctl -k gateway -k 192.0.2.2
290         atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \
291                 --sendif ${epair}a \
292                 --to 192.0.2.2 \
293                 --replyif ${epair}a
294
295         # Killing states with the relevant gateway does terminate our state
296         jexec alcatraz pfctl -k gateway -k 192.0.2.1
297         atf_check -s exit:1 -o ignore ${common_dir}/pft_ping.py \
298                 --sendif ${epair}a \
299                 --to 192.0.2.2 \
300                 --replyif ${epair}a
301 }
302
303 gateway_cleanup()
304 {
305         pft_cleanup
306 }
307
308 atf_init_test_cases()
309 {
310         atf_add_test_case "v4"
311         atf_add_test_case "label"
312         atf_add_test_case "multilabel"
313         atf_add_test_case "gateway"
314 }