1# $NetBSD: t_tunnel.sh,v 1.2 2020/08/29 07:22:49 tih Exp $ 2# 3# Copyright (c) 2018 Ryota Ozaki <ozaki.ryota@gmail.com> 4# All rights reserved. 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS 16# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25# POSSIBILITY OF SUCH DAMAGE. 26# 27 28BUS_LOCAL=bus_local 29BUS_TUN=bus_tun 30BUS_PEER=bus_peer 31SOCK_LOCAL=unix://wg_local 32SOCK_TUN_LOCAL=unix://wg_tun_local 33SOCK_TUN_PEER=unix://wg_tun_peer 34SOCK_PEER=unix://wg_peer 35 36escape_key() 37{ 38 39 echo $1 | sed 's/\+/\\+/g' | sed 's|\/|\\/|g' 40} 41 42setup_servers() 43{ 44 45 rump_server_start $SOCK_LOCAL netinet6 46 rump_server_add_iface $SOCK_LOCAL shmif0 $BUS_LOCAL 47 48 rump_server_crypto_start $SOCK_TUN_LOCAL netinet6 wg 49 rump_server_add_iface $SOCK_TUN_LOCAL shmif0 $BUS_LOCAL 50 rump_server_add_iface $SOCK_TUN_LOCAL shmif1 $BUS_TUN 51 52 rump_server_crypto_start $SOCK_TUN_PEER netinet6 wg 53 rump_server_add_iface $SOCK_TUN_PEER shmif0 $BUS_PEER 54 rump_server_add_iface $SOCK_TUN_PEER shmif1 $BUS_TUN 55 56 rump_server_start $SOCK_PEER netinet6 57 rump_server_add_iface $SOCK_PEER shmif0 $BUS_PEER 58} 59 60setup_edge() 61{ 62 local ifconfig="atf_check -s exit:0 rump.ifconfig" 63 local proto=$1 64 local ip=$2 65 local prefix=$3 66 local gw=$4 67 local ip_bad=$5 68 local alias= 69 70 atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.dad_count=0 71 atf_check -s exit:0 rump.sysctl -q -w net.inet6.ip6.dad_count=0 72 $ifconfig shmif0 $proto $ip/$prefix 73 atf_check -s exit:0 -o ignore rump.route add -$proto default $gw 74 75 if [ -z "$ip_bad" ]; then 76 return 77 fi 78 79 if [ $proto = inet ]; then 80 alias="alias" 81 fi 82 83 $ifconfig shmif0 $proto $ip_bad/$prefix $alias 84} 85 86setup_ip() 87{ 88 local ifconfig="atf_check -s exit:0 rump.ifconfig" 89 local proto=$1 90 local ip=$2 91 local prefix=$3 92 93 $ifconfig shmif0 $proto $ip/$prefix 94} 95setup_router() 96{ 97 98 atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.forwarding=1 99 atf_check -s exit:0 rump.sysctl -q -w net.inet6.ip6.forwarding=1 100 atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.dad_count=0 101 atf_check -s exit:0 rump.sysctl -q -w net.inet6.ip6.dad_count=0 102} 103 104setup_wg() 105{ 106 local ifconfig="atf_check -s exit:0 rump.ifconfig" 107 local wgconfig="atf_check -s exit:0 $HIJACKING wgconfig" 108 local proto=$1 109 local ip=$2 110 local prefix=$3 111 local port=$4 112 local key_priv="$5" 113 local privfile=./tmp 114 115 $ifconfig wg0 create 116 $ifconfig wg0 $proto $ip/$prefix 117 $DEBUG && rump.netstat -nr 118 echo $key_priv > $privfile 119 $wgconfig wg0 set private-key $privfile 120 $wgconfig wg0 set listen-port $port 121 rm -f $privfile 122 $ifconfig wg0 up 123 124 check_conf_port wg0 $port 125 check_conf_privkey wg0 "$key_priv" 126} 127 128setup_wg_route() 129{ 130 local proto=$1 131 local subnet=$2 132 local subnet_bad=$3 133 134 atf_check -s exit:0 -o ignore rump.route add -$proto -net $subnet -link wg0 -iface 135 if [ -n "$subnet_bad" ]; then 136 atf_check -s exit:0 -o ignore rump.route add -$proto -net $subnet_bad -link wg0 -iface 137 fi 138} 139 140prepare_file() 141{ 142 local file=$1 143 local data="0123456789" 144 145 touch $file 146 for i in `seq 1 200` 147 do 148 echo $data >> $file 149 done 150} 151 152test_tcp() 153{ 154 local proto=$1 155 local ip_peer=$2 156 local _proto= 157 158 prepare_file ./file_send 159 160 if [ $proto = inet ]; then 161 _proto=ipv4 162 else 163 _proto=ipv6 164 fi 165 start_nc_server $SOCK_PEER 1234 ./file_recv $_proto 166 167 export RUMP_SERVER=$SOCK_LOCAL 168 # Send a file to the server 169 # XXX Need a bit longer timeout value because the packet processing 170 # of the implementation is quite inefficient... 171 atf_check -s exit:0 $HIJACKING \ 172 nc -N -w 20 $ip_peer 1234 < ./file_send 173 $DEBUG && extract_new_packets $BUS > ./out 174 $DEBUG && cat ./out 175 stop_nc_server 176 $DEBUG && ls -s ./file_send ./file_recv 177 $DEBUG && wc -l ./file_send 178 $DEBUG && wc -l ./file_recv 179 $DEBUG && diff -u ./file_send ./file_recv 180 atf_check -s exit:0 diff -q ./file_send ./file_recv 181 rm -f ./out ./file_recv ./file_send 182} 183 184wg_tunnel_common() 185{ 186 local outer_proto=$1 187 local inner_proto=$2 188 local ifconfig="atf_check -s exit:0 rump.ifconfig" 189 local wgconfig="atf_check -s exit:0 $HIJACKING wgconfig" 190 local port=51820 191 local ip_local= ip_peer= 192 local ip_wg_local= ip_wg_peer= 193 local outer_prefix= outer_prefixall= 194 local inner_prefix= inner_prefixall= 195 196 if [ $outer_proto = inet ]; then 197 ip_tun_local_tun=192.168.10.1 198 ip_tun_peer_tun=192.168.10.2 199 outer_prefix=24 200 outer_prefixall=32 201 else 202 ip_tun_local_tun=fc00:10::1 203 ip_tun_peer_tun=fc00:10::2 204 outer_prefix=64 205 outer_prefixall=128 206 fi 207 208 if [ $inner_proto = inet ]; then 209 ip_local=192.168.1.2 210 ip_tun_local=192.168.1.1 211 ip_wg_local=10.0.0.1 212 ip_wg_peer=10.0.0.2 213 ip_tun_peer=192.168.2.1 214 ip_peer=192.168.2.2 215 ip_peer_bad=192.168.3.2 216 inner_prefix=24 217 inner_prefixall=32 218 subnet_local=192.168.1.0/24 219 subnet_peer=192.168.2.0/24 220 subnet_peer_bad=192.168.3.0/24 221 else 222 ip_tun_local=fc00:1::1 223 ip_local=fc00:1::2 224 ip_wg_local=fd00::1 225 ip_wg_peer=fd00::2 226 ip_tun_peer=fc00:2::1 227 ip_peer=fc00:2::2 228 ip_peer_bad=fc00:3::2 229 inner_prefix=64 230 inner_prefixall=128 231 subnet_local=fc00:1::/64 232 subnet_peer=fc00:2::/64 233 subnet_peer_bad=fc00:3::/64 234 fi 235 236 setup_servers 237 238 # It sets key_priv_local key_pub_local key_priv_peer key_pub_peer 239 generate_keys 240 241 export RUMP_SERVER=$SOCK_LOCAL 242 setup_edge $inner_proto $ip_local $inner_prefix $ip_tun_local 243 244 export RUMP_SERVER=$SOCK_TUN_LOCAL 245 setup_router 246 $ifconfig shmif0 $inner_proto $ip_tun_local/$inner_prefix 247 $ifconfig shmif1 $outer_proto $ip_tun_local_tun/$outer_prefix 248 setup_wg $inner_proto $ip_wg_local $inner_prefix $port "$key_priv_local" 249 setup_wg_route $inner_proto $subnet_peer $subnet_peer_bad 250 251 export RUMP_SERVER=$SOCK_TUN_PEER 252 setup_router 253 $ifconfig shmif0 $inner_proto $ip_tun_peer/$inner_prefix 254 $ifconfig shmif1 $outer_proto $ip_tun_peer_tun/$outer_prefix 255 setup_wg $inner_proto $ip_wg_peer $inner_prefix $port "$key_priv_peer" 256 setup_wg_route $inner_proto $subnet_local 257 258 export RUMP_SERVER=$SOCK_PEER 259 setup_edge $inner_proto $ip_peer $inner_prefix $ip_tun_peer $ip_peer_bad 260 261 export RUMP_SERVER=$SOCK_TUN_LOCAL 262 add_peer wg0 peer0 $key_pub_peer $ip_tun_peer_tun:$port \ 263 $ip_wg_peer/$inner_prefixall,$subnet_peer 264 265 export RUMP_SERVER=$SOCK_TUN_PEER 266 add_peer wg0 peer0 $key_pub_local $ip_tun_local_tun:$port \ 267 $ip_wg_local/$inner_prefixall,$subnet_local 268 269 export RUMP_SERVER=$SOCK_TUN_LOCAL 270 atf_check -s exit:0 -o match:"latest-handshake: \(never\)" \ 271 $HIJACKING wgconfig wg0 show peer peer0 272 273 export RUMP_SERVER=$SOCK_LOCAL 274 check_ping $inner_proto $ip_peer 275 276 export RUMP_SERVER=$SOCK_TUN_LOCAL 277 atf_check -s exit:0 -o not-match:"latest-handshake: \(never\)" \ 278 $HIJACKING wgconfig wg0 show peer peer0 279 280 export RUMP_SERVER=$SOCK_LOCAL 281 # ping fails because the subnet of the IP is not allowed 282 check_ping_fail $inner_proto $ip_peer_bad 283 284 # 285 # Test TCP stream over the tunnel 286 # 287 test_tcp $inner_proto $ip_peer 288 289 export RUMP_SERVER=$SOCK_TUN_LOCAL 290 $ifconfig wg0 destroy 291 export RUMP_SERVER=$SOCK_TUN_PEER 292 $ifconfig wg0 destroy 293} 294 295add_tunnel_test() 296{ 297 local inner=$1 298 local outer=$2 299 local ipv4=inet 300 local ipv6=inet6 301 302 name="wg_tunnel_${inner}_over_${outer}" 303 fulldesc="Test wg(4) with ${inner} over ${outer}" 304 305 eval inner=\$$inner 306 eval outer=\$$outer 307 308 atf_test_case ${name} cleanup 309 eval " 310 ${name}_head() { 311 atf_set descr \"${fulldesc}\" 312 atf_set require.progs rump_server wgconfig wg-keygen 313 } 314 ${name}_body() { 315 wg_tunnel_common $outer $inner 316 rump_server_destroy_ifaces 317 } 318 ${name}_cleanup() { 319 \$DEBUG && dump 320 cleanup 321 }" 322 atf_add_test_case ${name} 323} 324 325atf_init_test_cases() 326{ 327 328 add_tunnel_test ipv4 ipv4 329 add_tunnel_test ipv4 ipv6 330 add_tunnel_test ipv6 ipv4 331 add_tunnel_test ipv6 ipv6 332} 333