Wireguard, having been accepted into dkms is a simple, quick and easy to deploy VPN standard which, in all of my own testing, has dramatically outperformed OpenVPN and IPSEC.
I run my Datacenters on Proxmox 6 VE and I prefer to deploy all appliances as LXC Containers to simplify management. I also prefer LXC over VM for the resource overhead and I default to Debian for all my LXC Containers.
As Wireguard runs in Kernel, this means that you will need to enable the relevant mods on the host (Due to running LXC), if you intend to use this solution on bare-metal or in a full VM, you can just perform the Host configurations tasks directly on the VM or bare-metal server.
Note that this only applies to Proxmox VE6, as of Proxmox VE7 (Based on Debian 11), the Wireguard Kernel Modules do not require backports, additionally, Debian 11 routing tables differ, hence, if you are using Debian 11 or Proxmox 7, use the newer guide Here.
This how-to assumes that you are running as root, if you are not root, append sudo in front of all commands.
Host site IPv4 Subnet | 192.168.0.0/24 |
Remote Site IPv4 Subnet | 192.168.1.0/24 |
VPN Tunnel IPv4 Subnet | 10.10.10.0/24 |
Host Site Wireguard Server IPv4 Address | 192.168.0.1 |
Remote Site Wireguard Server IPv4 Address | 192.168.1.1 |
Gateways at each site configured to forward the other site’s subnet trafic to that site’s Wireguard Server |
- Set Static Routes:
-
At Host Site:
route -P add 192.168.1.0/24 192.168.0.1
-
At Remote Site:
route -P add 192.168.0.0/24 192.168.1.1
-
- For diagnostic purposes, the tunnel subnet can also be added to the routing tables at each site:
-
At Host Site:
route -P add 10.0.0.0/24 192.168.0.1
-
At Remote Site:
route -P add 10.0.0.0/24 192.168.1.1
-
Step 1 – Configuring the Proxmox VE Host (Or the VM, assuming Proxmox VE6 or Debian 10)
-
Make sure that you are running the latest updates:
apt update && apt upgrade -y
-
Install the Kernel Headers to enable Wireguard on the Host, note, as Wireguard runs in Kernel, it must be enabled on the Host for LXC Containers to gain access to the Kernel:
apt install pve-headers
-
Add the backports repository to Debian:
sh -c "echo 'deb http://deb.debian.org/debian buster-backports main contrib non-free' > /etc/apt/sources.list.d/buster-backports.list"
cat /etc/apt/sources.list.d/buster-backports.list
apt update
-
Install the DKMS for Wireguard from the backports repository:
apt install -t buster-backports wireguard-dkms
-
Enable Wireguard Kernel Module
modprobe wireguard
-
There should be no output if modprobe succeeds, if it fails it will inform you, another method is to use the lsmod command to list all available kernel modules
echo "wireguard" >> /etc/modules-load.d/modules.conf
-
Step 2 – Network Prep
- The LXC Container (VM or Bare-Metal Installation) which will server as your primary VPN Server should be accessible via the internet with a fixed address, wither a static IPv4 address or with proper router configuration a DynDNS address, in our case a static IPv4 of 196.196.196.196.
- On your router, ensure that you have set up port forwarding to the internal IP address of the LXC Container (VM or Bare-Metal Installation) for the port you choose to use, in this example we use port 7777.
- Ensure that you have set up a manual route on your routers at each site for all traffic intended for the destination subnet (In our example 192.168.0.0/24 for the host site and 192.168.1.0/24 for the remote site) so that it is routed to the internal IP address of the LXC Container (VM or Bare-Metal Installation), in our case 192.168.0.1 for the host site and 192.168.1.1 for the remote site.
Step 3 – VPN Host Site LXC Container (VM or Bare-Metal Installation)
- Ensure that you are updated and have packports enabled (See Step 1 above and repeat points 1 and 3 only of it is on an LXC Container, if on a VM or Bare-Metal you can skip this point and continue to point 2.
-
Install Wireguard Tools and enable IPv4 forwarding:
apt install --no-install-recommends wireguard-tools iptables
nano /etc/sysctl.conf
-
uncomment net.ipv4.ip_forward=1 (Delete the preceeding #)
sysctl -p
- The system should respond with “net.ipv4.ip_forward=1
-
-
Restart to ensure that the Kernel Modules are loaded:
reboot
-
Generate keys:
cd /etc/wireguard
umask 077
wg genkey | tee privatekey | wg pubkey > publickey
-
Make notes of what your Private and Public Keys are:
nano privatekey
-
write down the entire key, you will need it to configure the VPN Server
nano publickey
- write down the entire key, you will need it to configure the VPN Client
-
-
Configure a network interface for Wireguard to use and configure it with your tunnel IP address (In our example 10.0.0.1, this IP range should be outside of your server and client IP ranges):
ip link add dev wg0 type wireguard
ip address add dev wg0 10.0.0.1/24
-
Configure Wireguard settings:
nano wg0.conf
- edit the config file to resemble the following, use the Private Key generated at point 5:
- The [Interface] block refers to the configuration of the specific node.
Address is the specific IPv4 address for the virtual node and should be unique for each wireguard peer, remaining within the same subnet.
ListenPort referst to the port on which the Wireguard server node will listen for connections.
PrivateKey refers to the private key generated at point 5 and is unique to each instance.
PostUp and PostDown are the specific instructions which will allow the Wireguard server to route traffic from the local network(s) over the VPN tunnel with PostUp enabling NAT routing after the tunnel is created and PostDown disabling NAT routing before the tunnel goes down.
The [Peer] block is configured for each other connection to the Wireguard server. You can configure as many peers as you require.
PublicKey is the one generated from step 4 and is unique for each peer.
AllowedIPs refers to the subnets which will be allowed to communicate via the peer tunnel.
- The [Interface] block refers to the configuration of the specific node.
- edit the config file to resemble the following, use the Private Key generated at point 5:
[Interface]
Address = 10.0.0.1/24
ListenPort = 7777
PrivateKey = <Your Servers Private Key From Point 5>
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
[Peer]
PublicKey = <Your Client Public Key from Step 4>
AllowedIPs = 10.0.0.2/24, 192.168.1.0/24, 192.168.0.0/24
-
Enable daemons from the Kernel Headers:
systemctl enable --now systemd-resolvd
-
Reboot the system:
reboot
-
Enable the wg-quick@wg0 daemon:
systemctl enable wg-quick@wg0 --now
Step 4 – VPN Remote Site LXC Container (VM or Bare-Metal Installation)
- Ensure that you are updated and have packports enabled (See Step 1 above and repeat points 1 and 3 only of it is on an LXC Container, if on a VM or Bare-Metal you can skip this point and continue to point 2.
-
Install Wireguard Tools and enable IPv4 forwarding:
apt update && apt install --no-install-recommends wireguard-tools iptables -y
nano /etc/sysctl.conf
-
uncomment net.ipv4.ip_forward=1 (Delete the preceeding #)
sysctl -p
-
- The system should respond with “net.ipv4.ip_forward=1
-
Restart to ensure that the Kernel Modules are loaded:
reboot
-
Generate keys:
cd /etc/wireguard
umask 077
wg genkey | tee privatekey | wg pubkey > publickey
-
Make notes of what your Private and Public Keys are:
nano privatekey
-
write down the entire key, you will need it to configure the VPN Server
nano publickey
- write down the entire key, you will need it to configure the VPN Client
-
-
Configure a network interface for Wireguard to use and configure it with your tunnel IP address (In our example 10.0.0.2, this IP range should be outside of your server and client IP ranges):
ip link add dev wg0 type wireguard
ip address add dev wg0 10.0.0.2/24
-
Configure Wireguard settings:
nano wg0.conf
- edit the config file to resemble the following, use the Private Key generated at point 5:
[Interface]
Address = 10.0.0.2/24
PrivateKey = <Your Servers Private Key From Point 5>
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
[Peer]
Endpoint = 196.196.196.196:7777
PublicKey = <Your Server Public Key from Step 3>
AllowedIPs = 10.0.0.1/24, 192.168.0.0/24, 192.168.1.0/24
PersistentKeepalive = 25
-
Enable daemons from the Kernel Headers:
systemctl enable --now systemd-resolvd
-
Reboot the system:
reboot
-
Enable the wg-quick@wg0 daemon:
systemctl enable wg-quick@wg0 --now
Step 5 – Testing
Wireguard should immediately make the connection and, assuming your routing inside of your network is correct, you should be able to ping an IP address at the remote site.
Leave a Reply