How to setup a VPN on CentOS using Wireguard
Hi folks, today, we will learn how to setup Wireguard as VPN on CentOS.
This tutorial has been tested on CentOS 8.
Keep also in mind that Wireguard is different than OpenVPN for example because there is no concept of client/server, but only peers. So in my example, I will be using the CentOS as a « server » and the iOS as a « client » but in reality it’s just a point to point VPN between two machines.
Installation
Wireguard is not included in CentOS’s main repositories so you have to add additional repos to install it:
dnf install elrepo-release epel-release
dnf install kmod-wireguard wireguard-tools
As Wireguard is a kernel module, you will need to check if it’s enabled and enable it if it’s not.
To check if you will have to do so:
lsmod | grep wireguard
If it’s ok, you will get something like this:
root@centos:~# lsmod | grep wireguard
wireguard 208896 0
ip6_udp_tunnel 16384 1 wireguard
udp_tunnel 16384 1 wireguard
If you get nothing, you will have to enable it either :
- Manually for one time:
modprobe wireguard
- Automatically so it starts at boot:
echo "wireguard" > /etc/modules-load.d/wireguard.conf
Configuration
There are many ways to configure Wireguard. I will present you one that works but feel free to research for other methods.
Wireguard works kinda like OpenSSH, each peer have a pair of private and public key but unlike OpenSSH, Wireguard needs to know each public keys and private IP address of each peer he will allow the connection.
All the following commands will be performed on Ubuntu which as said previously will be our « server ».
Server configuration
Create private and public keys
mkdir /etc/wireguard
cd /etc/wireguard
wg genkey | tee privatekey | wg pubkey > publickey
Then, create a configuration file for wg0 which will be our device for routing.
/etc/wireguard/wg0.conf
[Interface]
Address = 192.168.2.1/24
ListenPort = 51820
PrivateKey = SERVER_PRIVATE_KEY
[Peer]
# iphone
PublicKey = PEER_IPHONE_PUBLIC_KEY
AllowedIPs = 192.168.2.2/32
Adress: Here we define a network in /24, feel free to change it.
ListenPort: We also make our "server" listen on port 51820 in UDP so don't forget to open it in your firewall(s).
PrivateKey: Replace SERVER_PRIVATE_KEY by the content of /etc/wireguard/privatekey.
Leave PEER_IPHONE_PUBLIC_KEY for now, we will replace it after with our client's public key.
AllowedIPs: Change the AllowedIPs if you change the network or if you want to attribute another IP to your peer/client.
Client configuration
We will host "clients" keys and configuration files on the "server" in that example. But you can also generate them on your client and keep them safely there. It's up to you. {: .notice--info}
Create a new directory to put client's configuration files
mkdir -p /etc/wireguard/clients/iphone
Generate private and public keys
cd /etc/wireguard/clients/iphone
wg genkey | tee privatekey | wg pubkey > publickey
Create client's configuration file
/etc/wireguard/clients/iphone/iphone.conf
[Interface]
Address = 192.168.2.2/24
PrivateKey = PEER_IPHONE_PRIVATE_KEY
DNS = 192.168.2.1
[Peer]
PublicKey = SERVER_PUBLICKEY
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = ubuntu.mydomain.com:51820
Address: Client’s IP address, it has to match the one you defined in the server’s configuration.
PrivateKey: Replace PEER_IPHONE_PRIVATE_KEY by the content of /etc/wireguard/clients/iphone/privatekey
DNS: Put whatever DNS you want.
PublicKey: Replace SERVER_PUBLICKEY by the content of /etc/wireguard/publickey.
AllowedIPs: Allow specific IP if it's a static one or all if it's dynamic IP.
Endpoint: Specify the hostname or IP of your server and the port.
In /etc/wireguard/wg0.conf, replace PEER_IPHONE_PUBLIC_KEY by the content of /etc/wireguard/clients/iphone/publickey
Start Wireguard at boot
You can simply use systemd and wg-quick to enable and start your interface:
systemctl enable wg-quick@wg0
systemctl start wg-quick@wg0
Mobile clients configuration
Create configuration manually
This is self-explanatory, you actually create the config on the mobile device then transfer the relevant keys to the server's config.
Create configuration from archive
Here you have to create a .zip archive of the client configuration file, transfer it to the device then import it into the app.
Import by reading a QR code (most secure method)
The mobile client supports QR code based input.
You need to install qrencode to generate a qr code from a configuration file:
apt install qrencode
Then call qrencode and pass the client configuration:
qrencode -t ansiutf8 < client.conf
This will generate a QR code that is readable by the mobile client.
The advantage of this approach is that there is no need to transfer sensitive information via data channels that can potentially be compromised and there is no need of any other supplementary software besides a terminal or console.
Conclusion
I hope you enjoyed this small tutorial about WireGuard on CentOS 8.
Feel free to comment below :D