Setup a Wireguard VPN Server

Introduction

Welcome to another blog post, today I’m going to show you how to setup a secure Wireguard VPN server.

WireGuard is a modern, fast, and secure VPN protocol that provides excellent performance and encryption. In this tutorial, we will explain how to set up a secure WireGuard server on Linux.

For this demonstration and walkthrough I will be using Ubuntu 22.04 on a 1vcpu 1GB Memory VPS hosted on www.binarylane.com.au. I highly recommened BinaryLane as they provide fast and reliable VPS solutions and even dedicated servers!

For the sake of compatibility, I will add how to do each step on Centos/RHEL based systems as well, but please be aware the commands/packages may have changed or be named differently since the time of posting.

Prerequisites

  • Linux Server
  • Root Access
  • iptables-persistent (Ubuntu Only)
  • resolvconf

Update System and Install Prerequisites

First we need to update the linux server with the latest packages and kernel.

Ubuntu

sudo apt update
sudo apt upgrade -y

Centos/RHEL

sudo yum update -y

Install iptables-persistent (Ubuntu Only)

sudo apt install iptables-persistent
sudo systemctl enable iptables

Install resolvconf

sudo apt install resolvconf

To reload the new kernel, restart your server, This is recommended!

restart

Setup Firewall

Now that the system is updated it is recommended secure the servers firewall to block any unauthorized SSH login attempts.

Blocking access to a specific IP address on port 22 is not required, espcially if you don’t have a static IP address, but is a great way to prevent any brute force attempts against your servers SSH server.

I will do this in two sections, IPv4 and IPv6. The IPv6 section is entirely optional.

Create the Iptables ruleset files and store them in /opt

Firewall Rules IPV4

nano /opt/ipv4rules.rules

Choose one of the following rulesets, paste in the following config and edit to your needs.

Without specifc IP address whitelisting

*filter
-A INPUT -i lo -j ACCEPT
-A INPUT ! -i lo -s 127.0.0.0/8 -j REJECT
-A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT
-A INPUT -p udp --dport 51820 -m state --state NEW -j ACCEPT
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -j DROP
COMMIT

With specifc IP address whitelisting

*filter
-A INPUT -i lo -j ACCEPT
-A INPUT ! -i lo -s 127.0.0.0/8 -j REJECT

#Edit this line here
-A INPUT -p tcp -s PLACEYOURIPHERE --dport 22 -m state --state NEW -j ACCEPT

-A INPUT -p udp --dport 51820 -m state --state NEW -j ACCEPT
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -j DROP
COMMIT

Firewall Rules IPV6

nano /opt/ipv6rules.rules

Without specifc IP address whitelisting

*filter
-A INPUT -i lo -j ACCEPT
-A INPUT -s fe80::/64 -j ACCEPT
-A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT
-A INPUT -p udp --dport 51820 -m state --state NEW -j ACCEPT
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -j DROP
COMMIT

With specifc IP address whitelisting

*filter
-A INPUT -i lo -j ACCEPT
-A INPUT -s fe80::/64 -j ACCEPT

#Edit this line here
-A INPUT -p tcp -s YOURIPV6ADDRESSHERE --dport 22 -m state --state NEW -j ACCEPT

-A INPUT -p udp --dport 51820 -m state --state NEW -j ACCEPT
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -j DROP
COMMIT

Once you have saved your Iptables rulset files, let’s go ahead and implement them and save the rules to automatically load on system start up.

This can be done with the following commands.

Ubuntu IPv4

iptables-restore < ipv4rules.rules
iptables-save > /etc/iptables/rules.v4

Ubuntu IPv6

iptables-restore < ipv6rules.rules
iptables-save > /etc/iptables/rules.v6

Centos/RHEL IPv4

iptables-restore < ipv4rules.rules
iptables-save > /etc/sysconfig/iptables

Centos/RHEL IPv6

iptables-restore < ipv6rules.rules
iptables-save > /etc/sysconfig/ip6tables

To double check the rules have successfully applied, you can run this command.

iptables -nL
ip6tables -nL

Install Wireguard

Now we need to install the Wireguard package, it is a simple process that can be done with one or two commands, depending on the system you are running.

Ubuntu

sudo apt install wireguard

Centos/RHEL

sudo yum install epel-release
sudo yum install wireguard-tools

Generating Server Keys

WireGuard uses public-key cryptography to secure the communication between the server and clients, Wireguard does not use usernames and passwords. To generate the keys, use the following commands:

Note: These keys will be used for the server, keep them stored somewhere safe and secure, the private key should not leave the server. The public key will be used in client configs.

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

Repeat the process one or more times, depending on how many clients you want to have connected to your Wireguard server.

For me, I only need 1 client config, which is me.

umask 077
wg genkey | tee client1privatekey | wg pubkey > client1publickey

Configuring the Wireguard Server

Create the confiuration file for Wireguard, This will be located at:

/etc/wireguard/wg0.conf

I have chosen the IPv4 subnet 10.99.99.0/24 for demonstration, feel free to change it to your liking. Likewise with the IPv6 prefix.

Here is an example config of what yours should look like.

Note: Replace eth0 with the interface name your server uses.

[Interface]
PrivateKey = iOXy1PjfCBXzEKl2sQORvD7KPIosDUPGad7M6ftDRlM=
Address = 10.99.99.1/24, fd0d:86fa:c3bc::1/64
ListenPort = 51820
PostUp = iptables -t nat -I POSTROUTING -o eth0 -j MASQUERADE
PostUp = ip6tables -t nat -I POSTROUTING -o eth0 -j MASQUERADE
PreDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
PreDown = ip6tables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer]
PublicKey = UpioRn1FRssAz7sdifGeB22CcYvMCahm/AqGwklFBGc=
AllowedIPs = 10.99.99.2/32, fd0d:86fa:c3bc::2/64

You can add more peers under the [Peer] sections, following the same format as the first peer. Just make sure to increment the AllowIPs and change the PublicKey to the client public key.

Enabling IP Forwarding

Enable for clients to access the internet via the Wireguard VPN, we need to enable IP forwarding in sysctl, it is a simple step with only 1 change to a file.

Open the sysctl.conf file.

sudo nano /etc/sysctl.conf

Uncomment or add the following line.

net.ipv4.ip_forward=1

If you are using IPv6 as well, Uncomment or add the following line as well.

net.ipv6.conf.all.forwarding=1

Now apply the new change.

sudo sysctl -p

Enabling Start at Boot

When the system reboot, we want to make sure the wireguard server starts automatically to avoid as much downtime as we can without any manual interaction.

We can enable start at book by running the following systemctl command.

systemctl enable wg-quick@wg0.service

Creating The Client Config

Before we start the Wireguard server we need to create out client config file, or we won’t be able to connect.

An example client config is shown below. I have used the Quad9 DNS servers for this example, but feel free to change it to your desired DNS servers.

Note: Remember to change the values to match your keys and IP addresses.

[Interface]
PrivateKey = <client private key>
Address = 10.99.99.2/32, fd0d:86fa:c3bc::2/64
DNS = 9.9.9.9, 2620:fe::fe

[Peer]
PublicKey = <server public key>
Endpoint = <server IP or domain name>:51820
AllowedIPs = 0.0.0.0/0, ::/0

Starting The Server

At this stage we have all of the server and client configurations setup and ready to go.

Lets go ahead and start the server!

wg-quick up wg0

To check the status of the Wireguard server, you can run this command.

wg show

Additionally to stop the server, simply run the following command.

wg-quick down wg0

Connecting Clients

Wireguard has many options to connect clients, this can be done on Windows, Linux, Android and IOS. I will show examples on how to connect a Windows Client and a Linux Client.

Wireguard can be downloaded here -> Wireguard Downloads

Windows

Export the client config from the Wireguard server and save somewhere safe as client1.conf.

Next open the Wireguard application and click the “Add Tunnel” button and select the client1.conf file.

The client is now imported and all you need to do is click the activate button.

To confirm you connectivity for IPv4 and IPv6 you can test your connection at https://test-ipv6.com/

Linux

Firstly, install wireguard and any requirements.

Ubuntu

sudo apt install resolvconf
sudo apt install wireguard

Centos/RHEL

sudo yum install epel-release
sudo yum install wireguard-tools

Create the wg0.conf file and paste in the client config you created on the server.

sudo nano /etc/wireguard/wg0.conf

Now start the Wireguard connection.

wg-quick up wg0

End

Epic! We now have a fully functioning Wireguard VPN server that can route IPv4 and IPv6. I hope you learned a lot from this demonstration and how easy and quick it is to create a secure and fast wireguard server.

I hope you enjoyed and thanks for taking the time to read my blog!

Links