How to Configure VPN with WireGuard

Steps to configure Site to Site VPN with WireGuard on CentOS 8 in our lab

WireGuard is implemented inside the Linux kernel as module to perform faster performance than tranditional VPN, like OpenVPN and run over UDP instead of TCP.

Components in this lab

Site to Site VPN with WireGuard

We had prepared another tutorial on Site to Site VPN with VeeamPN to replace the 2 x CentOS 8 Server with 2 x VeeamPN 2.1 Virtual Appliance which are using WireGuard for Site to Site Connectivity for comparison

Install WireGuard on CentOS 8

Enable and install EPEL repo

yum install epel-release
yum update

Enable PowerTools repository

sudo yum config-manager --set-enabled PowerTools

Setup WireGuard Repo

yum copr enable jdoss/wireguard

Install the GNU GCC compiler collection to compile and build the required Linux kernel modules.

yum install wireguard-dkms wireguard-tools

Load wireguard module

modprobe wireguard

#Verify wireguard module is loaded successfully
lsmod | grep wire
wireguard             229376  0
ip6_udp_tunnel         16384  1 wireguard
udp_tunnel             16384  1 wireguard

Generate Public & Private key

Generate Private / Public Key and store it in /etc/wireguard/

#Create a new directory
mkdir /etc/wireguard/

#Generate key and stoee it in file
wg genkey | tee /etc/wireguard/privatekey | wg pubkey > /etc/wireguard/publickey

Configuration file for WireGuard

Create WireGuard Server Config in /etc/wireguard/wg0.conf

# Create a new configuration 
touch /etc/wireguard/wg0.conf
# Secure the wg.conf file by allowing only root access
chmod 600 etc/wireguard/wg0.conf
-rw------- 1 root root 182 Apr  5 22:21 wg0.conf

You are warned with `/etc/wireguard/wg0.conf’ is world accessible later if wg0.conf is not secure

[root@centos wireguard]# wg-quick up wg0
Warning: `/etc/wireguard/wg0.conf' is world accessible

Add the configuration below to /etc/wireguard/wg0.conf

  • cat /etc/wireguard/privatekey
  • cat /etc/wireguard/publickey
[Interface]
#IP Address of wg0
Address = 172.16.0.222/24
#Listening Port
ListenPort = 34897
#Private Key of Server
PrivateKey = UElRF8Ra7d+kLeUxxxxxxxxxxxxx

[Peer]
#Public key of Windows 10 Client
PublicKey = uoQ6RYLPQkT2Hy9xxxxxxxxxxxxxxxxx
AllowedIPs = 172.16.0.100/32

[Peer]
#Public key of ubuntu
PublicKey = enUrsuEMrYXGuxxxxxxx
AllowedIPs = 172.16.0.102/32

[Peer]
#Site to Site Tunnel
PublicKey = JSWAcnywicyxxxxxxxxxx
AllowedIPs = 172.16.0.222/32, 10.10.10.0/24
Endpoint = 103.18.xxx.xxx:34897
PersistentKeepalive = 15

Enable and start WireGuard service

wg-quick is a simple script provided to bring up or down WireGuard interface

systemctl enable --now wg-quick@wg0 

#Verify wireguard is listening on UDP:34897
ss -tulpn 

Netid     State       Recv-Q      Send-Q            Local Address:Port              Peer Address:Port
udp       UNCONN      0           0                       0.0.0.0:34897                  0.0.0.0:*
udp       UNCONN      0           0                          [::]:34897                     [::]:*

Firewalld Rules

Create a new service file /etc/firewalld/services/wireguard.xml with the content below

<?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="34897"/>
</service>

Allow WireGuard in Firewalld

firewall-cmd --permanent --add-service=wireguard --zone=public
firewall-cmd --reload

Public Access for WireGuard UDP Port

Configure NAT in FortiGate Firewall to forward UDP 34897 to CentOS 8

Access Rule to allow UDP 34897 from WAN to LAN

Site to Site VPN with WireGuard

Setup another CentOS 8 following the steps above in 2nd Site, and add the following to /etc/wireguard/wg0.conf

[Interface]
Address = 172.16.0.1/24
ListenPort = 34897
PrivateKey = UElRF8Ra7d+kLxxxxxxxxxxxxxxxxxxxxxx

[Peer]
#Site to Site Tunnel
PublicKey = JSWAcnywicyM+0kxgoQRZ0rS5MAEG8uR642KvpjK/XM=
AllowedIPs = 172.16.0.222/32, 10.10.10.0/24
Endpoint = 103.18.246.222:34897
PersistentKeepalive = 15

Enable NAT (masquerade) on both CentOS 8 Server

firewall-cmd --permanent --zone=public --add-masquerade
firewall-cmd --reload

Servers located at both sites should be access to each other for now

Wg status from CentOS 8 (192.168.1.236)

[root@centos ~]# wg
interface: wg0
  public key: Kr5iuM5pYDxxxxxxxxxxxxxxxxxxx
  private key: (hidden)
  listening port: 34897

peer: JSWAcnywicyxxxxxxxxxxxxxxxxxx
  endpoint: 103.18.xxx.xxx:34897
  allowed ips: 172.16.0.222/32, 10.10.10.0/24
  latest handshake: 7 seconds ago
  transfer: 1.75 MiB received, 1.72 MiB sent
  persistent keepalive: every 15 seconds

Wg status from CentOS 8 (10.10.10.224)

[root@centos ~]# wg
interface: wg0
  public key: JSWAcnywicxxxxxxxxxxxxxxxxx
  private key: (hidden)
  listening port: 34897

peer: Kr5iuM5pYDxte0RSSpxxxxxxxxxxxxxxxxxxxxxxx
  endpoint: 121.121.xxx.xxx:34897
  allowed ips: 172.16.0.1/32, 192.168.1.0/24
  latest handshake: 52 seconds ago
  transfer: 1.72 MiB received, 1.77 MiB sent
  persistent keepalive: every 15 seconds

VPN with WireGuard – Client for Windows 10

  1. Download and install WireGuard for Windows for x64
  2. Update WireGuard is prompted

  1. Select Add empty tunnel

  1. Enter the following
[Interface]
#Auto Generated 
PrivateKey = KA7tO/xxxxxxxxxxxxxxxxxxxxxxx
#IP Address for WireGuard
Address = 172.16.0.100/24

[Peer]
#Public Key of CentOS 8 Server
PublicKey = JSWAcnywxxxxxxxxxxxxxxxxxxxxxx
#Forward the following IP range via WireGuard tunnel 
# 10.10.10.0/24 - Internal Servers in Corporate Office
AllowedIPs = 172.16.0.0/24,10.10.10.0/24
#End Point address of CentOS 8 WireGuard 
Endpoint = 103.18.xxx.xxx:34897
# Send keep alive packet to WireGuard every 15 Seconds
PersistentKeepalive = 15

NAT and stateful firewalls keep track of "connections", if a peer behind NAT or a firewall wishes to receive incoming packets, he must keep the NAT/firewall mapping valid, by periodically sending keepalive packets. This is called persistent keepalives

  1. Click Activate to connect to WireGuard Server and verify

Ping to 172.16.0.222 (IP of CentOS 8 wg0) successfully

Access to 10.10.10.100 (IP of Internal Server) successfully

VPN with WireGuard – Client for Ubuntu

Steps to connect from ubuntu 18.04 desktop

Install WireGuard

$ sudo add-apt-repository ppa:wireguard/wireguard
$ sudo apt-get update
$ sudo apt-get install wireguard
$ sudo modprobe wireguard

Switch to root to generate the Private / Public Key and wg0.conf file

su -
wg genkey | tee /etc/wireguard/privatekey | wg pubkey > /etc/wireguard/publickey

touch /etc/wireguard/wg0.conf
chmod 600 /etc/wireguard/wg0.conf 

Add the content below to /etc/wireguard/wg0.conf

root@ubuntu1804:~# cat /etc/wireguard/wg0.conf 
[Interface]
Private Key = SB9/pWV2Uxxxxxxxxxxxxxxxxxxxxxxx
Address = 172.16.0.102/24

[Peer]
PublicKey = JSWAcnywicxxxxxxxxxxxxxxxxxxxxxx
AllowedIPs = 172.16.0.0/24,10.10.10.0/24
Endpoint = 103.18.xxx.xxx:34897
PersistentKeepalive = 15

Enabled and start WireGuard Services with wg-quick@wg0

sudo systemctl enable --now wg-quick@wg0 

Verify the WireGuard Tunnel with sudo wg and try to

  • Ping to 172.16.0.222 (CentOS 8 wg0) successfully
  • Ping to 10.10.10.100 (Internal Server) and able to access file share with SMB successfully

Appendix

Disable Secure Boot

Ensure that CentOS 8 installed on VMware ESXi host is configured with Secure Boot Disabled

WireGuard on CentOS 8

WireGuard Module failed to load with Secure Boot Enabled

[root@centos ~]# modprobe wireguard
modprobe: ERROR: could not insert 'wireguard': Required key not available

[root@centos ~]# dmesg | grep -i secure
[    0.000000] secureboot: Secure boot enabled
[    0.000000] Kernel is locked down from EFI secure boot; see man kernel_lockdown.7
[    0.873960] integrity: Loaded X.509 cert 'CentOS Secure Boot (key 1): f037c6eaec36d4057a526c0ec6d5a95b324ee129'

NAT Issue

We noticed that the connection between 2 servers are translated to the interface IP of CentOS 8 Server

C:\Users\Administrator>netstat
Active Connections
  Proto  Local Address          Foreign Address        State
  TCP    10.10.10.100:445       10.10.10.224:60387     ESTABLISHED
  TCP    10.10.10.100:3389      10.10.10.224:61251     ESTABLISHED

We had to disabled Firewalld

systemctl stop firewalld 

The source IP address of server is displayed in Netstat with Firewalld disabled

C:\Users\Administrator>netstat
Active Connections
  Proto  Local Address          Foreign Address        State
  TCP    10.10.10.100:445       centos:60387           ESTABLISHED
  TCP    10.10.10.100:3389      192.168.1.232:61258    ESTABLISHED

We are doing some research to see whether is it possible to disabled NAT (masquerade) in Firewalld, and will update on this issue soon

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top