In this article, you will learn how to setup WireGuard VPN Server on CentOS 8. After successful configurations, we will also establish a VPN tunnel between two CentOS 8 machines.
This Article Provides:
- What is WireGuard?
- WireGuard Features
- How WireGuard Works
- Environment Specification
- Update CentOS 8 Software Packages
- Install WireGuard VPN Server on CentOS 8
- Setup WireGuard VPN Server on CentOS 8
- Enable IP Forwarding on CentOS 8
- Setup WireGuard VPN Client on CentOS 8
What is WireGuard?:
WireGuard is a free and open-source software application and communication protocol that implements virtual private network (VPN) techniques to create secure point-to-point connections in routed or bridged configurations.
It aims for better performance and power saving then the IPSEC and OpenVPN tunneling protocols.
WireGuard is written by Jason A. Donenfeld and is published under the GNU General Public License (GPL) version 2.
The Linux version of the software has reached a stable production release and was incorporated into the Linux kernel release in late March 2020.
WireGuard Features:
Core features of the WireGuard VPN software are.
- Simple Setup
- Fast and Secure
- Strong encryption
- IP Roaming at both ends
- Minimal attack surface
How WireGuard Works:
WireGuard creates virtual network interfaces on each peer device that operate as a tunnel endpoint.
Peers authenticates each other by exchanging the public keys similar to the SSH model. Each Public key is mapped with one or more IP addresses, that are allowed to use the tunnel.
Whereas the VPN traffic is encapsulated in UDP.
A good book related to VPNs is VPNs is Zero Trust Networks: Building Secure Systems in Untrusted Networks by O'Reilly Media. We recommend that you should read this book if you want to work on VPNs.
Environment Specification:
We are using two minimal CentOS 8 virtual machine with following specifications.
Wireguard VPN Server:
- CPU - 3.4 Ghz (2 cores)
- Memory - 2 GB
- Storage - 20 GB
- Operating System - CentOS 8.2
- Hostname – wireguard-vpn-01.centlinux.com
- IP Address - 192.168.116.206 /24
Wireguard VPN Client:
- CPU - 3.4 Ghz (2 cores)
- Memory - 2 GB
- Storage - 20 GB
- Operating System - CentOS 8.2
- Hostname – wireguard-vpn-02.centlinux.com
- IP Address - 192.168.116.227 /24
Update CentOS 8 Software Packages:
Connect with wireguard-vpn-01.centlinux.com as root user by using a SSH tool.
Update existing software packages on CentOS 8 server.
# dnf update -y
Our CentOS 8 server is already up to date.
Verify the version of Linux Kernel and operating system.
# uname -a Linux wireguard-vpn-01.centlinux.com 4.18.0-193.6.3.el8_2.x86_64 #1 SMP Wed Jun 10 11:09:32 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux # cat /etc/redhat-release CentOS Linux release 8.2.2004 (Core)
Install WireGuard VPN Server on CentOS 8:
WireGuard software is not available in default yum repositories, therefore, we are installing EPEL (Extra Packages for Enterprise Linux) and ELREPO (that provides hardware related packages) on our CentOS 8 Server.
# dnf install -y elrepo-release epel-release
Build cache for newly installed yum repositories.
# dnf makecache
CentOS-8 - AppStream 2.2 kB/s | 4.3 kB 00:01
CentOS-8 - Base 241 B/s | 3.9 kB 00:16
CentOS-8 - Extras 1.8 kB/s | 1.5 kB 00:00
ELRepo.org Community Enterprise Linux Repositor 70 kB/s | 233 kB 00:03
Extra Packages for Enterprise Linux Modular 8 - 33 kB/s | 119 kB 00:03
Extra Packages for Enterprise Linux 8 - x86_64 440 kB/s | 7.1 MB 00:16
Metadata cache created.
Install WireGuard Kernel module and relevant tools by using dnf command.
# dnf install -y kmod-wireguard wireguard-tools
Setup WireGuard VPN Server on CentOS 8:
The configuration files of WireGuard located in /etc/wireguard directory. This directory is automatically created during installation process.
For encrypted communication WireGuard uses a public/private key pair. Therefore, we need to generate a Public/Private key pair for WireGuard.
wg command provides a quiet handy method to generate these keys.
# wg genkey | tee /etc/wireguard/private.key | wg pubkey > /etc/wireguard/public.key
Verify that the keys have been generated successfuly.
# ls /etc/wireguard/
private.key public.key
Create a WireGuard VPN interface, you can use your preferred name for the interface but the default and recommended name is wg0.
# vi /etc/wireguard/wg0.conf
Add following directives in this file.
[Interface] Address = 100.10.1.1/24 SaveConfig = true ListenPort = 51820 PrivateKey = EE78DDj1ddIClV55vYB5Bi24yAbHj+R8zC7dDMrV11M= PostUp = firewall-cmd --zone=public --add-port 51820/udp && firewall-cmd --zone=public --add-masquerade PostDown = firewall-cmd --zone=public --remove-port 51820/udp && firewall-cmd --zone=public --remove-masquerade
Here,
- Address - is the IP address used by the WireGuard interface
- SaveConfig - if it is set to true then the current state of WireGuard interface will be saved on shutdown
- ListenPort – WireGuard daemon listening port
- PrivateKey - The Private Key that we have generated above
- PostUp - is used to specify any actions at the time of bringing up the WireGuard interface. We are opening the Listening port by using the firewall-cmd command
- PostDown - is used to specify any actions at the time of bringing down the WireGuard interface. We are closing the Listening port by using the firewall-cmd command
Adjust file permissions on critical files for improved security.
# chmod 600 /etc/wireguard/{private.key,wg0.conf}
Bring up the WireGuard interface by using wg-quick command.
# wg-quick up wg0
[#] ip link add wg0 type wireguard
[#] wg setconf wg0 /dev/fd/63
[#] ip -4 address add 100.10.1.1/24 dev wg0
[#] ip link set mtu 1420 up dev wg0
[#] firewall-cmd --zone=public --add-port 51820/udp && firewall-cmd --zone=public --add-masquerade
success
success
We can use wg and ip commands to check the status of the wg0 interface.
# wg
interface: wg0
public key: BojzNmenG3beCSNH4zPCLuMPgoY6/+5LVUfb4HHQWm0=
private key: (hidden)
listening port: 51820
# ip address show wg0
4: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN group default qlen 1000
link/none
inet 100.10.1.1/24 scope global wg0
valid_lft forever preferred_lft forever
To enable autostart of wg0 interface at the time of CentOS 8 server startup. We need to enable the wg-quick service as follows.
# systemctl enable wg-quick@wg0.service
Created symlink /etc/systemd/system/multi-user.target.wants/wg-quick@wg0.service â /usr/lib/systemd/system/wg-quick@.service.
Enable IP Forwarding on CentOS 8:
IP Forwarding is by-default disabled in CentOS 8. We need to explicitly enable it in Kernel configurations as follows.
# echo "net.ipv4.ip_forward=1" >> /etc/sysctl.d/99-custom.conf # sysctl -p
Our WireGuard server-side configurations has been completed successfully.
Setup WireGuard VPN Client on CentOS 8:
Connect with wireguard-02.centlinux.com as root user by using a SSH tool.
Update existing software packages by using dnf command.
# dnf update -y
Enable EPEL and ELREPO yum repositories.
# dnf install -y elrepo-release epel-release
Build cache for EPEL and ELREPO yum repositories.
# dnf makecache
CentOS-8 - AppStream 3.8 kB/s | 4.3 kB 00:01
CentOS-8 - Base 9.7 kB/s | 3.9 kB 00:00
CentOS-8 - Extras 2.5 kB/s | 1.5 kB 00:00
ELRepo.org Community Enterprise Linux Repositor 102 kB/s | 264 kB 00:02
Extra Packages for Enterprise Linux Modular 8 - 32 kB/s | 154 kB 00:04
Extra Packages for Enterprise Linux 8 - x86_64 453 kB/s | 7.1 MB 00:15
Metadata cache created.
Install WireGuard Kernel module and related tools as follows.
# dnf install -y kmod-wireguard wireguard-tools
Generate a public/private key pair, just like we have generated at the time of WireGuard Server setup.
# wg genkey | tee /etc/wireguard/private.key | wg pubkey > /etc/wireguard/public.key
Create a WireGuard interface on our CentOS 8 client.
# vi /etc/wireguard/wg0.conf
Add following directives there in.
[Interface] Address = 100.10.1.2/24 PrivateKey = +LqQdYG5t2Ai/juBks7VvxmDBvlpv/gPQsDbsDfz530= [Peer] PublicKey = BojzNmenG3beCSNH4zPCLuMPgoY6/+5LVUfb4HHQWm0= Endpoint = 192.168.116.206:51820 AllowedIPs = 0.0.0.0/0
Here,
- Address - is the IP Address used by the WireGuard interface
- PrivateKey - is the Private key that we have generated on WireGuard client
- PublicKey - is the Public key that we have generated on the WireGuard server
- Endpoint - Endpoint is the IP Address of the WireGuard Server followed by the port
- AllowedIPs - Network addresses allowed to send data to our WireGuard client
Adjust file permissions on critical files to improve security.
# chmod 600 /etc/wireguard/{private.key,wg0.conf}
Finally, we need to add our WireGuard client's public key and IP Address in our WireGuard VPN Server. Therefore, connect to wireguard-vpn-01.centlinux.com as root user and execute following command.
# wg set wg0 peer aXhOmnQY4fooJKpZVfJHfSoId03khzvPijtxPdN0IHA= allowed-ips 100.10.1.2
Restart wg0 interface to apply changes.
# systemctl restart wg-quick@wg0.service
Check WireGuard server status.
# wg
interface: wg0
public key: BojzNmenG3beCSNH4zPCLuMPgoY6/+5LVUfb4HHQWm0=
private key: (hidden)
listening port: 51820
peer: aXhOmnQY4fooJKpZVfJHfSoId03khzvPijtxPdN0IHA=
allowed ips: 100.10.1.2/32
Connect to wireguard-vpn-02.centlinux.com as root user.
Start and enable wg-quick service. It will bring up the wg0 interface and created the WireGuard VPN tunnel.
# systemctl enable --now wg-quick@wg0.service
Created symlink /etc/systemd/system/multi-user.target.wants/wg-quick@wg0.service â /usr/lib/systemd/system/wg-quick@.service.
Verify the WireGuard client status.
# wg
interface: wg0
public key: aXhOmnQY4fooJKpZVfJHfSoId03khzvPijtxPdN0IHA=
private key: (hidden)
listening port: 33030
fwmark: 0xca6c
peer: BojzNmenG3beCSNH4zPCLuMPgoY6/+5LVUfb4HHQWm0=
endpoint: 192.168.116.206:51820
allowed ips: 0.0.0.0/0
latest handshake: 18 seconds ago
transfer: 124 B received, 340 B sent
If you check the status of WireGuard server, you will see.
# wg
interface: wg0
public key: BojzNmenG3beCSNH4zPCLuMPgoY6/+5LVUfb4HHQWm0=
private key: (hidden)
listening port: 51820
peer: aXhOmnQY4fooJKpZVfJHfSoId03khzvPijtxPdN0IHA=
endpoint: 192.168.116.227:33030
allowed ips: 100.10.1.2/32
latest handshake: 32 seconds ago
transfer: 148 B received, 124 B sent
So, Our WireGuard VPN tunnel has been established successfully.
To verify that, is our communication routing through WireGuard VPN server? we can use the tracepath command on wireguard-vpn-02.centlinux.com to trace the route of a request.
# tracepath -n google.com
1?: [LOCALHOST] pmtu 1420
1: 100.10.1.1 0.569ms
1: 100.10.1.1 0.360ms
2: no reply
3: no reply
You can see that, our request is routing through the WireGuard VPN Server.
We have successfully setup WireGuard VPN server on CentOS 8 and created a VPN tunnel between two CentOS 8 machines.
This is excellent, thank you for the tutorial. I am having an issue when I try installing the client on a minimal CentOS install. When I run 'wg-quick up wg0' I recieve the following error:
ReplyDeletesudo wg-quick up wg0
[#] ip link add wg0 type wireguard
[#] wg setconf wg0 /dev/fd/63
[#] ip -4 address add 10.0.0.2/24 dev wg0
[#] ip link set mtu 1420 up dev wg0
[#] wg set wg0 fwmark 51820
[#] ip -4 route add 0.0.0.0/0 dev wg0 table 51820
[#] ip -4 rule add not fwmark 51820 table 51820
[#] ip -4 rule add table main suppress_prefixlength 0
[#] sysctl -q net.ipv4.conf.all.src_valid_mark=1
[#] nft -f /dev/fd/63
/dev/fd/63:5:1-96: Error: Could not process rule: No such file or directory
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[#] ip -4 rule delete table 51820
[#] ip -4 rule delete table main suppress_prefixlength 0
[#] ip link delete dev wg0
.............
Any idea on how I could resolve this would be much appriciated. I am also running an instance on OpenVPN on the client.
Hi, You are not using the correct command to start WireGuard interface on the client. You should run
Delete# wg set wg0 peer aXhOmnQY4fooJKpZVfJHfSoId03khzvPijtxPdN0IHA= allowed-ips 100.10.1.2
as mentioned in the above article.