Wireguard - an extremely simple yet fast and modern VPN
Wireguard is an extremely simple yet fast and modern VPN that utilizes state-of-the-art cryptography. It can be a useful replacement for IPSec or OpenVPN.
Official website: https://www.wireguard.io/
# echo "deb http://deb.debian.org/debian/ unstable main" > /etc/apt/sources.list.d/unstable-wireguard.list # printf 'Package: *\nPin: release a=unstable\nPin-Priority: 150\n' > /etc/apt/preferences.d/limit-unstable # apt update # apt install wireguard
Step 1 - Generating Keypairs
To generate key pairs, use:
# wg genkey | tee wg-private.key | wg pubkey > wg-public.key
Make sure that you protect the wg-private.key file, e.g. via appropriate file permissions.
Step 2 - Alternative A - Manual Configuration
Step 2 - Alternative B - /etc/network/interfaces
The following configuration examples focus on using /etc/network/interfaces as much as possible.
For a server, configuration based on /etc/network/interfaces is often the preferred way.
This example builds a simple point-to-point tunnel between two machines.
# /etc/network/interfaces auto wg-p2p iface wg-p2p inet static address 10.88.88.1 netmask 255.255.255.0 pre-up ip link add $IFACE type wireguard pre-up wg setconf $IFACE /etc/wireguard/$IFACE.conf post-down ip link del $IFACE iface wg-p2p inet6 static address 2001:db8:1234:5678::1 netmask 64
# /etc/wireguard/wg-p2p.conf [Interface] PrivateKey = <paste the private key of the local host here> ListenPort = <enter a port number to use for Wireguard UDP data, 51820 seems common> [Peer] Endpoint = <remote IP>:<remote port> PublicKey = <paste the public key of the remote host here> AllowedIPs = 0.0.0.0/0, ::/0
You can then simply add routes through the tunnel, either statically, or dynamically using e.g. OSPF or BGP. For static routes:
# ip route add 2001:db8:4242::/48 dev wg-demo # ip route add 192.168.42.0/24 dev wg-demo
VPN client with default route
This allows a "client" to connect to a server, and redirect its default route through the tunnel. This example uses wg-quick, make sure you understand what it does to your routing tables!
# /etc/network/interfaces auto wg-client iface wg-client inet static address 10.88.88.1 netmask 255.255.255.0 pre-up wg-quick up $IFACE post-down wg-quick down $IFACE
# /etc/wireguard/wg-client.conf [Interface] PrivateKey = <paste the private key of the local host here> ListenPort = <enter a port number to use for Wireguard UDP data, 51820 seems common> [Peer] Endpoint = <server IP>:<server port> PublicKey = <paste the public key of the remote host here> AllowedIPs = 0.0.0.0/0, ::/0
Step 2 - Alternative C - systemd
First, create a systemd.netdev(5) file ending in .netdev and place it in /etc/systemd/network, for example as /etc/systemd/network/wg0.netdev:
[NetDev] Name=wg0 Kind=wireguard Description=Wireguard test [WireGuard] PrivateKey=<paste the private key of the local host here> ListenPort=<enter a port number to use for Wireguard UDP data, 51820 seems common> [WireGuardPeer] PublicKey=<paste the public key of the remote host here> AllowedIPs=0.0.0.0/0 AllowedIPs=::/0 Endpoint=<remote IP or hostname>:<remote port>
Note that the above example assumes that you are setting up a "client" to connect to a server. If you are instead setting up a server, you probably want much more restricted AllowedIPs entries. Also, on a server you would typically have several WireGuardPeer sections.
The .netdev file contains security-sensitive data (the private key) and should have appropriate file permissions:
# chown root.systemd-network /etc/systemd/network/wg0.netdev # chmod 0640 /etc/systemd/network/wg0.netdev
Second, create a matching systemd.network(5) file ending in .network and place it in /etc/systemd/network, for example as /etc/systemd/network/wg0.network:
[Match] Name=wg0 [Network] Address=10.88.88.1/24 Address=2001:db8:1234:5678::1
# systemctl daemon-reload # systemctl start systemd-networkd
Step 3 - Check the end result
You can check the status of your new interface by using e.g.:
# ip addr show dev wg0 # wg show wg0
And, if you've let systemd create the interface, by using:
# networkctl status wg0