]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tests/sys/net/if_wg.sh
zfs: merge openzfs/zfs@10e36e176
[FreeBSD/FreeBSD.git] / tests / sys / net / if_wg.sh
1 # $FreeBSD$
2 #
3 # SPDX-License-Identifier: BSD-2-Clause
4 #
5 # Copyright (c) 2021 The FreeBSD Foundation
6 #
7 # This software was developed by Mark Johnston under sponsorship
8 # from the FreeBSD Foundation.
9 #
10 # Redistribution and use in source and binary forms, with or without
11 # modification, are permitted provided that the following conditions
12 # are met:
13 # 1. Redistributions of source code must retain the above copyright
14 #    notice, this list of conditions and the following disclaimer.
15 # 2. Redistributions in binary form must reproduce the above copyright
16 #    notice, this list of conditions and the following disclaimer in the
17 #    documentation and/or other materials provided with the distribution.
18 #
19 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 # ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 # SUCH DAMAGE.
30
31 . $(atf_get_srcdir)/../common/vnet.subr
32
33 atf_test_case "wg_basic" "cleanup"
34 wg_basic_head()
35 {
36         atf_set descr 'Create a wg(4) tunnel over an epair and pass traffic between jails'
37         atf_set require.user root
38 }
39
40 wg_basic_body()
41 {
42         local epair pri1 pri2 pub1 pub2 wg1 wg2
43         local endpoint1 endpoint2 tunnel1 tunnel2
44
45         kldload -n if_wg || atf_skip "This test requires if_wg and could not load it"
46
47         pri1=$(wg genkey)
48         pri2=$(wg genkey)
49
50         endpoint1=192.168.2.1
51         endpoint2=192.168.2.2
52         tunnel1=169.254.0.1
53         tunnel2=169.254.0.2
54
55         epair=$(vnet_mkepair)
56
57         vnet_init
58
59         vnet_mkjail wgtest1 ${epair}a
60         vnet_mkjail wgtest2 ${epair}b
61
62         jexec wgtest1 ifconfig ${epair}a ${endpoint1}/24 up
63         jexec wgtest2 ifconfig ${epair}b ${endpoint2}/24 up
64
65         wg1=$(jexec wgtest1 ifconfig wg create)
66         echo "$pri1" | jexec wgtest1 wg set $wg1 listen-port 12345 \
67             private-key /dev/stdin
68         pub1=$(jexec wgtest1 wg show $wg1 public-key)
69         wg2=$(jexec wgtest2 ifconfig wg create)
70         echo "$pri2" | jexec wgtest2 wg set $wg2 listen-port 12345 \
71             private-key /dev/stdin
72         pub2=$(jexec wgtest2 wg show $wg2 public-key)
73
74         atf_check -s exit:0 -o ignore \
75             jexec wgtest1 wg set $wg1 peer "$pub2" \
76             endpoint ${endpoint2}:12345 allowed-ips ${tunnel2}/32
77         atf_check -s exit:0 \
78             jexec wgtest1 ifconfig $wg1 inet ${tunnel1}/24 up
79
80         atf_check -s exit:0 -o ignore \
81             jexec wgtest2 wg set $wg2 peer "$pub1" \
82             endpoint ${endpoint1}:12345 allowed-ips ${tunnel1}/32
83         atf_check -s exit:0 \
84             jexec wgtest2 ifconfig $wg2 inet ${tunnel2}/24 up
85
86         # Generous timeout since the handshake takes some time.
87         atf_check -s exit:0 -o ignore jexec wgtest1 ping -c 1 -t 5 $tunnel2
88         atf_check -s exit:0 -o ignore jexec wgtest2 ping -c 1 $tunnel1
89 }
90
91 wg_basic_cleanup()
92 {
93         vnet_cleanup
94 }
95
96 # The kernel is expected to silently ignore any attempt to add a peer with a
97 # public key identical to the host's.
98 atf_test_case "wg_key_peerdev_shared" "cleanup"
99 wg_key_peerdev_shared_head()
100 {
101         atf_set descr 'Create a wg(4) interface with a shared pubkey between device and a peer'
102         atf_set require.user root
103 }
104
105 wg_key_peerdev_shared_body()
106 {
107         local epair pri1 pub1 wg1
108         local endpoint1 tunnel1
109
110         kldload -n if_wg || atf_skip "This test requires if_wg and could not load it"
111
112         pri1=$(wg genkey)
113
114         endpoint1=192.168.2.1
115         tunnel1=169.254.0.1
116
117         vnet_mkjail wgtest1
118
119         wg1=$(jexec wgtest1 ifconfig wg create)
120         echo "$pri1" | jexec wgtest1 wg set $wg1 listen-port 12345 \
121             private-key /dev/stdin
122         pub1=$(jexec wgtest1 wg show $wg1 public-key)
123
124         atf_check -s exit:0 \
125             jexec wgtest1 wg set ${wg1} peer "${pub1}" \
126             allowed-ips "${tunnel1}/32"
127
128         atf_check -o empty jexec wgtest1 wg show ${wg1} peers
129 }
130
131 wg_key_peerdev_shared_cleanup()
132 {
133         vnet_cleanup
134 }
135
136 # When a wg(8) interface has a private key reassigned that corresponds to the
137 # public key already on a peer, the kernel is expected to deconfigure the peer
138 # to resolve the conflict.
139 atf_test_case "wg_key_peerdev_makeshared" "cleanup"
140 wg_key_peerdev_makeshared_head()
141 {
142         atf_set descr 'Create a wg(4) interface and assign peer key to device'
143         atf_set require.progs wg
144 }
145
146 wg_key_peerdev_makeshared_body()
147 {
148         local epair pri1 pub1 pri2 wg1 wg2
149         local endpoint1 tunnel1
150
151         kldload -n if_wg || atf_skip "This test requires if_wg and could not load it"
152
153         pri1=$(wg genkey)
154         pri2=$(wg genkey)
155
156         endpoint1=192.168.2.1
157         tunnel1=169.254.0.1
158
159         vnet_mkjail wgtest1
160
161         wg1=$(jexec wgtest1 ifconfig wg create)
162         echo "$pri1" | jexec wgtest1 wg set $wg1 listen-port 12345 \
163             private-key /dev/stdin
164         pub1=$(jexec wgtest1 wg show $wg1 public-key)
165         wg2=$(jexec wgtest1 ifconfig wg create)
166         echo "$pri2" | jexec wgtest1 wg set $wg2 listen-port 12345 \
167             private-key /dev/stdin
168
169         atf_check -s exit:0 -o ignore \
170             jexec wgtest1 wg set ${wg2} peer "${pub1}" \
171             allowed-ips "${tunnel1}/32"
172
173         atf_check -o not-empty jexec wgtest1 wg show ${wg2} peers
174
175         jexec wgtest1 sh -c "echo '${pri1}' > pri1"
176
177         atf_check -s exit:0 \
178            jexec wgtest1 wg set ${wg2} private-key pri1
179
180         atf_check -o empty jexec wgtest1 wg show ${wg2} peers
181 }
182
183 wg_key_peerdev_makeshared_cleanup()
184 {
185         vnet_cleanup
186 }
187
188 # The kernel is expected to create the wg socket in the jail context that the
189 # wg interface was created in, even if the interface is moved to a different
190 # vnet.
191 atf_test_case "wg_vnet_parent_routing" "cleanup"
192 wg_vnet_parent_routing_head()
193 {
194         atf_set descr 'Create a wg(4) tunnel without epairs and pass traffic between jails'
195         atf_set require.user root
196 }
197
198 wg_vnet_parent_routing_body()
199 {
200         local pri1 pri2 pub1 pub2 wg1 wg2
201         local tunnel1 tunnel2
202
203         kldload -n if_wg
204
205         pri1=$(wg genkey)
206         pri2=$(wg genkey)
207
208         tunnel1=169.254.0.1
209         tunnel2=169.254.0.2
210
211         vnet_init
212
213         wg1=$(ifconfig wg create)
214         wg2=$(ifconfig wg create)
215
216         vnet_mkjail wgtest1 ${wg1}
217         vnet_mkjail wgtest2 ${wg2}
218
219         echo "$pri1" | jexec wgtest1 wg set $wg1 listen-port 12345 \
220             private-key /dev/stdin
221         pub1=$(jexec wgtest1 wg show $wg1 public-key)
222         echo "$pri2" | jexec wgtest2 wg set $wg2 listen-port 12346 \
223             private-key /dev/stdin
224         pub2=$(jexec wgtest2 wg show $wg2 public-key)
225
226         atf_check -s exit:0 -o ignore \
227             jexec wgtest1 wg set $wg1 peer "$pub2" \
228             endpoint 127.0.0.1:12346 allowed-ips ${tunnel2}/32
229         atf_check -s exit:0 \
230             jexec wgtest1 ifconfig $wg1 inet ${tunnel1}/24 up
231
232         atf_check -s exit:0 -o ignore \
233             jexec wgtest2 wg set $wg2 peer "$pub1" \
234             endpoint 127.0.0.1:12345 allowed-ips ${tunnel1}/32
235         atf_check -s exit:0 \
236             jexec wgtest2 ifconfig $wg2 inet ${tunnel2}/24 up
237
238         # Sanity check ICMP counters; should clearly be nothing on these new
239         # jails.  We'll check them as we go to ensure that the ICMP packets
240         # generated really are being handled by the jails' vnets.
241         atf_check -o not-match:"histogram" jexec wgtest1 netstat -s -p icmp
242         atf_check -o not-match:"histogram" jexec wgtest2 netstat -s -p icmp
243
244         # Generous timeout since the handshake takes some time.
245         atf_check -s exit:0 -o ignore jexec wgtest1 ping -c 1 -t 5 $tunnel2
246         atf_check -o match:"echo reply: 1" jexec wgtest1 netstat -s -p icmp
247         atf_check -o match:"echo: 1" jexec wgtest2 netstat -s -p icmp
248
249         atf_check -s exit:0 -o ignore jexec wgtest2 ping -c 1 $tunnel1
250         atf_check -o match:"echo reply: 1" jexec wgtest2 netstat -s -p icmp
251         atf_check -o match:"echo: 1" jexec wgtest1 netstat -s -p icmp
252 }
253
254 wg_vnet_parent_routing_cleanup()
255 {
256         vnet_cleanup
257 }
258
259 atf_init_test_cases()
260 {
261         atf_add_test_case "wg_basic"
262         atf_add_test_case "wg_key_peerdev_shared"
263         atf_add_test_case "wg_key_peerdev_makeshared"
264         atf_add_test_case "wg_vnet_parent_routing"
265 }