Introduction
WireGuard is a modern, fast, and secure VPN tunneling protocol that can be used to establish encrypted tunnels between machines to create private networks. It aims to be simpler, leaner, and more performant than older VPN protocols like IPsec and OpenVPN.
In this guide, we will walk through the full process of setting up WireGuard on Debian or Ubuntu Linux servers. This will allow you to create encrypted connections between servers, route traffic through VPN tunnels, and essentially create a virtual private network.
We will cover:
- Installing WireGuard
- Generating Keys and Configuration
- Creating Interfaces and Peers
- Routing Traffic Through the VPN Tunnel
- Permanent IP Addressing
- Enabling IP Forwarding
- NAT for Allowing Connections from Remote Peers
- Systemd Integration and Start on Boot
By the end, you should have a fully functioning WireGuard setup on Debian or Ubuntu that can securely tunnel traffic between servers.
Prerequisites
Before we get started, there are a few prerequisites:
- Debian 10 or higher, or Ubuntu 18.04 or higher on all machines
- Root access (sudo privileges) on all machines
- A basic understanding of Linux networking (IP addresses, subnets, routing, etc)
The setup will be done on two or more machines that can communicate over a network. For testing purposes, you can use local VMs, servers, or cloud machines.
The instructions will work for setting up WireGuard between any endpoints – it does not have to be just Debian/Ubuntu servers. WireGuard clients are available for all major platforms.
Installing WireGuard
The first step is to install the WireGuard package on all the machines that will be part of the VPN tunnel.
On Debian
$ sudo apt update
$ sudo apt install wireguard
On Ubuntu
$ sudo apt update
$ sudo apt install wireguard
This will install the WireGuard module and userspace tools like wg and wg-quick.
Generating Keys and Configuration
Now we need to generate the public/private key pairs that will be used by WireGuard to establish the encrypted tunnels. Each machine participating in the VPN will need its own private key and a corresponding public key.
Generate the private key with:
$ wg genkey > privatekey
This will create a new private key and save it to privatekey.
Next, generate the public key:
$ wg pubkey < privatekey > publickey
Do this for each server that will be part of the VPN. Make sure to safely store the private key file on each machine. The public key can be freely shared.
Next we need to generate a configuration file that specifies the interface, peers/endpoints, and keys.
Create a file called wg0.conf:
$ sudo nano /etc/wireguard/wg0.conf
Add the following contents, replacing the PublicKey and PrivateKey with your own for each server:
[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = SERVER1_PRIVATE_KEY
[Peer]
PublicKey = SERVER2_PUBLIC_KEY
AllowedIPs = 10.0.0.2/32
So for two servers, you may have:
Server 1:
[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = SERVER1_PRIVATE_KEY
[Peer]
PublicKey = SERVER2_PUBLIC_KEY
AllowedIPs = 10.0.0.2/32
Server 2:
[Interface]
Address = 10.0.0.2/24
ListenPort = 51820
PrivateKey = SERVER2_PRIVATE_KEY
[Peer]
PublicKey = SERVER1_PUBLIC_KEY
AllowedIPs = 10.0.0.1/32
The Address and AllowedIPs configure the IP addresses used by the VPN tunnel interface. Make sure any IPs used don’t conflict with your existing network.
The ListenPort and PrivateKey are required in the [Interface] section. Then add a [Peer] section for each server you want to connect to, using its PublicKey.
You can add more peers by adding additional [Peer] sections. Make sure to also add the peer IP to AllowedIPs.
Save the config file and enable IP forwarding (explained below).
Creating Interfaces and Peers
With the configuration in place, we can now create the interface and establish the peer connections:
$ sudo wg-quick up wg0
This will set up the wg0 interface using the details from wg0.conf.
Run the same wg-quick command on each server to bring up their VPN interfaces. The peers will connect using the public keys and begin tunneling traffic.
You can inspect the status of the interface with:
$ sudo wg show
This will display details like the public key, listening port, and peers for the interface.
At this point your WireGuard VPN tunnel is active! Traffic will now flow between the peered servers encrypted over the tunnels.
However, for routing to work properly we need to enable IP forwarding on each server.
Routing Traffic Through the VPN Tunnel
With IP forwarding enabled, traffic can be sent between the WireGuard peers and routed through the encrypted VPN tunnel.
To enable forwarding on Debian/Ubuntu:
$ sudo sysctl -w net.ipv4.ip_forward=1
To make this persistent across reboots:
$ sudo nano /etc/sysctl.conf
Uncomment the line:
net.ipv4.ip_forward=1
Save the file and reboot or run sudo sysctl -p to load the new settings.
Now traffic can be routed between the VPN peers. However, the connection will drop as soon as you restart the server since the wg-quick configuration is not persistent.
To automatically bring up the VPN on boot we need to integrate WireGuard with systemd.
Systemd Integration and Start on Boot
To have WireGuard start on boot and persist across restarts, we need to configure a systemd service.
Create a new systemd service file:
$ sudo nano /etc/systemd/system/[email protected]
Paste in the following:
[Unit]
Description=WireGuard VPN tunnel for %i
After=network-online.target nss-lookup.target
Wants=network-online.target nss-lookup.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/wg-quick up %i
ExecStop=/usr/bin/wg-quick down %i
[Install]
WantedBy=multi-user.target
This will start and stop the VPN tunnel using wg-quick.
Now enable the service:
$ sudo systemctl enable wg-quick@wg0
This will create a systemd service that runs wg-quick on boot.
Reboot your servers and WireGuard should come up automatically! Verify with wg show.
Permanent IP Addressing
By default, the WireGuard peers will use their latest public IP when making connections. If your servers have dynamic IPs, this can cause problems.
To assign permanent static IPs used just for the VPN connections, add a PersistentKeepalive option to the peer sections:
[Peer]
PublicKey = PEER_PUBLIC_KEY
AllowedIPs = 10.0.0.2/32
Endpoint = PEER_PUBLIC_IP:51820
PersistentKeepalive = 25
This will ping the peer every 25 seconds to keep the most recent IP address updated.
You can also explicitly set the endpoint IP like above if the public IP never changes.
NAT for Allowing Connections from Remote Peers
In most cases, you’ll want to allow connections to your VPN server from remote peers/clients over the internet.
This means opening and forwarding the WireGuard listening port (UDP 51820 by default).
If behind a NAT firewall, add these port forwarding rules:
# Forward port 51820 inbound to the WireGuard server
$ iptables -A INPUT -p udp --dport 51820 -j ACCEPT
$ iptables -A FORWARD -i eth0 -o wg0 -j ACCEPT
# Forward traffic from WireGuard server back out to internet
$ iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
You’ll also need to configure port forwarding rules on your router to send inbound UDP 51820 traffic to your WireGuard server.
Now remote peers can connect to your server’s public IP on port 51820 over the internet.
Client Configuration
To connect clients like mobile devices, just install a WireGuard app and use the server’s public IP and public key in the client config.
Here’s an example mobile client config:
[Interface]
PrivateKey = CLIENT_PRIVATE_KEY
Address = 10.0.0.3
[Peer]
PublicKey = SERVER_PUBLIC_KEY
Endpoint = SERVER_PUBLIC_IP:51820
AllowedIPs = 0.0.0.0/0
This will route all client traffic through the VPN tunnel when connected.
And that covers the full setup of WireGuard on Debian and Ubuntu!
Summary
Your Debian or Ubuntu servers should now have encrypted WireGuard tunnels between them. Traffic will be routed through the tunnels, secured by modern cryptography.
WireGuard is fast, simple, and lean compared to alternatives like IPsec or OpenVPN. It makes an ideal VPN for connecting infrastructure securely across the internet.
There are many additional options for tuning and expanding your WireGuard setup as well – refer to the project docs for more details.
I hope this guide was helpful for getting WireGuard set up on your Debian or Ubuntu systems! Let me know if you have any other questions.