Wireguard is an open-source VPN protocol alternative to IPSec, IKEv2, and OpenVPN. Wiruguard is designed for Linux and Unix operating systems, it runs on Linux kernel space, which makes the Wireguard faster and more reliable. Wireguard is used to create secure tunnel connections between two computers or more.

Wireguard aims to replace VPN protocols such as IPSec, IKEv2, and OpenVPN. Wireguard is lighter, faster, easy to set up, and more efficient. And at the same time, Wiregurad did not sacrifice the security aspect of the VPN protocol. Wireguard supports modern cryptography like the Noise protocol framework, Curve25519, ChaCha20, Poly1305, BLAKE2, SipHash24, HKDF, and secure trusted constructions.

Compared to other VPN protocols such as OpenVPN, IPSec, and IKEv2, wireguard is a new VPN protocol. Wireguard is released in 2015 by Jason A. Donenfeld as an alternative VPN protocol, It was merged to the Linux kernel v5.6 by Linus Torvalds in 2020 and the same year, also ported to FreeBSD 13.

This guide teaches you how to install and set up Wirgeuard Server on a Rocky Linux 9 server. You’ll also learn how to set up a client machine to connect to the Wireguard server.

You can use any Linux distribution as a client machine in this example. But this guide will use the Rocky Linux client machine, one of the RHEL9-based distributions.

Prerequisite

To start with this guide, you  must ensure that you have the following requirements:

  • A Rocky Linux 9 server – This example uses a Rocky Linux with hostname ‘wireguard-rocky‘.
  • A non-root user with sudo/root administrator privileges.
  • An SELinux is running in permissive mode.

Now with the prerequisites ready, you can now start installing and configuring the Wireguard server.

Enable Wireguard Kernel Module

The latest version of Rocky Linux 9 shipped with default Linux kernel 5.14, which is by default the ‘wireguard’ kernel module embedded on top of it. In this step, you’ll enable the Wirguard kernel module and install the ‘wireguard-tools’ on your Rocky Linux server.

Run the below modprobe command to enable the ‘wireguard’ kernel module. Then, verify the list of enabled kernel modules via the ‘lsmod’ command.

sudo modprobe wireguard

lsmod | grep wireguard

If the ‘wireguard‘ kernel module is enabled, you should receive an output similar to the following:

<img alt="enable wireguard" data-ezsrc="https://kirelos.com/wp-content/uploads/2023/01/echo/1-enable-wireguard.png63c7eb5758f5f.jpg" ezimgfmt="rs rscb5 src ng ngcb5" height="262" loading="lazy" src="data:image/svg xml,” width=”602″>

To load the wireguard module permanently, you can run the below command to add the new config file to ‘/etc/modules-load.d/’ directory. This will load the wireguard kernel module permanently at system boot.

sudo echo wireguard > /etc/modules-load.d/wireguard.conf

After the ‘wireguard‘ kernel module is enabled, you must install the ‘wireguard-tools‘ package to manage the Wireguard server. This includes generating keys, starting the Wireguard server, and many more.

Run the dnf command below to install ‘wireguard-tools‘. When prompted for confirmation, input y and press ENTER to proceed.

sudo dnf install wireguard-tools

Now the ‘wireguard-tools‘ installation should begin.

<img alt="install wireguard tools" data-ezsrc="https://kirelos.com/wp-content/uploads/2023/01/echo/2-install-wireguard-tools.png63c7eb578f384.jpg" ezimgfmt="rs rscb5 src ng ngcb5" height="219" loading="lazy" src="data:image/svg xml,” width=”750″>

Your Rocky Linux server now has the ‘wireguard‘ kernel module enabled and the ‘wireguard-tools‘ installed. Next, you’ll go over how to generate key pairs for both the Wireguard server and client via the wireguard-tools.

Generating Server and Client Key Pair

The wireguard-tools provide a user-space command line for managing Wireguard deployment. Two major utilities provided by wireguard-tools:

  • wg – a command line utility that can be used to set up the wireguard tunnel interface. With this utility, you can generate key pairs, verify the current wireguard runtime and interface, and set up the Wireguard tunnel interface.
  • wg-quick – a simple command line that can manage the Wireguard interface. You can start, stop, and restart any wireguard interfaces via the wg-quick command.

The first step after enabling the wireguard kernel module and installing wireguard-tools is generating key pairs for both the Wireguard server and client. And this can be done via the ‘wg‘ command utility.

Generating Server Key Pair

Run the below ‘wg genkey’ command to generate the server private key ‘/etc/wireguard/server.key‘. Then, change the default permission to ‘0400‘ to disable write and execute from others and groups.

wg genkey | sudo tee /etc/wireguard/server.key

sudo chmod 0400 /etc/wireguard/server.key

After that, run the below command to generate the public key for the wireguard server ‘/etc/wireguard/server.pub‘. The wireguard public key is derived from the wireguard private key ‘/etc/wireguard/server.key‘.

sudo cat /etc/wireguard/server.key | wg pubkey | sudo tee /etc/wireguard/server.pub

Output:

<img alt="generate server key pair" data-ezsrc="https://kirelos.com/wp-content/uploads/2023/01/echo/3-generate-server-key-pair.png63c7eb57c58bd.jpg" ezimgfmt="rs rscb5 src ng ngcb5" height="179" loading="lazy" src="data:image/svg xml,” width=”750″>

Next, verify both the wireguard server’s public and private keys via the cat command below.

cat /etc/wireguard/server.key

cat /etc/wireguard/server.pub

You may have a different key for both public and private keys, but the output is similar to this:

<img alt="verify server key pair" data-ezsrc="https://kirelos.com/wp-content/uploads/2023/01/echo/4-verify-server-key-pair.png63c7eb57f0f0e.jpg" ezimgfmt="rs rscb5 src ng ngcb5" height="194" loading="lazy" src="data:image/svg xml,” width=”575″>

Generating Client Key Pair

After generating the wireguard server key pair, you’ll generate a new one for the client. In this example, you’ll generate a new key pair with the name ‘client1‘.

Run the below command to create a new directory ‘/etc/wireguard/clients‘. This directory will be used to store client key pairs.

mkdir -p /etc/wireguard/clients

Next, run the below ‘wg genkey’ command to generate the client private key ‘/etc/wireguard/clients/client1.key‘. Then, generate the client public key ‘/etc/wireguard/clients/client1.pub‘ via the ‘wg pubkey‘ command.

wg genkey | tee /etc/wireguard/clients/client1.key

cat /etc/wireguard/clients/client1.key | wg pubkey | tee /etc/wireguard/clients/client1.pub

Output:

<img alt="generate client key pair" data-ezsrc="https://kirelos.com/wp-content/uploads/2023/01/echo/5-generate-lcient-key-pair.png63c7eb582ee47.jpg" ezimgfmt="rs rscb5 src ng ngcb5" height="168" loading="lazy" src="data:image/svg xml,” width=”750″>

Now verify both client’s public and private keys using the cat command below.

cat /etc/wireguard/clients/client1.key

cat /etc/wireguard/clients/client1.pub

The key should be similar for both the wireguard server and client key pair, which is a base64-like key.

<img alt="verify client key pair" data-ezsrc="https://kirelos.com/wp-content/uploads/2023/01/echo/6-verify-client-key-pair.png63c7eb585d024.jpg" ezimgfmt="rs rscb5 src ng ngcb5" height="196" loading="lazy" src="data:image/svg xml,” width=”631″>

Configuring Wireguard Server

In this step, you’ll create a new config file for the wireguard server, set up the wireguard interface, and set up peer connection for client connections. This includes the configuration of the wireguard VPN subnet, the IP address from the wireguard server, and the IP address for the peer client.

To start, Create a new wireguard server config file /etc/wireguard/wg0.conf’ using the below nano editor command.

sudo nano /etc/wireguard/wg0.conf

Add the following lines to the file and be sure to change the ‘PrivateKey‘ with the Wirguard server private key ‘server.key‘. With this, you’ll also set up the Wireguard server interface to be run at IP address ‘10.8.0.1‘. And for client connection, you’ll be using the UDP port 51820. And lastly, you’ll also enable the SaveConfig parameter that will ensure any changes are saved to the wireguard configuration file, even when the Wireguard interface is off.

[Interface]

# Wireguard Server private key - server.key

PrivateKey = iHaI5bkEbW8wqTQDbU/KITGhxtKoiezWVohVZsKwj3w=

# Wireguard interface will be run at 10.8.0.1

Address = 10.8.0.1/24

# Clients will connect to UDP port 51820

ListenPort = 51820

# Ensure any changes will be saved to the Wireguard config file

SaveConfig = true

Next, add the following lines to define the client peer connection. Be sure to change the ‘PublicKey‘ parameter with the client public key ‘client1.pub‘. With the ‘AllowedIPs‘ parameter, you can specify which Wireguard client that allowed to access this peer. In this example, only clients with IP ‘10.8.0.8‘ will be allowed to access this peer connection. Additionally, you can also allow the range of internal network subnets such as ‘172.16.100.0/24’ to access the wireguard peer.

[Peer]

# Wireguard client public key - client1.pub

PublicKey = iWskvxyj QK4185xO6Z2Fb0XYo1jGyiyI3iKbyGTkT8=

# clients' VPN IP addresses you allow to connect

# possible to specify subnet ⇒ [172.16.100.0/24]

AllowedIPs = 10.8.0.8/24

Save and exit the file when finished.

With this, you’ve now created the basic configuration for the Wreguard server. Also, you’ve defined peer connection for the client using the client public key ‘client1.pub‘. In the next step, set up the port forwarding on the wireguard server and set up the firewalld rules for traffic routing.

Setting up Port Forwarding

To set up any VPN server, you must enable port forwarding on your deployment server. In this step, you’ll enable port forwarding on your Rocky Linux server via the ‘/etc/sysctl.conf’ file.

Open the config file ‘/etc/sysctl.conf‘ using the nano editor below.

sudo nano /etc/sysctl.conf

Add the following lines to the bottom of the line. These lines will enable port forwarding for both IPv4 and IPv6. Whether you need IPv6 or not, you can disable it by putting a comment ‘#‘ at the start of the line.

# Port Forwarding for IPv4

net.ipv4.ip_forward=1

# Port forwarding for IPv6

net.ipv6.conf.all.forwarding=1

Save the file and exit the editor when finished.

Now run the below ‘sysctl‘ command to apply the changes on the ‘/etc/sysctl.conf‘ file.

sudo sysctl -p

And you’ll receive an output similar to this:

<img alt="enable port forwarding" data-ezsrc="https://kirelos.com/wp-content/uploads/2023/01/echo/7-enable-port-forwearding.png63c7eb588c86f.jpg" ezimgfmt="rs rscb5 src ng ngcb5" height="268" loading="lazy" src="data:image/svg xml,” width=”613″>

With Port-Forwarding enabled, you’ll next set up a firewalld that will be used to route traffics from clients to the specific network interface on the wireguard server.

Setting up Firewalld

You’ll set up the firewalld on the Wireguard server in this step. You’ll route client traffics to the specific network interface on the wireguard server via firewalld. And this can be done by adding new rules to firewalld permanently, or by using the wireguard ‘PostUp‘ and ‘PostDown‘ parameters in the Wireguard configuration file.

Before you start, run the below ip command to check the default network interface that is used for internet access on the wireguard server.

ip route show default

You’ll receive an output similar to this – In this example, the wireguard server used interface eth0 for internet access. You may have different names of network interfaces on your server.

<img alt="show default route" data-ezsrc="https://kirelos.com/wp-content/uploads/2023/01/echo/8-show-default-route.png63c7eb58bc147.jpg" ezimgfmt="rs rscb5 src ng ngcb5" height="126" loading="lazy" src="data:image/svg xml,” width=”695″>

Next, open the wireguard server config file ‘/etc/wireguard/wg0.conf‘ using the below nano editor command.

sudo nano /etc/wireguard/wg0.conf

Add the following lines to the ‘[Interface]‘ section.

PostUp = firewall-cmd --zone=public --add-masquerade

PostUp = firewall-cmd --direct --add-rule ipv4 filter FORWARD 0 -i wg -o eth0 -j ACCEPT

PostUp = firewall-cmd --direct --add-rule ipv4 nat POSTROUTING 0 -o eth0 -j MASQUERADE

PostDown = firewall-cmd --zone=public --remove-masquerade

PostDown = firewall-cmd --direct --remove-rule ipv4 filter FORWARD 0 -i wg -o eth0 -j ACCEPT

PostDown = firewall-cmd --direct --remove-rule ipv4 nat POSTROUTING 0 -o eth0 -j MASQUERADE

Save and exit the file.

  • The ‘PostUp‘ parameter will be executed whenever the Wirguard server starts the VPN tunnel.
  • The ‘PostDown‘ parameter will be executed whenever the Wireguard server stops the VPN tunnel.
  • The command ‘firewall-cmd –zone=public –add-masquerade‘ will enable masquerade on firewalld.
  • The command ‘firewall-cmd –direct –add-rule ipv4 filter FORWARD 0 -i wg -o eth0 -j ACCEPT‘ will add firewalld rich-rule for traffics from the wireguard interface to eth0.
  • The command ‘firewall-cmd –direct –add-rule ipv4 nat POSTROUTING 0 -o eth0 -j MASQUERADE‘ will enable NAT through the eth0 interface.
  • In the ‘PostDown‘ parameter, all of these commands are used to revert the changes on firewalld by removing rules that were applied during commands on the ‘PostUp‘ parameter executed.

Next, run the below firewall-cmd command to open the UDP port 51820 that will be used for wirguard clients. Then, reload the firewalld to apply the changes.

sudo firewall-cmd --add-port=51820/udp --permanent

sudo firewall-cmd --reload

Lastly, verify firewalld rules via the below firewall-cmd command.

sudo firewall-cmd --list-all

You should receive an output like this – The wireguard client port 51820/udp added to the firewalld.

<img alt="setup firewalld" data-ezsrc="https://kirelos.com/wp-content/uploads/2023/01/echo/9-setup-firewalld.png63c7eb5904dde.jpg" ezimgfmt="rs rscb5 src ng ngcb5" height="391" loading="lazy" src="data:image/svg xml,” width=”730″>

With this, you’ve now enabled port forwarding on the wireguard server and configured the firewalld to route traffic from the wireguard interface to the specific network interface. You’re now ready to start the wireguard server.

Starting Wireguard Server

In this step, you’ll start and enable the Wireguard server. You’ll also verify the Wireguard server and verify the wg0 interface that will be created by the Wireguard service.

Run the below systemctl command utility to start and enabled the wireguard server. This will start the wireguard service and create a new wireguard interface ‘wg0‘.

sudo systemctl start [email protected]

sudo systemctl enable [email protected]

Verify the wireguard server using the below systemctl command. This will ensure that the wireguard server is running.

sudo systemctl status [email protected]

And you’ll receive output similar to this – The wireguard server is now enabled and will be run automatically upon the bootup. And the status of the wireguard server is running.

<img alt="start verify wireguard server" data-ezsrc="https://kirelos.com/wp-content/uploads/2023/01/echo/10-start-verify-wireguard-server.png63c7eb59361ce.jpg" ezimgfmt="rs rscb5 src ng ngcb5" height="305" loading="lazy" src="data:image/svg xml,” width=”750″>

You can also verify the interface ‘wg0’ that is created by the wireguard server via the ip command below.

ip a show wg0

You’ll receive the detailed interface of wg0, which is matched with the wireguard server config file ‘/etc/wireguard/wg0.conf’. The wg0 interface should have an IP address ‘10.8.0.1‘ as described in the wireguard config file ‘/etc/wireguard/wg0.conf‘.

<img alt="verify wireguard ip" data-ezsrc="https://kirelos.com/wp-content/uploads/2023/01/echo/11-verify-wireguard-server-ip.png63c7eb595f23c.jpg" ezimgfmt="rs rscb5 src ng ngcb5" height="197" loading="lazy" src="data:image/svg xml,” width=”598″>

Another method that can be used to start the wireguard server is by using the ‘wg-quick‘ command utility that provides by wireguard-tools.

Run the ‘wg-quick up‘ to start the wireguard server and the ‘wg-quick down‘ to stop the wireguard server. Also, be sure to specify the full path of your wireguard server config file ‘/etc/wireguard/wg0.conf‘.

sudo wg-quick up /etc/wireguard/wg0.conf

sudo wg-quick down /etc/wireguard/wg0.conf

At this point, the wireguard server is running on the Rocky Linux server. In the next step, you’ll set up a client machine and connect it to the wireguard server.

Setting up Client and Connecting to Wireguard Server

In this step, you’ll set up a wireguard on a Linux client machine, then connect the client machine to the wireguard server. This example uses a Rocky Linux with the hostname ‘client1’ as a client machine, but you can also use any Linux distribution.

Log in to the client machine and run the below dnf command to install the wireguard-tools package to your client. This operation also installs the dependency ‘systemd-resolved’ that will be used by wireguard-tools for managing the DNS resolver.

sudo dnf install wireguard-tools

Input y when prompted and press ENTER to proceed.

<img alt="install wireguaard tools" data-ezsrc="https://kirelos.com/wp-content/uploads/2023/01/echo/13-install-wireguard-tools.png63c7eb598d766.jpg" ezimgfmt="rs rscb5 src ng ngcb5" height="262" loading="lazy" src="data:image/svg xml,” width=”750″>

During the ‘wireguard-tools‘ installation, the systemd-resolved package is also installed as a dependency.

Run the below command to start and enable the ‘systemd-resolved‘ service.

sudo systemctl start systemd-resolved

sudo systemctl enable systemd-resolved

With the wireguard-tools installed and the systemd-resolved running, you’ll next set up the NetworkManager to use the ‘systemd-resolved‘ as the DNS backend.

Open the NetworkManager config file ‘/etc/NetworkManager/NetworkManager.conf‘ using the below nano editor command.

sudo nano /etc/NetworkManager/NetworkManager.conf

Add the ‘dns’ parameter to the ‘[main]‘ section as below.

[main]

dns=systemd-resolved

Save the file and exit the editor.

Next, run the below command to remove the ‘/etc/resolv.conf‘ file and create a new symlink file of the ‘resolv.conf‘ file managed by systemd-resolved.

rm -f /etc/resolv.conf

sudo ln -s /usr/lib/systemd/resolv.conf /etc/resolv.conf

Now restart the NetworkManager service to apply the changes.

sudo systemctl restart NetworkManager

Now that the NetworkManager is configured, you are now ready to set up the wireguard client.

Create a new file ‘/etc/wireguard/wg-client1.conf’ using the below nano editor.

sudo nano /etc/wireguard/wg-client1.conf

Add the following lines to the file.

[Interface]

# Define the IP address for the client - must be matched with wg0 on Wireguard Server

Address = 10.8.0.8/24

# Private key for the client - client1.key

PrivateKey = 4FsCdtKr9GrLiX7zpNEYeqodMa5oSeHwH/m9hsNNfEs=

# Run resolvectl command

PostUp = resolvectl dns %i 1.1.1.1 9.9.9.9; resolvectl domain %i ~.

PreDown = resolvectl revert %i

[Peer]

# Public key of the Wireguard server - server.pub

PublicKey = aK MQ48PVopb8j1Vjs8Fvgz5ZIG2k6pmVZs8iVsgr1E=

# Allow all traffic to be routed via Wireguard VPN

AllowedIPs = 0.0.0.0/0

# Public IP address of the Wireguard Server

Endpoint = 192.168.5.59:51820

# Sending Keepalive every 25 sec

PersistentKeepalive = 25

Save the file and exit the editor when finished.

In the ‘[Interface]‘ section, you must define the following:

  • The IP address of the client must be matched with the subnet of the Wireguard server. The Wireguard client will get the IP address ‘10.8.0.8’ in this example.
  • Specify the DNS server for the client via the resolvectl command.
  • Change the ‘PrivateKey‘ parameter with the client private key that you’ve generated ‘client1.key‘.

In the ‘[Peer]‘ section, you must add the following:

  • Wireguard server public key ‘server.pub‘ to the PublicKey parameter.
  • Specify ‘AllowedIPs‘ to restrict access on the VPN peer, you can specify subnets of networks or you can just put 0.0.0.0/0 to tunnel all traffic over VPN.
  • Specify the Endpoint parameter with the public IP address of the Wireguard server or you can also use a domain name.

With the wireguard client config file created, you can run wireguard on the client machine via the ‘wg-quick up‘ command below.

wg-quick up wg-client1

You’ll receive an output similar to this – The new wireguard interface ‘wg-client1‘ is created and get an IP address ‘10.8.0.8‘.

<img alt="start wireguard client" data-ezsrc="https://kirelos.com/wp-content/uploads/2023/01/echo/20-start-wireguard-client.png63c7eb59bbb0a.jpg" ezimgfmt="rs rscb5 src ng ngcb5" height="365" loading="lazy" src="data:image/svg xml,” width=”750″>

Now verify the ‘wg-client1‘ interface via the ip command below.

ip a show wg-client1

Below is a similar output that will be printed to your terminal.

<img alt="verify wg client" data-ezsrc="https://kirelos.com/wp-content/uploads/2023/01/echo/14-verify-wireguard-client.png63c7eb5a126dc.jpg" ezimgfmt="rs rscb5 src ng ngcb5" height="196" loading="lazy" src="data:image/svg xml,” width=”549″>

You can also verify the DNS resolver on the wg-client1 interface via the ‘resolvectl‘ command below.

resolvectl status wg-client1

Below is the output you’ll receive on your terminal – The wireguard interface wg-client1 used a DNS resolver defined via the ‘PostUp‘ parameter, which is using the ‘systemd-resolved‘.

<img alt="verify resolver" data-ezsrc="https://kirelos.com/wp-content/uploads/2023/01/echo/21-verify-resolver.png63c7eb5a3ffaa.jpg" ezimgfmt="rs rscb5 src ng ngcb5" height="226" loading="lazy" src="data:image/svg xml,” width=”750″>

In addition to that, you can also verify the Wireguard connection via the ‘wg show‘ command.

Run the ‘wg show‘ command on the wireguard client machine and you will receive an output like the below screenshot.

wg show

The wireguard server IP address should be shown in the ‘endpoint‘ section. Also, you can see the wireguard server public key ‘server.pub‘.

<img alt="wge show client" data-ezsrc="https://kirelos.com/wp-content/uploads/2023/01/echo/15-wg-show-client.png63c7eb5a74bc4.jpg" ezimgfmt="rs rscb5 src ng ngcb5" height="344" loading="lazy" src="data:image/svg xml,” width=”578″>

Back to the wireguard server and run the ‘wg show‘ command below.

wg show

Below is the similar output you’ll receive on your terminal –  On the endpoint section, you’ll see the client’s public IP address and on the peer section you’ll see the client public key ‘client1.pub‘.

<img alt="wg show server" data-ezsrc="https://kirelos.com/wp-content/uploads/2023/01/echo/16-wg-show-server.png63c7eb5aa5bb8.jpg" ezimgfmt="rs rscb5 src ng ngcb5" height="333" loading="lazy" src="data:image/svg xml,” width=”596″>

Lastly, run the below command to ensure that the client machine can access the internet or access the internal network subnet of the Wireguard VPN.

ping -c5 10.8.0.1

ping -c5 1.1.1.1

ping -c5 duckduckgo.com

Below is the output you should receive:

The client machine can connect to the Wireguard server that has an IP address ‘10.8.0.1‘.

<img alt="verify ping wireguard server" data-ezsrc="https://kirelos.com/wp-content/uploads/2023/01/echo/17-verify-ping-wireguard-server.png63c7eb5ad6f62.jpg" ezimgfmt="rs rscb5 src ng ngcb5" height="311" loading="lazy" src="data:image/svg xml,” width=”584″>

The client machine can access the internet. All traffic is routed via the Wireguard server’s public IP address.

<img alt="verify ping internet" data-ezsrc="https://kirelos.com/wp-content/uploads/2023/01/echo/18-verify-ping-internet.png63c7eb5b15751.jpg" ezimgfmt="rs rscb5 src ng ngcb5" height="319" loading="lazy" src="data:image/svg xml,” width=”572″>

Now you’ve configured the wireguard VPN on the client machine. You’ve also verified the connection between the client machine to the wireguard server.

Conclusion

In this guide, you have installed and configured the wireguard VPN server on Rocky Linux 9. You’ve also learned how to set up the Rocky Linux client machine to connect to the wireguard server. Along with this, you have also learned how to enable port forwarding and set up NAT via firewalld.

Lastly, you’ve learned basic usages of the ‘wg’ command utility for generating public and private key pairs and verifying wireguard VPN connections. Then, you’ve also learned how to use the ‘wg-quick’ command to start and stop the wireguard connection.

If you want to learn more about WireGuard, visit the WireGuard documentation. Also, you can visit GitHub topics related to Wireguard to find automation deployment for WireGuard VPN Server.