Skip to content

VPN with WireGuard

This documentation will guide you in installing a VPN server on a computer or server that is always running on your network. Creating a VPN server with WireGuard is a free solution to securing your web traffic and accessing your home network when you are using public wifi.

1. Prerequisites

Before installing WireGuard on the server, we need to ensure we have our server preconfigured.

1.1 Ensure system up to date

sudo apt update && sudo apt upgrade

1.2 Install package iptables and net-tools

We'll need iptables to ensure our VPN clients can connect to the internet from the VPN. We'll also want net-tools so we can run ifconfig later on.

sudo apt install iptables net-tools

1.3 Enable IP Forwarding

sudo nano /etc/sysctl.conf

Find net.ipv4.ip_forward=1 and net.ipv6.conf.all.forwarding=1 and uncomment these.

Now verify the changes were saved.

sysctl -p

1.4 Check the Network Interface Name

ifconfig

The network interface name can be found with ifconfig. In bold, it is the first word returned on the next line.

root@thomas-HP-Z230-Tower-Workstation:/etc/wireguard# ifconfig
eno1: flags=4163 mtu 1500 ...

For me the value is eno1. Note, you will also see your network IP address on the next line, but likely you'll be using a DDNS instead of your IP address.

2. Install WireGuard on the Server

sudo apt install wireguard

3. Configure WireGuard VPN Server

3.1 Generate a private/public key pair for the Server.

Navigate to the WireGuard folder:

cd /etc/wireguard/

Now let's create the public and private key for the server.

umask 077
wg genkey | tee privatekey | wg pubkey > publickey

Now we need to note both the private key and public key. Print both out and copy them into a text file for later use.

cat privatekey
cat publickey

3.2 Create WireGuard Config File

sudo nano wg0.conf

This file will be created and empty. Go ahead and populate the file with the following:

[Interface]
# A virtual IP address you are giving to your new VPN server
Address = 10.0.0.1/24

# The following PostUp commands take effect upon the startup of the server.  The PostDown commands take effect on shutdown of the server.

# Permit forwarding of packets coming from the WireGuard interface to other interfaces.
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT

# Allow devices connected to the VPN to access the internet through the server's internet connection.
PostUp = iptables -t nat -A POSTROUTING -o [network interface name] -j MASQUERADE

# Delete the rule that allows traffic forwarding from the WireGuard interface 
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT

# Delete the previous rule allowing devices to connect to the internet
PostDown = iptables -t nat -D POSTROUTING -o [network interface name] -j MASQUERAD

# Port on the server for the VPN server to listen on
ListenPort = [Choose a port for the VPN server to run]

# Private key we previously generated
PrivateKey = [Private key previously generated for the VPN server]

Info

Make sure to replace network interface name with the value generated from ifconfig. Mine was eno1.

Go ahead and save and exit the file.

Change the permission on the config file so that only we the user can read them.

sudo chmod 600 wg0.conf
sudo chmod 600 privatekey

3.3 Start and Enable the WireGuard VPN Server

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

Check the status of the VPN server

sudo systemctl status wg-quick@wg0

It should say active.

Verify that the config file wg0 is active.

wg show wg0

It should tell you the public key and what port the server is listening on.

4. Open Firewall port on server

Make sure you have the firewall enabled.

sudo ufw status

If not, enable it.

sudo ufw enable

Now, allow traffic to the port that WireGuard is listening on.

sudo ufw allow <port that you chose>/udp

Note

Replace <port that you chose> with the port that you entered into the config file

Reload the firewall.

sudo ufw reload

You can check the status of the firewall again to confirm that the port has been enabled.

sudo ufw status

5. Configure a client

With WireGuard VPN, both the client and the server authenticate each other to prevent man in the middle attacks so the client also needs to generate a key and a config file. The client file will note the server's public key, and we will have to enable the client on the VPN server with the client's public key. We will also create a configuration file for the client that will have the necessary details about the server in order to connect to it.

5.1 Generate a private/public key pair for the client.

We could generate client's public and private key using the same command as before, or, if you are configuring a Windows/Android/Mac client at the moment, we can easily generate the keys and config file using the client application. You can download the client application here, https://www.wireguard.com/install/, or navigate to your mobile app store.

When you open the Desktop client, hit Add Tunnel at the bottom left, and choose an empty tunnel. This will conveniently create a public and private key for the client and start your config file off.

Adding a tunnel with Windows

5.2 Create the Client config file

[Interface]
PrivateKey = <private key generated by client application>
Address = <a new IP address for this particular client>/24
DNS = 8.8.8.8, 8.8.4.4

[Peer]
PublicKey = <public key of VPN server>
AllowedIPs = 0.0.0.0/0
EndPoint = <network IP address or DDNS>:<port WireGuard is listening on>

Replace the place holders

  • <private key generated by client application>: this is prefilled as you can see in the screen shot.
  • <a new IP address for this particular client>: I'm just going to increment from the server IP address I created, 10.0.0.1, and use 192.168.43.100/32 for this client.
  • <public key of VPN server>: This is the one we generated by command.
  • <network IP address or DDNS>: IP address of your router or your DDNS. If you simply use the IP address, that can be seen from when we ran ifconfig. Otherwise, if you haven't already created a DDNS, please see my documentation on how to do so.

Prepare .conf file for mobile app ease

If you set up this client on a desktop client, go ahead and save that config file into a file called client.conf. This makes it super easy to set up your mobile client on Android or iOS, as you can then just import the text file. Otherwise, you can simply input all of this data into the fields on your mobile app.

5.3 Authorize the new client

We need two things from the clients configuration including the public key as well as the IP address we created for the client. Again, I'm using 192.168.43.100/32.

wg set wg0 peer <client public key> allowed-ips <client vpn IP address>

You can now see all authorized clients with

wg show wg0

wg show wg0

myserver:/etc/wireguard# wg show wg0
interface: wg0
  public key: (hidden)
  private key: (hidden)
  listening port: (hidden)

peer: (hidden client public key) endpoint: (hidden) allowed ips: 10.0.0.0/24 latest handshake:
1 day, 22 hours, 20 minutes, 1 second ago transfer: 40.77 MiB received, 322.39 MiB sent

wg0.conf changed

We also see that a client section was added to wg0.conf

sudo nano wg0.conf

[Peer]
PublicKey = (hidden)
AllowedIPs = 192.168.43.100/32

Save the changes.

wg-quick save wg0

6. Open port forwarding on your Router

On your router configuration page, just make sure you expose and forward the port that your VPN server is routing through, thus enabling the connection to your VPN from outside of your network.

On an Eero router, for example, you can get there in the mobile app by going to

Settings -> Network Settings -> Reservation and Port Forwarding -> Add a Reservation

After adding a local IP reservation, you can then open whatever ports you need to expose and forward to your home server.

You're all set to go on your client now! You should be able to activate and quickly get on your network. Please let me know if you have any questions or comments down below!

Comments