1*065b5c7fSKristof Provost# $FreeBSD$ 2*065b5c7fSKristof Provost# 3*065b5c7fSKristof Provost# SPDX-License-Identifier: BSD-2-Clause-FreeBSD 4*065b5c7fSKristof Provost# 5*065b5c7fSKristof Provost# Copyright (c) 2021 Rubicon Communications, LLC (Netgate) 6*065b5c7fSKristof Provost# 7*065b5c7fSKristof Provost# Redistribution and use in source and binary forms, with or without 8*065b5c7fSKristof Provost# modification, are permitted provided that the following conditions 9*065b5c7fSKristof Provost# are met: 10*065b5c7fSKristof Provost# 1. Redistributions of source code must retain the above copyright 11*065b5c7fSKristof Provost# notice, this list of conditions and the following disclaimer. 12*065b5c7fSKristof Provost# 2. Redistributions in binary form must reproduce the above copyright 13*065b5c7fSKristof Provost# notice, this list of conditions and the following disclaimer in the 14*065b5c7fSKristof Provost# documentation and/or other materials provided with the distribution. 15*065b5c7fSKristof Provost# 16*065b5c7fSKristof Provost# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17*065b5c7fSKristof Provost# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18*065b5c7fSKristof Provost# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19*065b5c7fSKristof Provost# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20*065b5c7fSKristof Provost# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21*065b5c7fSKristof Provost# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22*065b5c7fSKristof Provost# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23*065b5c7fSKristof Provost# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24*065b5c7fSKristof Provost# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25*065b5c7fSKristof Provost# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26*065b5c7fSKristof Provost# SUCH DAMAGE. 27*065b5c7fSKristof Provost 28*065b5c7fSKristof Provost. $(atf_get_srcdir)/utils.subr 29*065b5c7fSKristof Provost 30*065b5c7fSKristof Provostcommon_dir=$(atf_get_srcdir)/../common 31*065b5c7fSKristof Provost 32*065b5c7fSKristof Provostatf_test_case "v4" "cleanup" 33*065b5c7fSKristof Provostv4_head() 34*065b5c7fSKristof Provost{ 35*065b5c7fSKristof Provost atf_set descr 'Test killing states by IPv4 address' 36*065b5c7fSKristof Provost atf_set require.user root 37*065b5c7fSKristof Provost atf_set require.progs scapy 38*065b5c7fSKristof Provost} 39*065b5c7fSKristof Provost 40*065b5c7fSKristof Provostv4_body() 41*065b5c7fSKristof Provost{ 42*065b5c7fSKristof Provost pft_init 43*065b5c7fSKristof Provost 44*065b5c7fSKristof Provost epair=$(vnet_mkepair) 45*065b5c7fSKristof Provost ifconfig ${epair}a 192.0.2.1/24 up 46*065b5c7fSKristof Provost 47*065b5c7fSKristof Provost vnet_mkjail alcatraz ${epair}b 48*065b5c7fSKristof Provost jexec alcatraz ifconfig ${epair}b 192.0.2.2/24 up 49*065b5c7fSKristof Provost jexec alcatraz pfctl -e 50*065b5c7fSKristof Provost 51*065b5c7fSKristof Provost pft_set_rules alcatraz "block all" \ 52*065b5c7fSKristof Provost "pass in proto icmp" 53*065b5c7fSKristof Provost 54*065b5c7fSKristof Provost # Sanity check & establish state 55*065b5c7fSKristof Provost # Note: use pft_ping so we always use the same ID, so pf considers all 56*065b5c7fSKristof Provost # echo requests part of the same flow. 57*065b5c7fSKristof Provost atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \ 58*065b5c7fSKristof Provost --sendif ${epair}a \ 59*065b5c7fSKristof Provost --to 192.0.2.2 \ 60*065b5c7fSKristof Provost --replyif ${epair}a 61*065b5c7fSKristof Provost 62*065b5c7fSKristof Provost # Change rules to now deny the ICMP traffic 63*065b5c7fSKristof Provost pft_set_rules noflush alcatraz "block all" 64*065b5c7fSKristof Provost 65*065b5c7fSKristof Provost # Established state means we can still ping alcatraz 66*065b5c7fSKristof Provost atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \ 67*065b5c7fSKristof Provost --sendif ${epair}a \ 68*065b5c7fSKristof Provost --to 192.0.2.2 \ 69*065b5c7fSKristof Provost --replyif ${epair}a 70*065b5c7fSKristof Provost 71*065b5c7fSKristof Provost # Killing with the wrong IP doesn't affect our state 72*065b5c7fSKristof Provost jexec alcatraz pfctl -k 192.0.2.3 73*065b5c7fSKristof Provost 74*065b5c7fSKristof Provost # So we can still ping 75*065b5c7fSKristof Provost atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \ 76*065b5c7fSKristof Provost --sendif ${epair}a \ 77*065b5c7fSKristof Provost --to 192.0.2.2 \ 78*065b5c7fSKristof Provost --replyif ${epair}a 79*065b5c7fSKristof Provost 80*065b5c7fSKristof Provost # Killing with one correct address and one incorrect doesn't kill the state 81*065b5c7fSKristof Provost jexec alcatraz pfctl -k 192.0.2.1 -k 192.0.2.3 82*065b5c7fSKristof Provost 83*065b5c7fSKristof Provost # So we can still ping 84*065b5c7fSKristof Provost atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \ 85*065b5c7fSKristof Provost --sendif ${epair}a \ 86*065b5c7fSKristof Provost --to 192.0.2.2 \ 87*065b5c7fSKristof Provost --replyif ${epair}a 88*065b5c7fSKristof Provost 89*065b5c7fSKristof Provost # Killing with correct address does remove the state 90*065b5c7fSKristof Provost jexec alcatraz pfctl -k 192.0.2.1 91*065b5c7fSKristof Provost 92*065b5c7fSKristof Provost # Now the ping fails 93*065b5c7fSKristof Provost atf_check -s exit:1 -o ignore ${common_dir}/pft_ping.py \ 94*065b5c7fSKristof Provost --sendif ${epair}a \ 95*065b5c7fSKristof Provost --to 192.0.2.2 \ 96*065b5c7fSKristof Provost --replyif ${epair}a 97*065b5c7fSKristof Provost} 98*065b5c7fSKristof Provost 99*065b5c7fSKristof Provostv4_cleanup() 100*065b5c7fSKristof Provost{ 101*065b5c7fSKristof Provost pft_cleanup 102*065b5c7fSKristof Provost} 103*065b5c7fSKristof Provost 104*065b5c7fSKristof Provostatf_test_case "label" "cleanup" 105*065b5c7fSKristof Provostlabel_head() 106*065b5c7fSKristof Provost{ 107*065b5c7fSKristof Provost atf_set descr 'Test killing states by label' 108*065b5c7fSKristof Provost atf_set require.user root 109*065b5c7fSKristof Provost atf_set require.progs scapy 110*065b5c7fSKristof Provost} 111*065b5c7fSKristof Provost 112*065b5c7fSKristof Provostlabel_body() 113*065b5c7fSKristof Provost{ 114*065b5c7fSKristof Provost pft_init 115*065b5c7fSKristof Provost 116*065b5c7fSKristof Provost epair=$(vnet_mkepair) 117*065b5c7fSKristof Provost ifconfig ${epair}a 192.0.2.1/24 up 118*065b5c7fSKristof Provost 119*065b5c7fSKristof Provost vnet_mkjail alcatraz ${epair}b 120*065b5c7fSKristof Provost jexec alcatraz ifconfig ${epair}b 192.0.2.2/24 up 121*065b5c7fSKristof Provost jexec alcatraz pfctl -e 122*065b5c7fSKristof Provost 123*065b5c7fSKristof Provost pft_set_rules alcatraz "block all" \ 124*065b5c7fSKristof Provost "pass in proto tcp label bar" \ 125*065b5c7fSKristof Provost "pass in proto icmp label foo" 126*065b5c7fSKristof Provost 127*065b5c7fSKristof Provost # Sanity check & establish state 128*065b5c7fSKristof Provost # Note: use pft_ping so we always use the same ID, so pf considers all 129*065b5c7fSKristof Provost # echo requests part of the same flow. 130*065b5c7fSKristof Provost atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \ 131*065b5c7fSKristof Provost --sendif ${epair}a \ 132*065b5c7fSKristof Provost --to 192.0.2.2 \ 133*065b5c7fSKristof Provost --replyif ${epair}a 134*065b5c7fSKristof Provost 135*065b5c7fSKristof Provost # Change rules to now deny the ICMP traffic 136*065b5c7fSKristof Provost pft_set_rules noflush alcatraz "block all" 137*065b5c7fSKristof Provost 138*065b5c7fSKristof Provost # Established state means we can still ping alcatraz 139*065b5c7fSKristof Provost atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \ 140*065b5c7fSKristof Provost --sendif ${epair}a \ 141*065b5c7fSKristof Provost --to 192.0.2.2 \ 142*065b5c7fSKristof Provost --replyif ${epair}a 143*065b5c7fSKristof Provost 144*065b5c7fSKristof Provost # Killing a label on a different rules keeps the state 145*065b5c7fSKristof Provost jexec alcatraz pfctl -k label -k bar 146*065b5c7fSKristof Provost atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \ 147*065b5c7fSKristof Provost --sendif ${epair}a \ 148*065b5c7fSKristof Provost --to 192.0.2.2 \ 149*065b5c7fSKristof Provost --replyif ${epair}a 150*065b5c7fSKristof Provost 151*065b5c7fSKristof Provost # Killing a non-existing label keeps the state 152*065b5c7fSKristof Provost jexec alcatraz pfctl -k label -k baz 153*065b5c7fSKristof Provost atf_check -s exit:0 -o ignore ${common_dir}/pft_ping.py \ 154*065b5c7fSKristof Provost --sendif ${epair}a \ 155*065b5c7fSKristof Provost --to 192.0.2.2 \ 156*065b5c7fSKristof Provost --replyif ${epair}a 157*065b5c7fSKristof Provost 158*065b5c7fSKristof Provost # Killing the correct label kills the state 159*065b5c7fSKristof Provost jexec alcatraz pfctl -k label -k foo 160*065b5c7fSKristof Provost atf_check -s exit:1 -o ignore ${common_dir}/pft_ping.py \ 161*065b5c7fSKristof Provost --sendif ${epair}a \ 162*065b5c7fSKristof Provost --to 192.0.2.2 \ 163*065b5c7fSKristof Provost --replyif ${epair}a 164*065b5c7fSKristof Provost} 165*065b5c7fSKristof Provost 166*065b5c7fSKristof Provostlabel_cleanup() 167*065b5c7fSKristof Provost{ 168*065b5c7fSKristof Provost pft_cleanup 169*065b5c7fSKristof Provost} 170*065b5c7fSKristof Provost 171*065b5c7fSKristof Provostatf_init_test_cases() 172*065b5c7fSKristof Provost{ 173*065b5c7fSKristof Provost atf_add_test_case "v4" 174*065b5c7fSKristof Provost atf_add_test_case "label" 175*065b5c7fSKristof Provost} 176