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 29atf_test_case "pr183198" "cleanup" 30pr183198_head() 31{ 32 atf_set descr 'Test tables referenced by rules in anchors' 33 atf_set require.user root 34} 35 36pr183198_body() 37{ 38 pft_init 39 40 epair=$(vnet_mkepair) 41 vnet_mkjail alcatraz ${epair}b 42 jexec alcatraz pfctl -e 43 44 # Forward with pf enabled 45 pft_set_rules alcatraz \ 46 "table <test> { 10.0.0.1, 10.0.0.2, 10.0.0.3 }" \ 47 "block in" \ 48 "anchor \"epair\" on ${epair}b { \n\ 49 pass in from <test> \n\ 50 }" 51 52 atf_check -s exit:0 -o ignore jexec alcatraz pfctl -sr -a '*' 53 atf_check -s exit:0 -o ignore jexec alcatraz pfctl -t test -T show 54} 55 56pr183198_cleanup() 57{ 58 pft_cleanup 59} 60 61atf_test_case "pr279225" "cleanup" 62pr279225_head() 63{ 64 atf_set descr "Test that we can retrieve longer anchor names, PR 279225" 65 atf_set require.user root 66} 67 68pr279225_body() 69{ 70 pft_init 71 72 vnet_mkjail alcatraz 73 74 pft_set_rules alcatraz \ 75 "nat-anchor \"appjail-nat/jail/*\" all" \ 76 "rdr-anchor \"appjail-rdr/*\" all" \ 77 "anchor \"appjail/jail/*\" all" 78 79 atf_check -s exit:0 -o match:"nat-anchor \"appjail-nat/jail/\*\" all \{" \ 80 jexec alcatraz pfctl -sn -a "*" 81 atf_check -s exit:0 -o match:"rdr-anchor \"appjail-rdr/\*\" all \{" \ 82 jexec alcatraz pfctl -sn -a "*" 83 atf_check -s exit:0 -o match:"anchor \"appjail/jail/\*\" all \{" \ 84 jexec alcatraz pfctl -sr -a "*" 85} 86 87pr279225_cleanup() 88{ 89 pft_cleanup 90} 91 92atf_test_case "nested_anchor" "cleanup" 93nested_anchor_head() 94{ 95 atf_set descr 'Test setting and retrieving nested anchors' 96 atf_set require.user root 97} 98 99nested_anchor_body() 100{ 101 pft_init 102 103 epair=$(vnet_mkepair) 104 vnet_mkjail alcatraz ${epair}a 105 106 pft_set_rules alcatraz \ 107 "anchor \"foo\" { \n\ 108 anchor \"bar\" { \n\ 109 pass on ${epair}a \n\ 110 } \n\ 111 }" 112 113 atf_check -s exit:0 -o inline:"anchor \"foo\" all { 114 anchor \"bar\" all { 115 pass on ${epair}a all flags S/SA keep state 116 } 117} 118" jexec alcatraz pfctl -sr -a "*" 119} 120 121nested_anchor_cleanup() 122{ 123 pft_cleanup 124} 125 126atf_test_case "deeply_nested" "cleanup" 127deeply_nested_head() 128{ 129 atf_set descr 'Test setting and retrieving deeply nested anchors' 130 atf_set require.user root 131} 132 133deeply_nested_body() 134{ 135 pft_init 136 137 epair=$(vnet_mkepair) 138 vnet_mkjail alcatraz ${epair}a 139 140 pft_set_rules alcatraz \ 141 "anchor \"foo\" { \n\ 142 anchor \"bar\" { \n\ 143 anchor \"foobar\" { \n\ 144 pass on ${epair}a \n\ 145 } \n\ 146 anchor \"quux\" { \n\ 147 pass on ${epair}a \n\ 148 } \n\ 149 } \n\ 150 anchor \"baz\" { \n\ 151 pass on ${epair}a \n\ 152 } \n\ 153 anchor \"qux\" { \n\ 154 pass on ${epair}a \n\ 155 } \n\ 156 }" 157 158 atf_check -s exit:0 -o \ 159 inline:" foo\n foo/bar\n foo/bar/foobar\n foo/bar/quux\n foo/baz\n foo/qux\n" \ 160 jexec alcatraz pfctl -sA 161 162 atf_check -s exit:0 -o inline:" foo/bar/foobar\n foo/bar/quux\n" \ 163 jexec alcatraz pfctl -a foo/bar -sA 164} 165 166deeply_nested_cleanup() 167{ 168 pft_cleanup 169} 170 171atf_test_case "wildcard" "cleanup" 172wildcard_head() 173{ 174 atf_set descr 'Test wildcard anchors for functionality' 175 atf_set require.user root 176} 177 178wildcard_body() 179{ 180 pft_init 181 182 epair=$(vnet_mkepair) 183 vnet_mkjail alcatraz ${epair}a 184 185 ifconfig ${epair}b 192.0.2.2/24 up 186 jexec alcatraz ifconfig ${epair}a 192.0.2.1/24 up 187 188 # Sanity check 189 atf_check -s exit:0 -o ignore ping -c 1 192.0.2.1 190 191 jexec alcatraz pfctl -e 192 pft_set_rules alcatraz \ 193 "block" \ 194 "anchor \"foo/*\"" 195 196 atf_check -s exit:2 -o ignore ping -c 1 192.0.2.1 197 198 echo "pass" | jexec alcatraz pfctl -g -f - -a "foo/bar" 199 200 jexec alcatraz pfctl -sr -a "*" 201 atf_check -s exit:0 -o ignore ping -c 1 192.0.2.1 202} 203 204wildcard_cleanup() 205{ 206 pft_cleanup 207} 208 209atf_test_case "nested_label" "cleanup" 210nested_label_head() 211{ 212 atf_set descr "Test recursive listing of labels" 213 atf_set require.user root 214} 215 216nested_label_body() 217{ 218 pft_init 219 220 vnet_mkjail alcatraz 221 222 pft_set_rules alcatraz \ 223 "anchor \"foo\" { \n\ 224 pass in quick proto icmp label \"passicmp\"\n\ 225 anchor \"bar\" { \n\ 226 pass in proto tcp label \"passtcp\"\n\ 227 } \n\ 228 }" \ 229 "pass quick from any to any label \"anytoany\"" 230 231 atf_check -s exit:0 \ 232 -o inline:"passicmp 0 0 0 0 0 0 0 0 233passtcp 0 0 0 0 0 0 0 0 234anytoany 0 0 0 0 0 0 0 0 235" jexec alcatraz pfctl -sl -a* 236} 237 238nested_label_cleanup() 239{ 240 pft_cleanup 241} 242 243atf_test_case "quick" "cleanup" 244quick_head() 245{ 246 atf_set descr "Test handling of quick on anchors" 247 atf_set require.user root 248} 249 250quick_body() 251{ 252 pft_init 253 254 epair=$(vnet_mkepair) 255 vnet_mkjail alcatraz ${epair}a 256 257 ifconfig ${epair}b 192.0.2.2/24 up 258 jexec alcatraz ifconfig ${epair}a 192.0.2.1/24 up 259 260 # Sanity check 261 atf_check -s exit:0 -o ignore ping -c 1 192.0.2.1 262 263 jexec alcatraz pfctl -e 264 pft_set_rules alcatraz \ 265 "anchor quick {\n\ 266 pass\n\ 267 }" \ 268 "block" 269 270 # We can still ping because the anchor is 'quick' 271 atf_check -s exit:0 -o ignore ping -c 1 192.0.2.1 272 jexec alcatraz pfctl -sr -v 273 jexec alcatraz pfctl -ss -v 274} 275 276quick_cleanup() 277{ 278 pft_cleanup 279} 280 281atf_test_case "quick_nested" "cleanup" 282quick_nested_head() 283{ 284 atf_set descr 'Verify that a nested anchor does not clear quick' 285 atf_set require.user root 286} 287 288quick_nested_body() 289{ 290 pft_init 291 292 epair=$(vnet_mkepair) 293 vnet_mkjail alcatraz ${epair}a 294 295 ifconfig ${epair}b 192.0.2.2/24 up 296 jexec alcatraz ifconfig ${epair}a 192.0.2.1/24 up 297 298 # Sanity check 299 atf_check -s exit:0 -o ignore ping -c 1 192.0.2.1 300 301 jexec alcatraz pfctl -e 302 pft_set_rules alcatraz \ 303 "anchor quick {\n\ 304 pass\n\ 305 anchor {\n\ 306 block proto tcp\n\ 307 }\n\ 308 }" \ 309 "block" 310 ping -c 1 192.0.2.1 311 312 jexec alcatraz pfctl -sr -v 313 jexec alcatraz pfctl -ss -v 314 315 # We can still ping because the anchor is 'quick' 316 atf_check -s exit:0 -o ignore ping -c 1 192.0.2.1 317 jexec alcatraz pfctl -sr -v 318 jexec alcatraz pfctl -ss -v 319} 320 321quick_nested_cleanup() 322{ 323 pft_cleanup 324} 325 326atf_test_case "counter" "cleanup" 327counter_head() 328{ 329 atf_set descr 'Test counters on anchors' 330 atf_set require.user root 331} 332 333counter_body() 334{ 335 pft_init 336 337 epair=$(vnet_mkepair) 338 vnet_mkjail alcatraz ${epair}a 339 340 ifconfig ${epair}b 192.0.2.2/24 up 341 jexec alcatraz ifconfig ${epair}a 192.0.2.1/24 up 342 343 # Sanity check 344 atf_check -s exit:0 -o ignore ping -c 1 192.0.2.1 345 346 jexec alcatraz pfctl -e 347 pft_set_rules alcatraz \ 348 "anchor \"foo\" {\n\ 349 pass\n\ 350 }" 351 352 # Generate traffic 353 atf_check -s exit:0 -o ignore ping -c 1 192.0.2.1 354 atf_check -s exit:0 -e ignore \ 355 -o match:'[ Evaluations: 1 Packets: 2 Bytes: 168 States: 1 ]' \ 356 jexec alcatraz pfctl -sr -vv 357} 358 359counter_cleanup() 360{ 361 pft_cleanup 362} 363 364atf_test_case "nat" "cleanup" 365nat_head() 366{ 367 atf_set descr 'Test nested nat anchors' 368 atf_set require.user root 369} 370 371nat_body() 372{ 373 pft_init 374 375 epair=$(vnet_mkepair) 376 vnet_mkjail alcatraz ${epair}a 377 378 ifconfig ${epair}b 192.0.2.2/24 up 379 jexec alcatraz ifconfig ${epair}a 192.0.2.1/24 up 380 381 # Sanity check 382 atf_check -s exit:0 -o ignore ping -c 1 192.0.2.1 383 384 jexec alcatraz pfctl -e 385 pft_set_rules alcatraz \ 386 "nat-anchor \"foo/*\"" \ 387 "pass" 388 389 echo "nat log on ${epair}a inet from 192.0.2.0/24 to any port = 53 -> 192.0.2.1" \ 390 | jexec alcatraz pfctl -a "foo/bar" -g -f - 391 echo "rdr on ${epair}a proto tcp to port echo -> 127.0.0.1 port echo" \ 392 | jexec alcatraz pfctl -a "foo/baz" -g -f - 393 394 jexec alcatraz pfctl -sn -a "*" 395 jexec alcatraz pfctl -sn -a "foo/bar" 396 jexec alcatraz pfctl -sn -a "foo/baz" 397 398 atf_check -s exit:0 -o match:"nat log on ${epair}a inet from 192.0.2.0/24 to any port = domain -> 192.0.2.1" \ 399 jexec alcatraz pfctl -sn -a "*" 400 atf_check -s exit:0 -o match:"rdr on ${epair}a inet proto tcp from any to any port = echo -> 127.0.0.1 port 7" \ 401 jexec alcatraz pfctl -sn -a "*" 402} 403 404nat_cleanup() 405{ 406 pft_cleanup 407} 408 409atf_test_case "include" "cleanup" 410include_head() 411{ 412 atf_set descr 'Test including inside anchors' 413 atf_set require.user root 414} 415 416include_body() 417{ 418 pft_init 419 420 wd=`pwd` 421 422 epair=$(vnet_mkepair) 423 vnet_mkjail alcatraz ${epair}a 424 425 ifconfig ${epair}b 192.0.2.2/24 up 426 jexec alcatraz ifconfig ${epair}a 192.0.2.1/24 up 427 428 # Sanity check 429 atf_check -s exit:0 -o ignore ping -c 1 192.0.2.1 430 431 echo "pass" > ${wd}/extra.conf 432 jexec alcatraz pfctl -e 433 pft_set_rules alcatraz \ 434 "block" \ 435 "anchor \"foo\" {\n\ 436 include \"${wd}/extra.conf\"\n\ 437 }" 438 439 jexec alcatraz pfctl -sr 440 441 atf_check -s exit:0 -o ignore ping -c 1 192.0.2.1 442} 443 444include_cleanup() 445{ 446 pft_cleanup 447} 448 449atf_test_case "quick" "cleanup" 450quick_head() 451{ 452 atf_set descr 'Test quick on anchors' 453 atf_set require.user root 454} 455 456quick_body() 457{ 458 pft_init 459 460 epair=$(vnet_mkepair) 461 vnet_mkjail alcatraz ${epair}a 462 463 ifconfig ${epair}b 192.0.2.2/24 up 464 jexec alcatraz ifconfig ${epair}a 192.0.2.1/24 up 465 466 # Sanity check 467 atf_check -s exit:0 -o ignore ping -c 1 192.0.2.1 468 469 jexec alcatraz pfctl -e 470 pft_set_rules alcatraz \ 471 "anchor quick {\n\ 472 pass\n\ 473 }" \ 474 "block" 475 476 atf_check -s exit:0 -o ignore ping -c 1 192.0.2.1 477 jexec alcatraz pfctl -sr -vv -a "*" 478} 479 480quick_cleanup() 481{ 482 pft_cleanup 483} 484 485atf_test_case "recursive_flush" "cleanup" 486recursive_flush_head() 487{ 488 atf_set descr 'Test recursive flushing of rules' 489 atf_set require.user root 490} 491 492recursive_flush_body() 493{ 494 pft_init 495 496 epair=$(vnet_mkepair) 497 vnet_mkjail alcatraz ${epair}a 498 499 ifconfig ${epair}b 192.0.2.2/24 up 500 jexec alcatraz ifconfig ${epair}a 192.0.2.1/24 up 501 502 # Sanity check 503 atf_check -s exit:0 -o ignore ping -c 1 192.0.2.1 504 505 jexec alcatraz pfctl -e 506 pft_set_rules alcatraz \ 507 "block" \ 508 "anchor \"foo\" {\n\ 509 pass\n\ 510 }" 511 512 # We can ping thanks to the pass rule in foo 513 atf_check -s exit:0 -o ignore ping -c 1 192.0.2.1 514 515 # Only reset the main rules. I.e. not a recursive flush 516 pft_set_rules alcatraz \ 517 "block" \ 518 "anchor \"foo\"" 519 520 # "foo" still has the pass rule, so this works 521 jexec alcatraz pfctl -a "*" -sr 522 atf_check -s exit:0 -o ignore ping -c 1 192.0.2.1 523 524 # Now do a recursive flush 525 atf_check -s exit:0 -e ignore -o ignore \ 526 jexec alcatraz pfctl -a "*" -Fr 527 pft_set_rules alcatraz \ 528 "block" \ 529 "anchor \"foo\"" 530 531 # So this fails 532 jexec alcatraz pfctl -a "*" -sr 533 atf_check -s exit:2 -o ignore ping -c 1 192.0.2.1 534} 535 536recursive_flush_cleanup() 537{ 538 pft_cleanup 539} 540 541atf_init_test_cases() 542{ 543 atf_add_test_case "pr183198" 544 atf_add_test_case "pr279225" 545 atf_add_test_case "nested_anchor" 546 atf_add_test_case "deeply_nested" 547 atf_add_test_case "wildcard" 548 atf_add_test_case "nested_label" 549 atf_add_test_case "quick" 550 atf_add_test_case "quick_nested" 551 atf_add_test_case "counter" 552 atf_add_test_case "nat" 553 atf_add_test_case "include" 554 atf_add_test_case "quick" 555 atf_add_test_case "recursive_flush" 556} 557