Skip to main content

setup wireguard vpn

WireGuard is a fast, easy to configure VPN. If you have at least one node with a public IP all devices will be able to communicate with each other regardless of NAT or port forwards. The setup below has three nodes, one VPS node with a public IP and two additional nodes, both behind NAT.

Stage 1: Install WireGuard on our clients.

I'm not going to re-produce the install procedure, WireGuard have very good documentation available here. I installed on three systems, two Ubuntu 19.10 Servers and one CentOS 8.

  • ubnt-01 (Local VM)
  • ubnt-02 (VPS with WAN IP)
  • cent-01 (Local VM)

Once installed you can run sudo wg to check if it's installed, you will get an error if it's not.

Stage 2: Generate our public and private keys on the three nodes.

Now we need to generate our keys for WireGuard to use. The same process can be used on the three nodes (substituting the server name in my example below). Make sure to secure them. I create a .wg folder in my home folder but you can create and store then where ever you wish, we will be copying the content of the keys to the config files later so the files themselves do not need to be saved in any particular location.

mkdir .wg
cd .wg
wg genkey | tee ubnt-01.pri | wg pubkey >
chmod 600 ubnt-01*

Stage 3: Create our WireGuard config on each server.

You should now have three sets of keys, one on each server. We now create the config file on each server, we also make sure the config file is not world readable. We'll call the interface wg0 in the example below. We use the range for our WireGuard network.

First we have the config for the server with the WAN IP:

sudo vi /etc/wireguard/wg0.conf
sudo chmod 600 /etc/wireguard/wg0.conf

# This is our external node config, the IP and port it will use and the private key (just cat the contents)
Address =
ListenPort = 51820 # Server Listening Wireguard Port
PrivateKey = mBtIxxxxxxxxxxxxxxxxxxxxxxxxxxzdlc=

# Now we enter the other clients in the network
# ubnt-01 - Laptop
PublicKey = 7QG7xxxxxxxxxxxxxxxxxxxxxxxxxx/2u1X8=
AllowedIPs =

# cent-01 - Home VM
PublicKey = +ClxNxxxxxxxxxxxxxxxxxxxxxxxxxxp9nY=
AllowedIPs =

Then we have the config for our clients behind NAT:

sudo vi /etc/wireguard/wg0.conf
sudo chmod 600 /etc/wireguard/wg0.conf

# This is our ubnt-01 config, the IP it will use and the private key (just cat the contents)
Address =
PrivateKey = UIzxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxgpPXY=

# This is the ubnt-02 config which in our case is the external device with a WAN IP
PublicKey = HtWVExxxxxxxxxxxxxxxxxxxxxxxxxxxxx5+fl0=
## All traffic to this range will be sent to this peer
AllowedIPs =
Endpoint =
## Use if you wish to keep connection to server alive e.g. if client is behind NAT
PersistentKeepalive = 25

Stage 4: Bring up our WireGuard VPN and test.

Now we need to start the WireGuard connection on each node, we also set it to start automatically. Finally we can use the wg command to see the status of our network.

sudo wg-quick up wg0
sudo systemctl enable wg-quick@wg0

Now on the server if we check sudo wg we can see the status of all the nodes.

If we check sudo wg on one of the nodes behind nat we can just see the server status.

However on that same node we can ping any of the other nodes.

  • Note depending on the server you might need to enable IP Forwarding, one way to do this is check cat /proc/sys/net/ipv4/ip_forward and if not set to 1 run: echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward
  • After a recent update my WireGuard server stopped forwarding traffic so I also had to add the following line net.ipv4.ip_forward=1 to /etc/sysctl.conf
  • Recently switched my server to Ubuntu with UFW enabled so I had to add an additional rule to allow peer to peer traffic sudo ufw route allow in on wg0 out on wg0 Prior to enabling this I could ping from peer to peer but could not access services (ssh, vnc etc.) between peers.