1# $FreeBSD$ 2# 3# SPDX-License-Identifier: BSD-2-Clause-FreeBSD 4# 5# Copyright (c) 2021 Modirum MDPay 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 "basic" "cleanup" 33basic_head() 34{ 35 atf_set descr 'Basic syncookie test' 36 atf_set require.user root 37} 38 39basic_body() 40{ 41 pft_init 42 43 epair=$(vnet_mkepair) 44 45 vnet_mkjail alcatraz ${epair}b 46 jexec alcatraz ifconfig ${epair}b 192.0.2.1/24 up 47 jexec alcatraz /usr/sbin/inetd -p inetd-alcatraz.pid \ 48 $(atf_get_srcdir)/echo_inetd.conf 49 50 ifconfig ${epair}a 192.0.2.2/24 up 51 52 jexec alcatraz pfctl -e 53 pft_set_rules alcatraz \ 54 "set syncookies always" \ 55 "pass in" \ 56 "pass out" 57 58 # Sanity check 59 atf_check -s exit:0 -o ignore ping -c 1 192.0.2.1 60 61 reply=$(echo foo | nc -N -w 5 192.0.2.1 7) 62 if [ "${reply}" != "foo" ]; 63 then 64 atf_fail "Failed to connect to syncookie protected echo daemon" 65 fi 66} 67 68basic_cleanup() 69{ 70 rm -f inetd-alcatraz.pid 71 pft_cleanup 72} 73 74atf_test_case "forward" "cleanup" 75forward_head() 76{ 77 atf_set descr 'Syncookies for forwarded hosts' 78 atf_set require.user root 79} 80 81forward_body() 82{ 83 pft_init 84 85 epair_in=$(vnet_mkepair) 86 epair_out=$(vnet_mkepair) 87 88 vnet_mkjail fwd ${epair_in}b ${epair_out}a 89 vnet_mkjail srv ${epair_out}b 90 91 jexec fwd ifconfig ${epair_in}b 192.0.2.1/24 up 92 jexec fwd ifconfig ${epair_out}a 198.51.100.1/24 up 93 jexec fwd sysctl net.inet.ip.forwarding=1 94 95 jexec srv ifconfig ${epair_out}b 198.51.100.2/24 up 96 jexec srv route add default 198.51.100.1 97 jexec srv /usr/sbin/inetd -p inetd-alcatraz.pid \ 98 $(atf_get_srcdir)/echo_inetd.conf 99 100 ifconfig ${epair_in}a 192.0.2.2/24 up 101 route add -net 198.51.100.0/24 192.0.2.1 102 103 jexec fwd pfctl -e 104 pft_set_rules fwd \ 105 "set syncookies always" \ 106 "pass in" \ 107 "pass out" 108 109 # Sanity check 110 atf_check -s exit:0 -o ignore ping -c 1 198.51.100.2 111 112 reply=$(echo foo | nc -N -w 5 198.51.100.2 7) 113 if [ "${reply}" != "foo" ]; 114 then 115 atf_fail "Failed to connect to syncookie protected echo daemon" 116 fi 117} 118 119forward_cleanup() 120{ 121 rm -f inetd-alcatraz.pid 122 pft_cleanup 123} 124 125atf_test_case "nostate" "cleanup" 126nostate_head() 127{ 128 atf_set descr 'Ensure that we do not create until SYN|ACK' 129 atf_set require.user root 130 atf_set require.progs scapy 131} 132 133nostate_body() 134{ 135 pft_init 136 137 epair=$(vnet_mkepair) 138 ifconfig ${epair}a 192.0.2.2/24 up 139 140 vnet_mkjail alcatraz ${epair}b 141 jexec alcatraz ifconfig ${epair}b 192.0.2.1/24 up 142 143 jexec alcatraz pfctl -e 144 pft_set_rules alcatraz \ 145 "set syncookies always" \ 146 "pass in" \ 147 "pass out" 148 149 # Sanity check 150 atf_check -s exit:0 -o ignore ping -c 1 192.0.2.1 151 152 # Now syn flood to create many states 153 ${common_dir}/pft_synflood.py \ 154 --sendif ${epair}a \ 155 --to 192.0.2.2 \ 156 --count 20 157 158 states=$(jexec alcatraz pfctl -ss | grep tcp) 159 if [ -n "$states" ]; 160 then 161 echo "$states" 162 atf_fail "Found unexpected state" 163 fi 164} 165 166nostate_cleanup() 167{ 168 pft_cleanup 169} 170 171atf_test_case "adaptive" "cleanup" 172adaptive_head() 173{ 174 atf_set descr 'Adaptive mode test' 175 atf_set require.user root 176 atf_set require.progs scapy 177} 178 179adaptive_body() 180{ 181 pft_init 182 183 epair=$(vnet_mkepair) 184 ifconfig ${epair}a 192.0.2.2/24 up 185 186 vnet_mkjail alcatraz ${epair}b 187 jexec alcatraz ifconfig ${epair}b 192.0.2.1/24 up 188 189 jexec alcatraz pfctl -e 190 pft_set_rules alcatraz \ 191 "set limit states 100" \ 192 "set syncookies adaptive (start 10%%, end 5%%)" \ 193 "pass in" \ 194 "pass out" 195 196 # Sanity check 197 atf_check -s exit:0 -o ignore ping -c 1 192.0.2.1 198 199 # Now syn flood to create many states 200 ${common_dir}/pft_synflood.py \ 201 --sendif ${epair}a \ 202 --to 192.0.2.2 \ 203 --count 100 204 205 # Adaptive mode should kick in and stop us from creating more than 206 # about 10 states 207 states=$(jexec alcatraz pfctl -ss | grep tcp | wc -l) 208 if [ "$states" -gt 20 ]; 209 then 210 echo "$states" 211 atf_fail "Found unexpected states" 212 fi 213} 214 215adaptive_cleanup() 216{ 217 pft_cleanup 218} 219 220atf_init_test_cases() 221{ 222 atf_add_test_case "basic" 223 atf_add_test_case "forward" 224 atf_add_test_case "nostate" 225 atf_add_test_case "adaptive" 226} 227