CentLinux | Learn How to Install CentOS/Rocky Linux Servers

Sunday, June 28, 2020

How to Setup WireGuard VPN Server on CentOS 8

Setup WireGuard VPN Server on CentOS 8

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 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.

Setup WireGuard VPN Server on CentOS 8

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.

If you find this article useful? Consider supporting us by Buy Me A Coffee


2 comments:

  1. 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:

    sudo 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.

    ReplyDelete
    Replies
    1. Hi, You are not using the correct command to start WireGuard interface on the client. You should run

      # wg set wg0 peer aXhOmnQY4fooJKpZVfJHfSoId03khzvPijtxPdN0IHA= allowed-ips 100.10.1.2

      as mentioned in the above article.

      Delete

© 2023 CentLinux. All Rights Reserved.