How to set up Wireguard VPN on CentOS 8
On this page
- Step 1 - Update System
- Step 2 - Install and Enable EPEL repo
- Step 3 - Install Wireguard
- Step 4 - Configure Wireguard Server
- Step 5 - Configure Firewall
- Step 6 - Turn on IPv4 Forwarding
- Step 7 - Enable and Start the Wireguard Service
- Step 8 - Install and Configure WireGuard Client
- Step 9 - Configure Server to Add the Client
- Step 10 - Test
- Conclusion
Wireguard is an open-source cross-platform VPN implementation that uses state of the art cryptography. It is faster, simpler and more functional than IPSec and OpenVPN protocols. It is designed as a general-purpose VPN to run on embedded interfaces and supercomputers and runs on Linux, Windows, macOS, iOS, Android, BSD and various other platforms.
This tutorial will cover how to install Wireguard VPN on a CentOS 8 based server and to connect to it using a Linux(CentOS/Fedora/Ubuntu) client.
Step 1 - Update System
Before proceeding any further, it's imperative to update your system to install the latest updates.
$ sudo dnf update
Step 2 - Install and Enable EPEL repo
The required Wireguard packages can be found in the EPEL repository so we need to install and enable it.
$ sudo dnf install epel-release
$ sudo dnf config-manager --set-enabled PowerTools
We also enabled the PowerTools repository since EPEL packages depend on it.
Step 3 - Install Wireguard
Enable the Wireguard repository.
$ sudo dnf copr enable jdoss/wireguard
Install Wireguard.
$ sudo dnf install wireguard-dkms wireguard-tools
This step also installs GNU GCC compiler needed to build the Linux Kernel modules.
Step 4 - Configure Wireguard Server
Create an empty configuration file on the server for Wireguard settings with proper permissions.
$ sudo mkdir /etc/wireguard
$ sudo sh -c 'umask 077; touch /etc/wireguard/wg0.conf'
Touch command creates the file wg0-server.conf
file in the /etc/wireguard
directory.
Next, create a private/public key pair for the Wireguard server.
$ cd /etc/wireguard
$ sudo sh -c 'umask 077; wg genkey | tee privatekey | wg pubkey > publickey'
This creates both public and private key for the Wireguard and writes them to the respective files.
View the private key that we just created.
$ sudo cat privatekey
Note the key and copy it because we will need it to configure Wireguard.
Next, edit the configuration file.
$ sudo nano /etc/wireguard/wg0.conf
Add the following code.
[Interface]
## VPN server private IP address ##
Address = 192.168.10.1/24
## VPN server port - You can choose any port ##
ListenPort = 37822
## VPN server's private key i.e. /etc/wireguard/privatekey - the one from above ##
PrivateKey = GCEXafeZKqSsuLfvuHE+zLzMYwoH4qQyBh7MZ4f/3kM=
## Save and update this config file when a new peer (vpn client) added ##
SaveConfig = true
Each configuration has one section called [Interface]
where the server-part is defined.
It contains the private key of the local WireGuard server, the UDP port it should listen for incoming connections and its own VPN IP addresses.
We also set SaveConfig
to true
. This will tell the Wireguard service to automatically save its active configuration to this file at shutdown.
Press Ctrl + W to close the file and enter Y when prompted to save the file.
Step 5 - Configure Firewall
We need to open the port we chose for Wireguard.
First, we need to define Wireguard service for the firewall. To do that, create a file wireguard.xml
with the Nano editor.
$ sudo nano /etc/firewalld/services/wireguard.xml
Paste the following code in the file.
<?xml version="1.0" encoding="utf-8"?>
<service>
<short>wireguard</short>
<description>WireGuard open UDP port 37822 for client connections</description>
<port protocol="udp" port="37822"/>
</service>
Press Ctrl + W to close the file and enter Y when prompted to save the file.
Next, enable the Wireguard service in the firewall.
$ sudo firewall-cmd --permanent --add-service=wireguard
Turn on masquerading so all traffic coming and going out from 192.168.10.0/24 routed via our public IP address of the server 203.1.114.98/24.
$ sudo firewall-cmd --permanent --add-masquerade
Finally, reload the firewall to activate the rules.
$ sudo firewall-cmd --reload
List the current firewall rules to confirm.
$ sudo firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: eth0
sources:
services: wireguard ssh
ports:
protocols:
masquerade: yes
forward-ports:
source-ports:
icmp-blocks:
rich rules:
Step 6 - Turn on IPv4 Forwarding
Create /etc/sysctl.d/99-custom.conf
file.
$ sudo nano /etc/sysctl.d/99-custom.conf
Paste the following code in the file.
## Turn on bbr ##
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
## for IPv4 ##
net.ipv4.ip_forward = 1
## Turn on basic protection/security ##
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.tcp_syncookies = 1
## for IPv6 ##
net.ipv6.conf.all.forwarding = 1
Press Ctrl + W to close the file and enter Y when prompted to save the file.
The scope of the code in the file above is outside the scope of this tutorial so for now, just use it as it is.
Reload the changes.
$ sudo sysctl -p /etc/sysctl.d/99-custom.conf
By default, the firewall won't let wg0
and eth0
interfaces talk to each other. So we need to add the Wireguard interface to the internal network and turn on masquerading.
$ sudo firewall-cmd --add-interface=wg0 --zone=internal
$ sudo firewall-cmd --permanent --zone=internal --add-masquerade
Step 7 - Enable and Start the Wireguard Service
Next, we need to enable and start the Wireguard service.
$ sudo systemctl enable wg-quick@wg0
$ sudo systemctl start wg-quick@wg0
You can verify if the Wireguard interface, wg0
is up and running by using the following command.
$ sudo wg
interface: wg0
public key: VWndJ4oB7ZJwC/7UOm++OLDrbAxMPsR2yd0cl3sEkUI=
private key: (hidden)
listening port: 37822
$ sudo ip a show wg0
3: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN group default qlen 1000
link/none
inet 192.168.10.1/24 scope global wg0
valid_lft forever preferred_lft forever
Step 8 - Install and Configure WireGuard Client
You can find the install instructions for Wireguard client for your Linux distribution from their official install page.
Once you install the client, you need to create the client configuration file.
$ sudo mkdir /etc/wireguard
$ sudo sh -c 'umask 077; touch /etc/wireguard/wg0.conf'
$ cd /etc/wireguard/
$ sudo sh -c 'umask 077; wg genkey | tee privatekey | wg pubkey > publickey'
$ sudo cat privatekey
Note the private key you get at the end. Next, we need to edit the configuration file we just created.
$ sudo nano /etc/wireguard/wg0.conf
Add the following directives to the file.
[Interface]
## client private key ##
PrivateKey = OEM6D/zt2fVWOepVv3iEDD430V0gAshKp4+5oVVt5EE=
## client ip address ##
Address = 192.168.10.2/24
[Peer]
## CentOS 8 server public key ##
PublicKey = VWndJ4oB7ZJwC/7UOm++OLDrbAxMPsR2yd0cl3sEkUI=
## set ACL ##
AllowedIPs = 192.168.10.0/24
## Your CentOS 8 server's public IPv4/IPv6 address and port ##
Endpoint = 203.1.114.98:37822
## Key connection alive ##
PersistentKeepalive = 15
Note that we assigned the private IP 192.168.10.1 to the server and 192.168.10.2 to the client. We also added the client's private key to the file.
The [Peer]
section is where you enter the server's configuration to which the client will connect to. Here we have added the public key, public IP and a set of Allowed IPs which contains the private IP of our server. PersistentKeepalive
tells WireGuard to send a UDP packet every 15 seconds, this is useful if you are behind a NAT and you want to keep the connection alive.
Press Ctrl + W to close the file and enter Y when prompted to save the file.
Now is the time to enable and start the VPN client.
$ sudo systemctl enable wg-quick@wg0
$ sudo systemctl start wg-quick@wg0
$ sudo systemctl status wg-quick@wg0
Step 9 - Configure Server to Add the Client
Now, we need to add the client's configuration to the server again to let it know about the client.
Stop the Wireguard service first.
$ sudo systemctl stop wg-quick@wg0
Open the file wg0.conf for editing.
$ sudo nano /etc/wireguard/wg0.conf
Append the following code at the end of the file.
[Peer]
## client VPN public key ##
PublicKey = dmfO9pirB315slXOgxXtmrBwAqPy07C57EvPks1IKzA=
## client VPN IP address (note /32 subnet) ##
AllowedIPs = 192.168.10.2/32
Press Ctrl + W to close the file and enter Y when prompted to save the file.
The [Peer]
sections define the other members of the VPN network. You can add as many as needed.
They contain their public key, which must match the peers private key in its [Interface]
section.
Note that any incoming connection is first authenticated against one of the public keys. If the connection is not from a verified peer, the incoming packets are just silently ignored. Since connections from hosts who don’t own a matching private key are not answered at all, a WireGuard VPN does not only provide encrypted communication, it also remains hidden from outsiders.
Start the Wireguard service again.
$ sudo systemctl start wg-quick@wg0
Step 10 - Test
Let us check if both the client and the server are connected securely using VPN. To test the connection, run the following commands on your client.
$ ping -c 192.168.10.1
PING 192.168.10.1 (192.168.10.1) 56(84) bytes of data.
64 bytes from 192.168.10.1: icmp_seq=1 ttl=64 time=44.2 ms
64 bytes from 192.168.10.1: icmp_seq=2 ttl=64 time=45.8 ms
64 bytes from 192.168.10.1: icmp_seq=3 ttl=64 time=46.7 ms
64 bytes from 192.168.10.1: icmp_seq=4 ttl=64 time=44.1 ms
--- 192.168.10.1 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 2800ms
rtt min/avg/max/mdev = 41.729/47.829/48.953/5.046 ms
$ sudo wg
interface: wg0
public key: dmfO9pirB315slXOgxXtmrBwAqPy07C57EvPks1IKzA=
private key: (hidden)
listening port:
peer: VWndJ4oB7ZJwC/7UOm++OLDrbAxMPsR2yd0cl3sEkUI=
endpoint: 203.1.114.98:37822
allowed ips: 192.168.10.0/24
latest handshake: 1 minute, 40 seconds ago
transfer: 938 B received, 45.67 KiB sent
persistent: keepalive: every 15 seconds
Conclusion
That is all that there is to this tutorial. You should now have a Wireguard based VPN server based off a CentOS 8 Server. If you have any questions, ask them in the comments below.