xref: /freebsd/tests/sys/netpfil/pf/pass_block.sh (revision 4d846d26)
1# $FreeBSD$
2#
3# SPDX-License-Identifier: BSD-2-Clause
4#
5# Copyright (c) 2018 Kristof Provost <kp@FreeBSD.org>
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
30common_dir=$(atf_get_srcdir)/../common
31
32atf_test_case "v4" "cleanup"
33v4_head()
34{
35	atf_set descr 'Basic pass/block test for IPv4'
36	atf_set require.user root
37}
38
39v4_body()
40{
41	pft_init
42
43	epair=$(vnet_mkepair)
44	ifconfig ${epair}a 192.0.2.1/24 up
45
46	# Set up a simple jail with one interface
47	vnet_mkjail alcatraz ${epair}b
48	jexec alcatraz ifconfig ${epair}b 192.0.2.2/24 up
49
50	# Trivial ping to the jail, without pf
51	atf_check -s exit:0 -o ignore ping -c 1 -t 1 192.0.2.2
52
53	# pf without policy will let us ping
54	jexec alcatraz pfctl -e
55	atf_check -s exit:0 -o ignore ping -c 1 -t 1 192.0.2.2
56
57	# Block everything
58	pft_set_rules alcatraz "block in"
59	atf_check -s exit:2 -o ignore ping -c 1 -t 1 192.0.2.2
60
61	# Block everything but ICMP
62	pft_set_rules alcatraz "block in" "pass in proto icmp"
63	atf_check -s exit:0 -o ignore ping -c 1 -t 1 192.0.2.2
64}
65
66v4_cleanup()
67{
68	pft_cleanup
69}
70
71atf_test_case "v6" "cleanup"
72v6_head()
73{
74	atf_set descr 'Basic pass/block test for IPv6'
75	atf_set require.user root
76}
77
78v6_body()
79{
80	pft_init
81
82	epair=$(vnet_mkepair)
83	ifconfig ${epair}a inet6 2001:db8:42::1/64 up no_dad
84
85	# Set up a simple jail with one interface
86	vnet_mkjail alcatraz ${epair}b
87	jexec alcatraz ifconfig ${epair}b inet6 2001:db8:42::2/64 up no_dad
88
89	# Trivial ping to the jail, without pf
90	atf_check -s exit:0 -o ignore ping -6 -c 1 -W 1 2001:db8:42::2
91
92	# pf without policy will let us ping
93	jexec alcatraz pfctl -e
94	atf_check -s exit:0 -o ignore ping -6 -c 1 -W 1 2001:db8:42::2
95
96	# Block everything
97	pft_set_rules alcatraz "block in"
98	atf_check -s exit:2 -o ignore ping -6 -c 1 -W 1 2001:db8:42::2
99
100	# Block everything but ICMP
101	pft_set_rules alcatraz "block in" "pass in proto icmp6"
102	atf_check -s exit:0 -o ignore ping -6 -c 1 -W 1 2001:db8:42::2
103
104	# Allowing ICMPv4 does not allow ICMPv6
105	pft_set_rules alcatraz "block in" "pass in proto icmp"
106	atf_check -s exit:2 -o ignore ping -6 -c 1 -W 1 2001:db8:42::2
107}
108
109v6_cleanup()
110{
111	pft_cleanup
112}
113
114atf_test_case "noalias" "cleanup"
115noalias_head()
116{
117	atf_set descr 'Test the :0 noalias option'
118	atf_set require.user root
119}
120
121noalias_body()
122{
123	pft_init
124
125	epair=$(vnet_mkepair)
126	ifconfig ${epair}a inet6 2001:db8:42::1/64 up no_dad
127
128	vnet_mkjail alcatraz ${epair}b
129	jexec alcatraz ifconfig ${epair}b inet6 2001:db8:42::2/64 up no_dad
130
131	linklocaladdr=$(jexec alcatraz ifconfig ${epair}b inet6 \
132		| grep %${epair}b \
133		| awk '{ print $2; }' \
134		| cut -d % -f 1)
135
136	# Sanity check
137	atf_check -s exit:0 -o ignore ping -6 -c 3 -W 1 2001:db8:42::2
138	atf_check -s exit:0 -o ignore ping -6 -c 3 -W 1 ${linklocaladdr}%${epair}a
139
140	jexec alcatraz pfctl -e
141	pft_set_rules alcatraz "block out inet6 from (${epair}b:0) to any"
142
143	atf_check -s exit:2 -o ignore ping -6 -c 3 -W 1 2001:db8:42::2
144
145	# We should still be able to ping the link-local address
146	atf_check -s exit:0 -o ignore ping -6 -c 3 -W 1 ${linklocaladdr}%${epair}a
147
148	pft_set_rules alcatraz "block out inet6 from (${epair}b) to any"
149
150	# We cannot ping to the link-local address
151	atf_check -s exit:2 -o ignore ping -6 -c 3 -W 1 ${linklocaladdr}%${epair}a
152}
153
154noalias_cleanup()
155{
156	pft_cleanup
157}
158
159atf_test_case "nested_inline" "cleanup"
160nested_inline_head()
161{
162	atf_set descr "Test nested inline anchors, PR196314"
163	atf_set require.user root
164}
165
166nested_inline_body()
167{
168	pft_init
169
170	epair=$(vnet_mkepair)
171	ifconfig ${epair}a inet 192.0.2.1/24 up
172
173	vnet_mkjail alcatraz ${epair}b
174	jexec alcatraz ifconfig ${epair}b 192.0.2.2/24 up
175
176	jexec alcatraz pfctl -e
177	pft_set_rules alcatraz \
178		"block in" \
179		"anchor \"an1\" {" \
180			"pass in quick proto tcp to port time" \
181			"anchor \"an2\" {" \
182				"pass in quick proto icmp" \
183			"}" \
184		"}"
185
186	atf_check -s exit:0 -o ignore ping -c 1 -t 1 192.0.2.2
187}
188
189nested_inline_cleanup()
190{
191	pft_cleanup
192}
193
194atf_test_case "urpf" "cleanup"
195urpf_head()
196{
197	atf_set descr "Test unicast reverse path forwarding check"
198	atf_set require.user root
199	atf_set require.progs scapy
200}
201
202urpf_body()
203{
204	pft_init
205
206	epair_one=$(vnet_mkepair)
207	epair_two=$(vnet_mkepair)
208
209	vnet_mkjail alcatraz ${epair_one}b ${epair_two}b
210
211	ifconfig ${epair_one}a 192.0.2.2/24 up
212	ifconfig ${epair_two}a 198.51.100.2/24 up
213
214	jexec alcatraz ifconfig ${epair_one}b 192.0.2.1/24 up
215	jexec alcatraz ifconfig ${epair_two}b 198.51.100.1/24 up
216	jexec alcatraz sysctl net.inet.ip.forwarding=1
217
218	# Sanity checks
219	atf_check -s exit:0 -o ignore ping -c 1 -t 1 192.0.2.1
220	atf_check -s exit:0 -o ignore ping -c 1 -t 1 198.51.100.1
221	atf_check -s exit:0 ${common_dir}/pft_ping.py \
222		--sendif ${epair_one}a \
223		--to 192.0.2.1 \
224		--fromaddr 198.51.100.2 \
225		--replyif ${epair_two}a
226	atf_check -s exit:0 ${common_dir}/pft_ping.py \
227		--sendif ${epair_two}a \
228		--to 198.51.100.1 \
229		--fromaddr 192.0.2.2 \
230		--replyif ${epair_one}a
231
232	pft_set_rules alcatraz \
233		"block quick from urpf-failed"
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