Home | History | Annotate | Line # | Download | only in if_wg
      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