Skip to content

Commit f78460e

Browse files
committed
Add support for WireGuard
Almost full support for WireGuard admin@server:/> show interface wg0 name : wg0 type : wireguard index : 10 mtu : 1420 operational status : up ipv4 addresses : 10.0.0.1/24 (static) ipv6 addresses : fd00::1/64 (static) peers : 2 Peer 1: public key : ROaZyvJc5DzA2XUAAeTj2YlwDsy2w0lr3t+rWj2imAk= status : UP endpoint : 192.168.10.2:51821 latest handshake : 2025-12-09T22:51:38+00:00 transfer tx : 1412 bytes transfer rx : 1324 bytes Peer 2: public key : Om9CPLYdK3l93GauKrq5WXo/gbcD+1CeqFpobRLLkB4= status : UP endpoint : 2001:db8:3c4d:20::2:51822 latest handshake : 2025-12-09T22:51:38+00:00 transfer tx : 1812 bytes transfer rx : 428 bytes in-octets : 1752 out-octets : 3224 admin@server:/>
1 parent 97f4638 commit f78460e

38 files changed

+2217
-14
lines changed

board/aarch64/linux_defconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG=y
244244
CONFIG_NETDEVICES=y
245245
CONFIG_BONDING=m
246246
CONFIG_DUMMY=m
247+
CONFIG_WIREGUARD=m
247248
CONFIG_MACVLAN=m
248249
CONFIG_MACVTAP=m
249250
CONFIG_IPVLAN=m

board/x86_64/linux_defconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG=y
191191
CONFIG_NETDEVICES=y
192192
CONFIG_BONDING=m
193193
CONFIG_DUMMY=m
194+
CONFIG_WIREGUARD=m
194195
CONFIG_MACVLAN=m
195196
CONFIG_MACVTAP=m
196197
CONFIG_IPVLAN=m

configs/aarch32_defconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ BR2_PACKAGE_OPENSSH=y
8282
BR2_PACKAGE_SOCAT=y
8383
BR2_PACKAGE_TCPDUMP=y
8484
BR2_PACKAGE_WHOIS=y
85+
BR2_PACKAGE_WIREGUARD_TOOLS=y
8586
BR2_PACKAGE_BASH_COMPLETION=y
8687
BR2_PACKAGE_SUDO=y
8788
BR2_PACKAGE_GETENT=y

configs/aarch32_minimal_defconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ BR2_PACKAGE_OPENSSH=y
8282
BR2_PACKAGE_SOCAT=y
8383
BR2_PACKAGE_TCPDUMP=y
8484
BR2_PACKAGE_WHOIS=y
85+
BR2_PACKAGE_WIREGUARD_TOOLS=y
8586
BR2_PACKAGE_BASH_COMPLETION=y
8687
BR2_PACKAGE_SUDO=y
8788
BR2_PACKAGE_GETENT=y

configs/aarch64_defconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ BR2_PACKAGE_TCPDUMP=y
102102
BR2_PACKAGE_TRACEROUTE=y
103103
BR2_PACKAGE_ULOGD=y
104104
BR2_PACKAGE_WHOIS=y
105+
BR2_PACKAGE_WIREGUARD_TOOLS=y
105106
BR2_PACKAGE_BASH_COMPLETION=y
106107
BR2_PACKAGE_NEOFETCH=y
107108
BR2_PACKAGE_SUDO=y

configs/aarch64_minimal_defconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ BR2_PACKAGE_OPENSSH=y
8585
BR2_PACKAGE_SOCAT=y
8686
BR2_PACKAGE_TCPDUMP=y
8787
BR2_PACKAGE_WHOIS=y
88+
BR2_PACKAGE_WIREGUARD_TOOLS=y
8889
BR2_PACKAGE_BASH_COMPLETION=y
8990
BR2_PACKAGE_SUDO=y
9091
BR2_PACKAGE_KMOD_TOOLS=y

configs/x86_64_defconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ BR2_PACKAGE_TCPDUMP=y
9898
BR2_PACKAGE_TRACEROUTE=y
9999
BR2_PACKAGE_ULOGD=y
100100
BR2_PACKAGE_WHOIS=y
101+
BR2_PACKAGE_WIREGUARD_TOOLS=y
101102
BR2_PACKAGE_BASH_COMPLETION=y
102103
BR2_PACKAGE_NEOFETCH=y
103104
BR2_PACKAGE_SUDO=y

configs/x86_64_minimal_defconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ BR2_PACKAGE_OPENSSH=y
8080
BR2_PACKAGE_SOCAT=y
8181
BR2_PACKAGE_TCPDUMP=y
8282
BR2_PACKAGE_WHOIS=y
83+
BR2_PACKAGE_WIREGUARD_TOOLS=y
8384
BR2_PACKAGE_BASH_COMPLETION=y
8485
BR2_PACKAGE_SUDO=y
8586
BR2_PACKAGE_GETENT=y

doc/tunnels.md

Lines changed: 331 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,3 +210,334 @@ non-standard VXLAN ports.
210210
> [!NOTE]
211211
> VXLAN tunnels also support the `ttl` and `tos` settings described in
212212
> the [Advanced Tunnel Settings](#advanced-tunnel-settings) section above.
213+
214+
## WireGuard VPN
215+
216+
WireGuard is a modern, high-performance VPN protocol that uses state-of-the-art
217+
cryptography. It is significantly simpler and faster than traditional VPN
218+
solutions like IPsec or OpenVPN, while maintaining strong security guarantees.
219+
220+
Key features of WireGuard:
221+
222+
- **Simple Configuration:** Minimal settings required compared to IPsec
223+
- **High Performance:** Runs in kernel space with efficient cryptography
224+
- **Strong Cryptography:** Uses Curve25519, ChaCha20, Poly1305, and BLAKE2
225+
- **Roaming Support:** Seamlessly handles endpoint IP address changes
226+
- **Dual-Stack:** Supports IPv4 and IPv6 for both tunnel endpoints and traffic
227+
228+
> [!TIP]
229+
> If you name your WireGuard interface `wgN`, where `N` is a number, the
230+
> CLI infers the interface type automatically.
231+
232+
### Key Management
233+
234+
WireGuard uses public-key cryptography similar to SSH. Each WireGuard interface
235+
requires a private key, and each peer is identified by its public key.
236+
237+
**Generate a WireGuard key pair using the `wg` command:**
238+
239+
```bash
240+
admin@example:~$ wg genkey | tee privatekey | wg pubkey > publickey
241+
admin@example:~$ cat privatekey
242+
aMqBvZqkSP5JrqBvZqkSP5JrqBvZqkSP5JrqBvZqkSP=
243+
admin@example:~$ cat publickey
244+
bN1CwZ1lTP6KsrCwZ1lTP6KsrCwZ1lTP6KsrCwZ1lTP=
245+
```
246+
247+
This generates a private key, saves it to `privatekey`, derives the public key,
248+
and saves it to `publickey`.
249+
250+
**Import the private key into the keystore:**
251+
252+
```
253+
admin@example:/> configure
254+
admin@example:/config/> edit keystore asymmetric-key wg-site-a
255+
admin@example:/config/keystore/asymmetric-key/wg-site-a/> set public-key-format x25519-public-key-format
256+
admin@example:/config/keystore/asymmetric-key/wg-site-a/> set private-key-format x25519-private-key-format
257+
admin@example:/config/keystore/asymmetric-key/wg-site-a/> set public-key bN1CwZ1lTP6KsrCwZ1lTP6KsrCwZ1lTP6KsrCwZ1lTP=
258+
admin@example:/config/keystore/asymmetric-key/wg-site-a/> set private-key aMqBvZqkSP5JrqBvZqkSP5JrqBvZqkSP5JrqBvZqkSP=
259+
admin@example:/config/keystore/asymmetric-key/wg-site-a/> leave
260+
admin@example:/>
261+
```
262+
263+
**Import peer public keys into the truststore:**
264+
265+
```
266+
admin@example:/> configure
267+
admin@example:/config/> edit truststore public-key-bag wg-peers public-key peer-b
268+
admin@example:/config/truststore/…/peer-b/> set public-key-format x25519-public-key-format
269+
admin@example:/config/truststore/…/peer-b/> set public-key PEER_PUBLIC_KEY_HERE
270+
admin@example:/config/truststore/…/peer-b/> leave
271+
admin@example:/>
272+
```
273+
274+
> [!IMPORTANT]
275+
> Keep private keys secure! Never share your private key. Only exchange
276+
> public keys with peers. Delete the `privatekey` file after importing it
277+
> into the keystore.
278+
279+
### Point-to-Point Configuration
280+
281+
A basic WireGuard tunnel between two sites:
282+
283+
**Site A configuration:**
284+
285+
```
286+
admin@siteA:/> configure
287+
admin@siteA:/config/> edit interface wg0
288+
admin@siteA:/config/interface/wg0/> set wireguard listen-port 51820
289+
admin@siteA:/config/interface/wg0/> set wireguard private-key wg-site-a
290+
admin@siteA:/config/interface/wg0/> set ipv4 address 10.0.0.1 prefix-length 24
291+
admin@siteA:/config/interface/wg0/> edit wireguard peer wg-peers peer-b
292+
admin@siteA:/config/interface/wg0/wireguard/peer/…/> set endpoint 203.0.113.2
293+
admin@siteA:/config/interface/wg0/wireguard/peer/…/> set endpoint-port 51820
294+
admin@siteA:/config/interface/wg0/wireguard/peer/…/> set allowed-ips 10.0.0.2/32
295+
admin@siteA:/config/interface/wg0/wireguard/peer/…/> set persistent-keepalive 25
296+
admin@siteA:/config/interface/wg0/wireguard/peer/…/> leave
297+
admin@siteA:/>
298+
```
299+
300+
**Site B configuration:**
301+
302+
```
303+
admin@siteB:/> configure
304+
admin@siteB:/config/> edit interface wg0
305+
admin@siteB:/config/interface/wg0/> set wireguard listen-port 51820
306+
admin@siteB:/config/interface/wg0/> set wireguard private-key wg-site-b
307+
admin@siteB:/config/interface/wg0/> set ipv4 address 10.0.0.2 prefix-length 24
308+
admin@siteB:/config/interface/wg0/> edit wireguard peer wg-peers peer-a
309+
admin@siteB:/config/interface/wg0/wireguard/peer/…/> set endpoint 203.0.113.1
310+
admin@siteB:/config/interface/wg0/wireguard/peer/…/> set endpoint-port 51820
311+
admin@siteB:/config/interface/wg0/wireguard/peer/…/> set allowed-ips 10.0.0.1/32
312+
admin@siteB:/config/interface/wg0/wireguard/peer/…/> set persistent-keepalive 25
313+
admin@siteB:/config/interface/wg0/wireguard/peer/…/> leave
314+
admin@siteB:/>
315+
```
316+
317+
This creates an encrypted tunnel with Site A at 10.0.0.1 and Site B at 10.0.0.2.
318+
319+
### Understanding Allowed IPs
320+
321+
The `allowed-ips` setting in WireGuard serves two critical purposes:
322+
323+
1. **Ingress Filtering:** Only packets with source IPs in the allowed list
324+
are accepted from the peer
325+
2. **Cryptokey Routing:** Determines which peer receives outbound packets
326+
for a given destination
327+
328+
Think of `allowed-ips` as a combination of firewall rules and routing table.
329+
330+
For a simple point-to-point tunnel, you typically allow only the peer's
331+
tunnel IP address (e.g., `10.0.0.2/32`). For site-to-site VPNs connecting
332+
entire networks, include the remote network prefixes:
333+
334+
```
335+
admin@siteA:/config/interface/wg0/wireguard/peer/…/> set allowed-ips 10.0.0.2/32
336+
admin@siteA:/config/interface/wg0/wireguard/peer/…/> set allowed-ips 192.168.2.0/24
337+
```
338+
339+
This allows traffic to/from the peer at 10.0.0.2 and routes traffic destined
340+
for 192.168.2.0/24 through this peer.
341+
342+
> [!NOTE]
343+
> When routing traffic to networks behind WireGuard peers, you also need
344+
> to configure static routes pointing to the WireGuard interface. See
345+
> [Static Routes](networking.md#static-routes) for more information.
346+
347+
### Hub-and-Spoke Topology
348+
349+
WireGuard excels at hub-and-spoke (star) topologies where multiple remote
350+
sites connect to a central hub.
351+
352+
**Hub configuration:**
353+
354+
```
355+
admin@hub:/> configure
356+
admin@hub:/config/> edit interface wg0
357+
admin@hub:/config/interface/wg0/> set wireguard listen-port 51820
358+
admin@hub:/config/interface/wg0/> set wireguard private-key wg-hub
359+
admin@hub:/config/interface/wg0/> set ipv4 address 10.0.0.1 prefix-length 24
360+
admin@hub:/config/interface/wg0/> end
361+
362+
# Spoke 1
363+
admin@hub:/config/> edit interface wg0 wireguard peer wg-peers spoke1
364+
admin@hub:/config/interface/wg0/wireguard/peer/…/> set allowed-ips 10.0.0.2/32
365+
admin@hub:/config/interface/wg0/wireguard/peer/…/> set allowed-ips 192.168.1.0/24
366+
admin@hub:/config/interface/wg0/wireguard/peer/…/> end
367+
368+
# Spoke 2
369+
admin@hub:/config/> edit interface wg0 wireguard peer wg-peers spoke2
370+
admin@hub:/config/interface/wg0/wireguard/peer/…/> set allowed-ips 10.0.0.3/32
371+
admin@hub:/config/interface/wg0/wireguard/peer/…/> set allowed-ips 192.168.2.0/24
372+
admin@hub:/config/interface/wg0/wireguard/peer/…/> leave
373+
admin@hub:/>
374+
375+
# Add routes for spoke networks
376+
admin@hub:/> configure
377+
admin@hub:/config/> edit routing control-plane-protocol static name default
378+
admin@hub:/config/routing/…/static/> set ipv4 route 192.168.1.0/24 wg0
379+
admin@hub:/config/routing/…/static/> set ipv4 route 192.168.2.0/24 wg0
380+
admin@hub:/config/routing/…/static/> leave
381+
admin@hub:/>
382+
```
383+
384+
**Spoke 1 configuration:**
385+
386+
```
387+
admin@spoke1:/> configure
388+
admin@spoke1:/config/> edit interface wg0
389+
admin@spoke1:/config/interface/wg0/> set wireguard listen-port 51820
390+
admin@spoke1:/config/interface/wg0/> set wireguard private-key wg-spoke1
391+
admin@spoke1:/config/interface/wg0/> set ipv4 address 10.0.0.2 prefix-length 24
392+
admin@spoke1:/config/interface/wg0/> edit wireguard peer wg-peers hub
393+
admin@spoke1:/config/interface/wg0/wireguard/peer/…/> set endpoint 203.0.113.1
394+
admin@spoke1:/config/interface/wg0/wireguard/peer/…/> set endpoint-port 51820
395+
admin@spoke1:/config/interface/wg0/wireguard/peer/…/> set allowed-ips 10.0.0.1/32
396+
admin@spoke1:/config/interface/wg0/wireguard/peer/…/> set allowed-ips 10.0.0.3/32
397+
admin@spoke1:/config/interface/wg0/wireguard/peer/…/> set allowed-ips 192.168.0.0/24
398+
admin@spoke1:/config/interface/wg0/wireguard/peer/…/> set allowed-ips 192.168.2.0/24
399+
admin@spoke1:/config/interface/wg0/wireguard/peer/…/> set persistent-keepalive 25
400+
admin@spoke1:/config/interface/wg0/wireguard/peer/…/> end
401+
admin@spoke1:/config/> edit routing control-plane-protocol static name default
402+
admin@spoke1:/config/routing/…/static/> set ipv4 route 192.168.0.0/24 wg0
403+
admin@spoke1:/config/routing/…/static/> set ipv4 route 192.168.2.0/24 wg0
404+
admin@spoke1:/config/routing/…/static/> leave
405+
admin@spoke1:/>
406+
```
407+
408+
This configuration allows Spoke 1 to reach both the hub network (192.168.0.0/24)
409+
and Spoke 2's network (192.168.2.0/24) via the hub, enabling spoke-to-spoke
410+
communication through the central hub.
411+
412+
### Persistent Keepalive
413+
414+
The `persistent-keepalive` setting sends periodic packets to keep the tunnel
415+
active through NAT devices and firewalls:
416+
417+
```
418+
admin@example:/config/interface/wg0/wireguard/peer/…/> set persistent-keepalive 25
419+
```
420+
421+
This is particularly important when:
422+
423+
- The peer is behind NAT
424+
- Intermediate firewalls have connection timeouts
425+
- You need the tunnel to remain ready for bidirectional traffic
426+
427+
A value of 25 seconds is recommended for most scenarios. Omit this setting
428+
for peers with public static IPs that initiate connections.
429+
430+
> [!NOTE]
431+
> Only the peer behind NAT needs `persistent-keepalive` configured. The
432+
> peer with a public IP learns the NAT endpoint from incoming packets.
433+
434+
### IPv6 Endpoints
435+
436+
WireGuard fully supports IPv6 for tunnel endpoints:
437+
438+
```
439+
admin@example:/> configure
440+
admin@example:/config/> edit interface wg0
441+
admin@example:/config/interface/wg0/> set wireguard listen-port 51820
442+
admin@example:/config/interface/wg0/> set wireguard private-key wg-key
443+
admin@example:/config/interface/wg0/> set ipv4 address 10.0.0.1 prefix-length 24
444+
admin@example:/config/interface/wg0/> set ipv6 address fd00::1 prefix-length 64
445+
admin@example:/config/interface/wg0/> edit wireguard peer wg-peers remote
446+
admin@example:/config/interface/wg0/wireguard/peer/…/> set endpoint 2001:db8::2
447+
admin@example:/config/interface/wg0/wireguard/peer/…/> set endpoint-port 51820
448+
admin@example:/config/interface/wg0/wireguard/peer/…/> set allowed-ips 10.0.0.2/32
449+
admin@example:/config/interface/wg0/wireguard/peer/…/> set allowed-ips fd00::2/128
450+
admin@example:/config/interface/wg0/wireguard/peer/…/> leave
451+
admin@example:/>
452+
```
453+
454+
WireGuard can carry both IPv4 and IPv6 traffic regardless of whether the
455+
tunnel endpoints use IPv4 or IPv6.
456+
457+
### Dynamic Endpoints (Road Warriors)
458+
459+
For mobile clients or peers without fixed IPs, omit the `endpoint` setting.
460+
WireGuard learns the peer's endpoint from authenticated incoming packets:
461+
462+
```
463+
admin@hub:/> configure
464+
admin@hub:/config/> edit interface wg0 wireguard peer wg-peers mobile-client
465+
admin@hub:/config/interface/wg0/wireguard/peer/…/> set allowed-ips 10.0.0.10/32
466+
admin@hub:/config/interface/wg0/wireguard/peer/…/> leave
467+
admin@hub:/>
468+
```
469+
470+
The mobile client configures the hub's endpoint normally. The hub learns
471+
and tracks the mobile client's changing IP address automatically.
472+
473+
### Monitoring WireGuard Status
474+
475+
Check WireGuard interface status and peer connections:
476+
477+
```
478+
admin@example:/> show interfaces
479+
wg0 wireguard UP 2 peers (1 up)
480+
ipv4 10.0.0.1/24 (static)
481+
ipv6 fd00::1/64 (static)
482+
483+
admin@example:/> show interfaces wg0
484+
name : wg0
485+
type : wireguard
486+
index : 12
487+
operational status : up
488+
peers : 2
489+
490+
Peer 1:
491+
status : UP
492+
endpoint : 203.0.113.2:51820
493+
latest handshake : 2025-12-09T10:23:45+0000
494+
transfer tx : 125648 bytes
495+
transfer rx : 98432 bytes
496+
497+
Peer 2:
498+
status : DOWN
499+
endpoint : 203.0.113.3:51820
500+
latest handshake : 2025-12-09T09:15:22+0000
501+
transfer tx : 45120 bytes
502+
transfer rx : 32768 bytes
503+
```
504+
505+
The connection status shows `UP` if a handshake occurred within the last 3
506+
minutes, indicating an active tunnel. The `latest handshake` timestamp shows
507+
when the peers last successfully authenticated and exchanged keys.
508+
509+
### Post-Quantum Security (Preshared Keys)
510+
511+
For additional security against future quantum computers, WireGuard supports
512+
preshared keys that provide post-quantum resistance.
513+
514+
**Generate a preshared key using `wg genpsk`:**
515+
516+
```bash
517+
admin@example:~$ wg genpsk > preshared.key
518+
admin@example:~$ cat preshared.key
519+
cO2DxZ2mUQ7LtsrDxZ2mUQ7LtsrDxZ2mUQ7LtsrDxZ2m=
520+
```
521+
522+
**Import the preshared key into the keystore:**
523+
524+
```
525+
admin@example:/> configure
526+
admin@example:/config/> edit keystore symmetric-key wg-psk
527+
admin@example:/config/keystore/symmetric-key/wg-psk/> set key-format wireguard-symmetric-key-format
528+
admin@example:/config/keystore/symmetric-key/wg-psk/> set key cO2DxZ2mUQ7LtsrDxZ2mUQ7LtsrDxZ2mUQ7LtsrDxZ2m=
529+
admin@example:/config/keystore/symmetric-key/wg-psk/> end
530+
admin@example:/config/> edit interface wg0 wireguard peer wg-peers remote
531+
admin@example:/config/interface/wg0/wireguard/peer/…/> set preshared-key wg-psk
532+
admin@example:/config/interface/wg0/wireguard/peer/…/> leave
533+
admin@example:/>
534+
```
535+
536+
The preshared key must be securely shared between both peers and configured
537+
on both sides. This provides an additional layer of symmetric encryption
538+
alongside the Curve25519 key exchange.
539+
540+
> [!IMPORTANT]
541+
> Preshared keys must be kept secret and exchanged through a secure channel,
542+
> just like passwords. Delete the `preshared.key` file after importing it
543+
> into both peer keystores.

0 commit comments

Comments
 (0)