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