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