CentOS 8 set up WireGuard VPN server

last updated in Categories , ,

How do I install and set up WireGuard VPN server on a CentOS 8 Linux? How can I configure CentOS 8 as the WireGuard VPN server?

WireGuard is a free, open-source modern and fast VPN with state-of-the-art cryptography. It is quicker and simpler as compared to IPSec and OpenVPN. Originally, released for the Linux kernel, but it is getting cross-platform support for other operating systems too. This page explains how to install and set up WireGuard VPN on CentOS 8 Linux.

Advertisements

Procedure: CentOS 8 set up WireGuard VPN server

Our sample setup includes a simple peer connection between a cloud server running CentOS 8 server, and a CentOS/Ubuntu Linux desktop client:
WireGuard Setup
The steps are as follows for installing and configuring WireGuard on CentOS Linux as a VPN server.

Please note that {vivek@centos8:~ }$ is my shell prompt and is not part of actual commands. In other words, you need to copy and paste command after my shell prompt.

Step 1 – Update your system

Run the dnf command or yum command to install CentOS 8 security updates:
{vivek@centos8:~ }$ sudo dnf updateOR
{vivek@centos8:~ }$ sudo yum update

Step 2 – Enable and install EPEL repo

We need to install a package named wireguard-tools from EPEL repo that provides the wg binary for controlling the WireGuard server. Let us enable and install EPEL repo on CentOS 8, run:
{vivek@centos8:~ }$ sudo yum install epel-release
Turn on EPEL repo for CentOS Linux 8 server
Make sure you enable the PowerTools repository since EPEL packages may depend on packages from it:
{vivek@centos8:~ }$ sudo yum install 'dnf-command(config-manager)'
{vivek@centos8:~ }$ sudo yum config-manager --set-enabled PowerTools

Step 3 – Set up wireguard repo

Before we can install the wireguard Linux kernel module, turn on the official wireguard repo. Execute the following command:
{vivek@centos8:~ }$ sudo yum copr enable jdoss/wireguard
CentOS 8 enable Wireguard Copr repo

Step 4 – Installing a WireGuard VPN server on CentOS 8

Now we got everything set up. It is time for setting up a WireGuard VPN server on CentOS 8 box. Run:
{vivek@centos8:~ }$ sudo yum install wireguard-dkms wireguard-tools
CentOS 8 install WireGuard dkms using yum command
The above will also install the GNU GCC compiler collection to compile and build the required Linux kernel modules. So it would be best if you waited some time to complete the procedure.

Step 5 – Configuring WireGuard server

First, we are going to create an empty WireGuard server config file with proper permissions. Use the mkdir command as follows:
{vivek@centos8:~ }$ sudo mkdir -v /etc/wireguard/
mkdir: created directory '/etc/wireguard/'
{vivek@centos8:~ }$ sudo sh -c 'umask 077; touch /etc/wireguard/wg0.conf'
{vivek@centos8:~ }$ sudo ls -l /etc/wireguard/wg0.conf
-rw-------. 1 root root 0 Mar 13 09:13 /etc/wireguard/wg0.conf

Create a private and public key pair for the WireGuard server

We need to run the following commands in /etc/wireguard/ directory. Use the cd command:
{vivek@centos8:~ }$ cd /etc/wireguard/
Run the following command:
{vivek@centos8:~ }$ sudo sh -c 'umask 077; wg genkey | tee privatekey | wg pubkey > publickey'
To view keys use the cat command and ls command:
{vivek@centos8:~ }$ ls -l privatekey publickey
{vivek@centos8:~ }$ sudo cat privatekey
#### Note down the privatekey ####
{vivek@centos8:~ }$ sudo cat publickey

Set Up WireGuard VPN on CentOS Linux

Configure WireGuard server

Edit the /etc/wireguard/wg0.conf file:
{vivek@centos8:~ }$ sudo vi /etc/wireguard/wg0.conf
Append the following directives:

[Interface]
## VPN server private IP address ##
Address = 192.168.5.1/24
 
## VPN server port ##
ListenPort = 31194
 
## VPN server's private key i.e. /etc/wireguard/privatekey ##
PrivateKey = cBRd8MhXckz5ZnNRvk8F+r0558sfJlI0YdJ7ZQfWqUM=
 
## Save and update this config file when a new peer (vpn client) added ##
SaveConfig = true

Save and close the file.

Set up firewalld rules

We have set up a firewall using FirewallD on our CentOS 8 server. Hence, we need to open UDP port 31194 by creating wireguard service:
{vivek@centos8:~ }$ sudo vi /etc/firewalld/services/wireguard.xml

<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>wireguard</short>
  <description>WireGuard open UDP port 31194 for client connections</description>
  <port protocol="udp" port="31194"/>
</service>

Next, I am going to enable our WireGuard service in firewalld using the firewall-cmd command as follows:
{vivek@centos8:~ }$ sudo firewall-cmd --permanent --add-service=wireguard --zone=public
Turn on masquerading so all traffic coming and going out from 192.168.5.0/24 routed correctly via our public IP address 172.105.120.136/24:
{vivek@centos8:~ }$ sudo firewall-cmd --permanent --zone=public --add-masquerade
Finally reload the firewalld and list our configuration:
{vivek@centos8:~ }$ sudo firewall-cmd --reload
{vivek@centos8:~ }$ sudo firewall-cmd --list-all

Sample outputs:

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: 
Turn on IPv4/IPv6 forwarding

Edit the /etc/sysctl.d/99-custom.conf file
{vivek@centos8:~ }$ sudo vi /etc/sysctl.d/99-custom.conf
Append the following config options:

## 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 - uncomment the following line ##
#net.ipv6.conf.all.forwarding = 1

Reload changes using the sysctl command:
{vivek@centos8:~ }$ sudo sysctl -p /etc/sysctl.d/99-custom.conf
Above directives are explained in details in my previous tutorials:

Allow peer to peer connection

By default, firewalld will drop all communication between internal (wg0) and the public network (eth0). So we are going to add interface wg0 to the internal network and turn on masquerading as follows
{vivek@centos8:~ }$ sudo firewall-cmd --add-interface=wg0 --zone=internal
{vivek@centos8:~ }$ sudo firewall-cmd --permanent --zone=internal --add-masquerade

Step 5 – Enable and start WireGuard service

Now we installed and configured server correctly it is time to enable and start wireguard service using the systemctl command:
{vivek@centos8:~ }$ sudo systemctl enable wg-quick@wg0 #<-- turn it on
{vivek@centos8:~ }$ sudo systemctl start wg-quick@wg0 #<-- start it
{vivek@centos8:~ }$ sudo systemctl status wg-quick@wg0 #<-- get status

Verify that interface wg0 is up and running using the ip command:
{vivek@centos8:~ }$ sudo wg
{vivek@centos8:~ }$ sudo ip a show wg0

Please note down the public key when displayed:
Linux VPN and verification commands

Step 6 – Wireguard VPN client configuration

The procedure for installing and configuring a VPN client is the same as setting up the server. Let us install the client on a CentOS 8:
{vivek@centos8-vpn-client:~ }$ sudo yum install epel-release
{vivek@centos8-vpn-client:~ }$ sudo yum install 'dnf-command(config-manager)'
{vivek@centos8-vpn-client:~ }$ sudo yum config-manager --set-enabled PowerTools
{vivek@centos8-vpn-client:~ }$ sudo yum copr enable jdoss/wireguard
{vivek@centos8-vpn-client:~ }$ sudo yum install wireguard-dkms wireguard-tools

Here is how I installed it on my Ubuntu Linux laptop using the apt command:
{vivek@ubuntu19-10-vpn-client:~ }$ sudo apt install wireguard-dkms wireguard-tools wireguard
Let us create our VPN client config:
{vivek@centos8-vpn-client:~ }$ sudo mkdir -v /etc/wireguard/
{vivek@centos8-vpn-client:~ }$ sudo sh -c 'umask 077; touch /etc/wireguard/wg0.conf'
{vivek@centos8-vpn-client:~ }$ sudo ls -l /etc/wireguard/wg0.conf
{vivek@centos8-vpn-client:~ }$ cd /etc/wireguard/
{vivek@centos8-vpn-client:~ }$ sudo sh -c 'umask 077; wg genkey | tee privatekey | wg pubkey > publickey'
#### Note down the privatekey ####
{vivek@centos8-vpn-client:~ }$ sudo cat privatekey

Edit the /etc/wireguard/wg0.conf file:
{vivek@centos8-vpn-client:~ }$ sudo vi /etc/wireguard/wg0.conf
Append the following directives:

[Interface]
## client private key ##
PrivateKey = sKVVArGeo75fCkskltZc8WRIi9fPQ3SPLXmrr8uBp3M=
 
## client ip address ##
Address = 192.168.5.2/24
 
[Peer]
## CentOS 8 server public key ##
PublicKey = qdjdqh2+N3DEMDUDRob8K3b+9BZFJbT59f+rBrl99zM
 
## set ACL ##
AllowedIPs = 192.168.5.0/24
 
## Your CentOS 8 server's public IPv4/IPv6 address and port ##
Endpoint = 172.105.120.136:31194
 
##  Key connection alive ##
PersistentKeepalive = 15

Enable and start VPN client/peer, run:
{vivek@centos8-vpn-client:~ }$ sudo systemctl enable wg-quick@wg0
{vivek@centos8-vpn-client:~ }$ sudo systemctl start wg-quick@wg0
{vivek@centos8-vpn-client:~ }$ sudo systemctl status wg-quick@wg0

Allow client and server connection

We need to configure the server-side and allow a connection between the client and the server. Let us go back to our CentOS 8 server and edit wg0.conf file to add [Peer] (client) information as follows (type commands on the server):
{vivek@centos8:~ }$ sudo systemctl stop wg-quick@wg0
{vivek@centos8:~ }$ sudo vi /etc/wireguard/wg0.conf

Append the following config:

[Peer]
## client VPN public key ##
PublicKey = hM/J1IVUns1F4gWjA11pOPq6uDmlYsSq0o7JWCQ02C4=
 
## client VPN IP address (note /32 subnet) ##
AllowedIPs = 192.168.5.2/32

Save and close the file in vim. Next start the service again, run:
{vivek@centos8:~ }$ sudo systemctl start wg-quick@wg0

Verification

That is all. By now, both servers and clients must be connected securely using VPN. Let us test the connection. Type the following ping command on your client machine:
{vivek@centos8-vpn-client:~ }$ ping -c 4 192.168.5.1
{vivek@centos8-vpn-client:~ }$ sudo wg

Set Up WireGuard VPN on CentOS 8 and verify with ping command

Conclusion

Congratulation! You just end up setting up a WireGuard VPN server on CentOS 8 and peer (client) on both Ubuntu/CentOS Linux desktop. See WireGuard project docs and other information here.

ADVERTISEMENTS

Posted by: Vivek Gite

The author is the creator of nixCraft and a seasoned sysadmin, DevOps engineer, and a trainer for the Linux operating system/Unix shell scripting. Get the latest tutorials on SysAdmin, Linux/Unix and open source topics via RSS/XML feed or weekly email newsletter.

Start the discussion at www.nixcraft.com