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 (at] 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 28 BUS_LOCAL=bus_local 29 BUS_TUN=bus_tun 30 BUS_PEER=bus_peer 31 SOCK_LOCAL=unix://wg_local 32 SOCK_TUN_LOCAL=unix://wg_tun_local 33 SOCK_TUN_PEER=unix://wg_tun_peer 34 SOCK_PEER=unix://wg_peer 35 36 escape_key() 37 { 38 39 echo $1 | sed 's/\+/\\+/g' | sed 's|\/|\\/|g' 40 } 41 42 setup_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 60 setup_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 86 setup_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 } 95 setup_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 104 setup_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 128 setup_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 140 prepare_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 152 test_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 184 wg_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 295 add_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 325 atf_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