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