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 "enable_disable" "cleanup" 32enable_disable_head() 33{ 34 atf_set descr 'Test enable/disable' 35 atf_set require.user root 36} 37 38enable_disable_body() 39{ 40 pft_init 41 42 j="pass_block:enable_disable" 43 44 vnet_mkjail ${j} 45 46 # Disable when disabled fails 47 atf_check -s exit:1 -e ignore \ 48 jexec ${j} pfctl -d 49 50 # Enable succeeds 51 atf_check -s exit:0 -e ignore \ 52 jexec ${j} pfctl -e 53 54 # Enable when enabled fails 55 atf_check -s exit:1 -e ignore \ 56 jexec ${j} pfctl -e 57 58 # Disable succeeds 59 atf_check -s exit:0 -e ignore \ 60 jexec ${j} pfctl -d 61} 62 63enable_disable_cleanup() 64{ 65 pft_cleanup 66} 67 68atf_test_case "v4" "cleanup" 69v4_head() 70{ 71 atf_set descr 'Basic pass/block test for IPv4' 72 atf_set require.user root 73} 74 75v4_body() 76{ 77 pft_init 78 79 epair=$(vnet_mkepair) 80 ifconfig ${epair}a 192.0.2.1/24 up 81 82 # Set up a simple jail with one interface 83 vnet_mkjail alcatraz ${epair}b 84 jexec alcatraz ifconfig ${epair}b 192.0.2.2/24 up 85 86 # Trivial ping to the jail, without pf 87 atf_check -s exit:0 -o ignore ping -c 1 -t 1 192.0.2.2 88 89 # pf without policy will let us ping 90 jexec alcatraz pfctl -e 91 atf_check -s exit:0 -o ignore ping -c 1 -t 1 192.0.2.2 92 93 # Block everything 94 pft_set_rules alcatraz "block in" 95 atf_check -s exit:2 -o ignore ping -c 1 -t 1 192.0.2.2 96 97 # Block everything but ICMP 98 pft_set_rules alcatraz "block in" "pass in proto icmp" 99 atf_check -s exit:0 -o ignore ping -c 1 -t 1 192.0.2.2 100} 101 102v4_cleanup() 103{ 104 pft_cleanup 105} 106 107atf_test_case "v6" "cleanup" 108v6_head() 109{ 110 atf_set descr 'Basic pass/block test for IPv6' 111 atf_set require.user root 112} 113 114v6_body() 115{ 116 pft_init 117 118 epair=$(vnet_mkepair) 119 ifconfig ${epair}a inet6 2001:db8:42::1/64 up no_dad 120 121 # Set up a simple jail with one interface 122 vnet_mkjail alcatraz ${epair}b 123 jexec alcatraz ifconfig ${epair}b inet6 2001:db8:42::2/64 up no_dad 124 125 # Trivial ping to the jail, without pf 126 atf_check -s exit:0 -o ignore ping -6 -c 1 -W 1 2001:db8:42::2 127 128 # pf without policy will let us ping 129 jexec alcatraz pfctl -e 130 atf_check -s exit:0 -o ignore ping -6 -c 1 -W 1 2001:db8:42::2 131 132 # Block everything 133 pft_set_rules alcatraz "block in" 134 atf_check -s exit:2 -o ignore ping -6 -c 1 -W 1 2001:db8:42::2 135 136 # Block everything but ICMP 137 pft_set_rules alcatraz "block in" "pass in proto icmp6" 138 atf_check -s exit:0 -o ignore ping -6 -c 1 -W 1 2001:db8:42::2 139 140 # Allowing ICMPv4 does not allow ICMPv6 141 pft_set_rules alcatraz "block in" "pass in proto icmp" 142 atf_check -s exit:2 -o ignore ping -6 -c 1 -W 1 2001:db8:42::2 143} 144 145v6_cleanup() 146{ 147 pft_cleanup 148} 149 150atf_test_case "noalias" "cleanup" 151noalias_head() 152{ 153 atf_set descr 'Test the :0 noalias option' 154 atf_set require.user root 155} 156 157noalias_body() 158{ 159 pft_init 160 161 epair=$(vnet_mkepair) 162 ifconfig ${epair}a inet6 2001:db8:42::1/64 up no_dad 163 164 vnet_mkjail alcatraz ${epair}b 165 jexec alcatraz ifconfig ${epair}b inet6 2001:db8:42::2/64 up no_dad 166 167 linklocaladdr=$(jexec alcatraz ifconfig ${epair}b inet6 \ 168 | grep %${epair}b \ 169 | awk '{ print $2; }' \ 170 | cut -d % -f 1) 171 172 # Sanity check 173 atf_check -s exit:0 -o ignore ping -6 -c 3 -W 1 2001:db8:42::2 174 atf_check -s exit:0 -o ignore ping -6 -c 3 -W 1 ${linklocaladdr}%${epair}a 175 176 jexec alcatraz pfctl -e 177 pft_set_rules alcatraz "block out inet6 from (${epair}b:0) to any" 178 179 atf_check -s exit:2 -o ignore ping -6 -c 3 -W 1 2001:db8:42::2 180 181 # We should still be able to ping the link-local address 182 atf_check -s exit:0 -o ignore ping -6 -c 3 -W 1 ${linklocaladdr}%${epair}a 183 184 pft_set_rules alcatraz "block out inet6 from (${epair}b) to any" 185 186 # We cannot ping to the link-local address 187 atf_check -s exit:2 -o ignore ping -6 -c 3 -W 1 ${linklocaladdr}%${epair}a 188} 189 190noalias_cleanup() 191{ 192 pft_cleanup 193} 194 195atf_test_case "nested_inline" "cleanup" 196nested_inline_head() 197{ 198 atf_set descr "Test nested inline anchors, PR196314" 199 atf_set require.user root 200} 201 202nested_inline_body() 203{ 204 pft_init 205 206 epair=$(vnet_mkepair) 207 ifconfig ${epair}a inet 192.0.2.1/24 up 208 209 vnet_mkjail alcatraz ${epair}b 210 jexec alcatraz ifconfig ${epair}b 192.0.2.2/24 up 211 212 jexec alcatraz pfctl -e 213 pft_set_rules alcatraz \ 214 "block in" \ 215 "anchor \"an1\" {" \ 216 "pass in quick proto tcp to port time" \ 217 "anchor \"an2\" {" \ 218 "pass in quick proto icmp" \ 219 "}" \ 220 "}" 221 222 atf_check -s exit:0 -o ignore ping -c 1 -t 1 192.0.2.2 223} 224 225nested_inline_cleanup() 226{ 227 pft_cleanup 228} 229 230atf_test_case "urpf" "cleanup" 231urpf_head() 232{ 233 atf_set descr "Test unicast reverse path forwarding check" 234 atf_set require.user root 235 atf_set require.progs scapy 236} 237 238urpf_body() 239{ 240 pft_init 241 242 epair_one=$(vnet_mkepair) 243 epair_two=$(vnet_mkepair) 244 245 vnet_mkjail alcatraz ${epair_one}b ${epair_two}b 246 247 ifconfig ${epair_one}a 192.0.2.2/24 up 248 ifconfig ${epair_two}a 198.51.100.2/24 up 249 250 jexec alcatraz ifconfig ${epair_one}b 192.0.2.1/24 up 251 jexec alcatraz ifconfig ${epair_two}b 198.51.100.1/24 up 252 jexec alcatraz sysctl net.inet.ip.forwarding=1 253 254 # Sanity checks 255 atf_check -s exit:0 -o ignore ping -c 1 -t 1 192.0.2.1 256 atf_check -s exit:0 -o ignore ping -c 1 -t 1 198.51.100.1 257 atf_check -s exit:0 ${common_dir}/pft_ping.py \ 258 --sendif ${epair_one}a \ 259 --to 192.0.2.1 \ 260 --fromaddr 198.51.100.2 \ 261 --replyif ${epair_two}a 262 atf_check -s exit:0 ${common_dir}/pft_ping.py \ 263 --sendif ${epair_two}a \ 264 --to 198.51.100.1 \ 265 --fromaddr 192.0.2.2 \ 266 --replyif ${epair_one}a 267 268 pft_set_rules alcatraz \ 269 "block quick from urpf-failed" \ 270 "set skip on lo" 271 jexec alcatraz pfctl -e 272 273 # Correct source still works 274 atf_check -s exit:0 -o ignore ping -c 1 -t 1 192.0.2.1 275 atf_check -s exit:0 -o ignore ping -c 1 -t 1 198.51.100.1 276 277 # Unexpected source interface is blocked 278 atf_check -s exit:1 ${common_dir}/pft_ping.py \ 279 --sendif ${epair_one}a \ 280 --to 192.0.2.1 \ 281 --fromaddr 198.51.100.2 \ 282 --replyif ${epair_two}a 283 atf_check -s exit:1 ${common_dir}/pft_ping.py \ 284 --sendif ${epair_two}a \ 285 --to 198.51.100.1 \ 286 --fromaddr 192.0.2.2 \ 287 --replyif ${epair_one}a 288} 289 290urpf_cleanup() 291{ 292 pft_cleanup 293} 294 295atf_test_case "received_on" "cleanup" 296received_on_head() 297{ 298 atf_set descr 'Test received-on filtering' 299 atf_set require.user root 300} 301 302received_on_body() 303{ 304 pft_init 305 306 epair_one=$(vnet_mkepair) 307 epair_two=$(vnet_mkepair) 308 epair_route=$(vnet_mkepair) 309 310 vnet_mkjail alcatraz ${epair_one}b ${epair_two}b ${epair_route}a 311 vnet_mkjail srv ${epair_route}b 312 313 ifconfig ${epair_one}a 192.0.2.2/24 up 314 ifconfig ${epair_two}a 198.51.100.2/24 up 315 route add 203.0.113.2 192.0.2.1 316 route add 203.0.113.3 198.51.100.1 317 318 jexec alcatraz ifconfig ${epair_one}b 192.0.2.1/24 up 319 jexec alcatraz ifconfig ${epair_two}b 198.51.100.1/24 up 320 jexec alcatraz ifconfig ${epair_route}a 203.0.113.1/24 up 321 jexec alcatraz sysctl net.inet.ip.forwarding=1 322 323 jexec srv ifconfig ${epair_route}b 203.0.113.2/24 up 324 jexec srv ifconfig ${epair_route}b inet alias 203.0.113.3/24 up 325 jexec srv route add default 203.0.113.1 326 327 # Sanity checks 328 atf_check -s exit:0 -o ignore \ 329 ping -c 1 192.0.2.1 330 atf_check -s exit:0 -o ignore \ 331 ping -c 1 198.51.100.1 332 atf_check -s exit:0 -o ignore \ 333 ping -c 1 203.0.113.2 334 atf_check -s exit:0 -o ignore \ 335 ping -c 1 203.0.113.3 336 337 jexec alcatraz pfctl -e 338 pft_set_rules alcatraz \ 339 "block in" \ 340 "pass received-on ${epair_one}b" 341 342 atf_check -s exit:0 -o ignore \ 343 ping -c 1 192.0.2.1 344 atf_check -s exit:2 -o ignore \ 345 ping -c 1 198.51.100.1 346 347 # And ensure we can check the received-on interface after routing 348 atf_check -s exit:0 -o ignore \ 349 ping -c 1 203.0.113.2 350 atf_check -s exit:2 -o ignore \ 351 ping -c 1 203.0.113.3 352 353 # Now try this with a group instead 354 jexec alcatraz ifconfig ${epair_one}b group test 355 pft_set_rules alcatraz \ 356 "block in" \ 357 "pass received-on test" 358 359 atf_check -s exit:0 -o ignore \ 360 ping -c 1 192.0.2.1 361 atf_check -s exit:2 -o ignore \ 362 ping -c 1 198.51.100.1 363 364 # And ensure we can check the received-on interface after routing 365 atf_check -s exit:0 -o ignore \ 366 ping -c 1 203.0.113.2 367 atf_check -s exit:2 -o ignore \ 368 ping -c 1 203.0.113.3 369} 370 371received_on_cleanup() 372{ 373 pft_cleanup 374} 375 376atf_test_case "optimize_any" "cleanup" 377optimize_any_head() 378{ 379 atf_set descr 'Test known optimizer bug' 380 atf_set require.user root 381} 382 383optimize_any_body() 384{ 385 pft_init 386 387 epair=$(vnet_mkepair) 388 389 vnet_mkjail alcatraz ${epair}a 390 391 ifconfig ${epair}b 192.0.2.2/24 up 392 393 jexec alcatraz ifconfig ${epair}a 192.0.2.1/24 up 394 395 # Sanity check 396 atf_check -s exit:0 -o ignore ping -c 1 -t 1 192.0.2.1 397 398 jexec alcatraz pfctl -e 399 pft_set_rules alcatraz \ 400 "block" \ 401 "pass in inet from { any, 192.0.2.3 }" 402 403 atf_check -s exit:0 -o ignore ping -c 1 -t 1 192.0.2.1 404} 405 406optimize_any_cleanup() 407{ 408 pft_cleanup 409} 410 411atf_init_test_cases() 412{ 413 atf_add_test_case "enable_disable" 414 atf_add_test_case "v4" 415 atf_add_test_case "v6" 416 atf_add_test_case "noalias" 417 atf_add_test_case "nested_inline" 418 atf_add_test_case "urpf" 419 atf_add_test_case "received_on" 420 atf_add_test_case "optimize_any" 421} 422