xref: /freebsd/tests/sys/netpfil/pf/pass_block.sh (revision 22cf89c938886d14f5796fc49f9f020c23ea8eaf)
1#
2# SPDX-License-Identifier: BSD-2-Clause
3#
4# Copyright (c) 2018 Kristof Provost <kp@FreeBSD.org>
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
9# 1. Redistributions of source code must retain the above copyright
10#    notice, this list of conditions and the following disclaimer.
11# 2. Redistributions in binary form must reproduce the above copyright
12#    notice, this list of conditions and the following disclaimer in the
13#    documentation and/or other materials provided with the distribution.
14#
15# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25# SUCH DAMAGE.
26
27. $(atf_get_srcdir)/utils.subr
28
29common_dir=$(atf_get_srcdir)/../common
30
31atf_test_case "v4" "cleanup"
32v4_head()
33{
34	atf_set descr 'Basic pass/block test for IPv4'
35	atf_set require.user root
36}
37
38v4_body()
39{
40	pft_init
41
42	epair=$(vnet_mkepair)
43	ifconfig ${epair}a 192.0.2.1/24 up
44
45	# Set up a simple jail with one interface
46	vnet_mkjail alcatraz ${epair}b
47	jexec alcatraz ifconfig ${epair}b 192.0.2.2/24 up
48
49	# Trivial ping to the jail, without pf
50	atf_check -s exit:0 -o ignore ping -c 1 -t 1 192.0.2.2
51
52	# pf without policy will let us ping
53	jexec alcatraz pfctl -e
54	atf_check -s exit:0 -o ignore ping -c 1 -t 1 192.0.2.2
55
56	# Block everything
57	pft_set_rules alcatraz "block in"
58	atf_check -s exit:2 -o ignore ping -c 1 -t 1 192.0.2.2
59
60	# Block everything but ICMP
61	pft_set_rules alcatraz "block in" "pass in proto icmp"
62	atf_check -s exit:0 -o ignore ping -c 1 -t 1 192.0.2.2
63}
64
65v4_cleanup()
66{
67	pft_cleanup
68}
69
70atf_test_case "v6" "cleanup"
71v6_head()
72{
73	atf_set descr 'Basic pass/block test for IPv6'
74	atf_set require.user root
75}
76
77v6_body()
78{
79	pft_init
80
81	epair=$(vnet_mkepair)
82	ifconfig ${epair}a inet6 2001:db8:42::1/64 up no_dad
83
84	# Set up a simple jail with one interface
85	vnet_mkjail alcatraz ${epair}b
86	jexec alcatraz ifconfig ${epair}b inet6 2001:db8:42::2/64 up no_dad
87
88	# Trivial ping to the jail, without pf
89	atf_check -s exit:0 -o ignore ping -6 -c 1 -W 1 2001:db8:42::2
90
91	# pf without policy will let us ping
92	jexec alcatraz pfctl -e
93	atf_check -s exit:0 -o ignore ping -6 -c 1 -W 1 2001:db8:42::2
94
95	# Block everything
96	pft_set_rules alcatraz "block in"
97	atf_check -s exit:2 -o ignore ping -6 -c 1 -W 1 2001:db8:42::2
98
99	# Block everything but ICMP
100	pft_set_rules alcatraz "block in" "pass in proto icmp6"
101	atf_check -s exit:0 -o ignore ping -6 -c 1 -W 1 2001:db8:42::2
102
103	# Allowing ICMPv4 does not allow ICMPv6
104	pft_set_rules alcatraz "block in" "pass in proto icmp"
105	atf_check -s exit:2 -o ignore ping -6 -c 1 -W 1 2001:db8:42::2
106}
107
108v6_cleanup()
109{
110	pft_cleanup
111}
112
113atf_test_case "noalias" "cleanup"
114noalias_head()
115{
116	atf_set descr 'Test the :0 noalias option'
117	atf_set require.user root
118}
119
120noalias_body()
121{
122	pft_init
123
124	epair=$(vnet_mkepair)
125	ifconfig ${epair}a inet6 2001:db8:42::1/64 up no_dad
126
127	vnet_mkjail alcatraz ${epair}b
128	jexec alcatraz ifconfig ${epair}b inet6 2001:db8:42::2/64 up no_dad
129
130	linklocaladdr=$(jexec alcatraz ifconfig ${epair}b inet6 \
131		| grep %${epair}b \
132		| awk '{ print $2; }' \
133		| cut -d % -f 1)
134
135	# Sanity check
136	atf_check -s exit:0 -o ignore ping -6 -c 3 -W 1 2001:db8:42::2
137	atf_check -s exit:0 -o ignore ping -6 -c 3 -W 1 ${linklocaladdr}%${epair}a
138
139	jexec alcatraz pfctl -e
140	pft_set_rules alcatraz "block out inet6 from (${epair}b:0) to any"
141
142	atf_check -s exit:2 -o ignore ping -6 -c 3 -W 1 2001:db8:42::2
143
144	# We should still be able to ping the link-local address
145	atf_check -s exit:0 -o ignore ping -6 -c 3 -W 1 ${linklocaladdr}%${epair}a
146
147	pft_set_rules alcatraz "block out inet6 from (${epair}b) to any"
148
149	# We cannot ping to the link-local address
150	atf_check -s exit:2 -o ignore ping -6 -c 3 -W 1 ${linklocaladdr}%${epair}a
151}
152
153noalias_cleanup()
154{
155	pft_cleanup
156}
157
158atf_test_case "nested_inline" "cleanup"
159nested_inline_head()
160{
161	atf_set descr "Test nested inline anchors, PR196314"
162	atf_set require.user root
163}
164
165nested_inline_body()
166{
167	pft_init
168
169	epair=$(vnet_mkepair)
170	ifconfig ${epair}a inet 192.0.2.1/24 up
171
172	vnet_mkjail alcatraz ${epair}b
173	jexec alcatraz ifconfig ${epair}b 192.0.2.2/24 up
174
175	jexec alcatraz pfctl -e
176	pft_set_rules alcatraz \
177		"block in" \
178		"anchor \"an1\" {" \
179			"pass in quick proto tcp to port time" \
180			"anchor \"an2\" {" \
181				"pass in quick proto icmp" \
182			"}" \
183		"}"
184
185	atf_check -s exit:0 -o ignore ping -c 1 -t 1 192.0.2.2
186}
187
188nested_inline_cleanup()
189{
190	pft_cleanup
191}
192
193atf_test_case "urpf" "cleanup"
194urpf_head()
195{
196	atf_set descr "Test unicast reverse path forwarding check"
197	atf_set require.user root
198	atf_set require.progs scapy
199}
200
201urpf_body()
202{
203	pft_init
204
205	epair_one=$(vnet_mkepair)
206	epair_two=$(vnet_mkepair)
207
208	vnet_mkjail alcatraz ${epair_one}b ${epair_two}b
209
210	ifconfig ${epair_one}a 192.0.2.2/24 up
211	ifconfig ${epair_two}a 198.51.100.2/24 up
212
213	jexec alcatraz ifconfig ${epair_one}b 192.0.2.1/24 up
214	jexec alcatraz ifconfig ${epair_two}b 198.51.100.1/24 up
215	jexec alcatraz sysctl net.inet.ip.forwarding=1
216
217	# Sanity checks
218	atf_check -s exit:0 -o ignore ping -c 1 -t 1 192.0.2.1
219	atf_check -s exit:0 -o ignore ping -c 1 -t 1 198.51.100.1
220	atf_check -s exit:0 ${common_dir}/pft_ping.py \
221		--sendif ${epair_one}a \
222		--to 192.0.2.1 \
223		--fromaddr 198.51.100.2 \
224		--replyif ${epair_two}a
225	atf_check -s exit:0 ${common_dir}/pft_ping.py \
226		--sendif ${epair_two}a \
227		--to 198.51.100.1 \
228		--fromaddr 192.0.2.2 \
229		--replyif ${epair_one}a
230
231	pft_set_rules alcatraz \
232		"block quick from urpf-failed" \
233		"set skip on lo"
234	jexec alcatraz pfctl -e
235
236	# Correct source still works
237	atf_check -s exit:0 -o ignore ping -c 1 -t 1 192.0.2.1
238	atf_check -s exit:0 -o ignore ping -c 1 -t 1 198.51.100.1
239
240	# Unexpected source interface is blocked
241	atf_check -s exit:1 ${common_dir}/pft_ping.py \
242		--sendif ${epair_one}a \
243		--to 192.0.2.1 \
244		--fromaddr 198.51.100.2 \
245		--replyif ${epair_two}a
246	atf_check -s exit:1 ${common_dir}/pft_ping.py \
247		--sendif ${epair_two}a \
248		--to 198.51.100.1 \
249		--fromaddr 192.0.2.2 \
250		--replyif ${epair_one}a
251}
252
253urpf_cleanup()
254{
255	pft_cleanup
256}
257
258atf_init_test_cases()
259{
260	atf_add_test_case "v4"
261	atf_add_test_case "v6"
262	atf_add_test_case "noalias"
263	atf_add_test_case "nested_inline"
264	atf_add_test_case "urpf"
265}
266