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
- BinaryLane www.binarylane.com.au
- Github https://github.com/tijjjy
- Wireguard https://www.wireguard.com/