@@ -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