Share on Social Media

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. #centlinux #linux #vpn

What is WireGuard?

WireGuard is a modern, high-performance VPN (Virtual Private Network) protocol designed to be simpler, faster, and more secure than traditional VPN protocols like IPsec and OpenVPN. Developed by Jason A. Donenfeld and released under the GPLv2 license, WireGuard aims to provide a robust and efficient solution for secure network communication. Here are some key features and aspects of WireGuard:

  • Simplicity: WireGuard is known for its minimal codebase, which makes it easier to audit and maintain compared to more complex protocols. This simplicity also contributes to its enhanced security.
  • Performance: WireGuard is designed to be highly performant, leveraging modern cryptographic algorithms and techniques. It operates at the network layer (Layer 3) and is integrated into the Linux kernel, providing low-latency and high-throughput communication.
  • Security: The protocol uses state-of-the-art cryptographic primitives like ChaCha20 for encryption, Poly1305 for authentication, and Curve25519 for key exchange. This ensures strong security while minimizing the risk of vulnerabilities.
  • Ease of Configuration: Configuring WireGuard is straightforward, involving the creation of simple configuration files. This ease of use extends to its deployment on various platforms, including Linux, Windows, macOS, Android, and iOS.
  • Cross-Platform Support: WireGuard is compatible with multiple operating systems, making it versatile for different environments and use cases. It has official support and third-party implementations for a wide range of systems.
  • Statelessness: Unlike traditional VPNs that maintain state and connections, WireGuard operates statelessly. This means it doesn’t keep persistent connections, leading to lower overhead and better performance.
  • Efficiency: WireGuard uses fewer resources compared to other VPN protocols, making it suitable for devices with limited processing power and memory.

In summary, WireGuard is a next-generation VPN protocol that emphasizes simplicity, performance, and security. Its efficient design and strong cryptographic foundations make it an attractive choice for securing network communications in various applications.

How WireGuard works?

WireGuard works by establishing a secure, encrypted tunnel between two devices, often referred to as peers. Here’s a detailed overview of how WireGuard operates:

1. Key Exchange

  • Asymmetric Cryptography: Each peer generates a pair of cryptographic keys: a private key and a public key. The private key is kept secret, while the public key is shared with other peers.
  • Pre-shared Keys: Optionally, WireGuard supports the use of pre-shared keys (PSKs) for an additional layer of security.

2. Configuration

  • Interface Configuration: Each peer configures a network interface for WireGuard. This involves setting up the private key, assigning IP addresses, and specifying the port WireGuard will listen on.
  • Peer Configuration: Peers exchange their public keys and other configuration details, such as allowed IP ranges (which define what traffic should be routed through the tunnel).

3. Connection Establishment

  • Handshake Process: When one peer wants to initiate a connection, it sends an initial handshake message to the other peer. This message includes the sender’s public key and other cryptographic data.
  • Response and Session Establishment: The receiving peer responds with its own handshake message, completing the key exchange process. Both peers now have all the necessary cryptographic information to establish a secure session.

4. Encryption and Decryption

  • ChaCha20 Encryption: Data sent through the WireGuard tunnel is encrypted using the ChaCha20 cipher. This ensures that the data is secure and cannot be read by unauthorized parties.
  • Poly1305 Authentication: Each packet is authenticated using the Poly1305 algorithm to ensure its integrity and authenticity.

5. Data Transmission

  • Stateless Operation: WireGuard does not maintain persistent connections. Instead, it uses a stateless model where each packet is encrypted and decrypted independently. This reduces overhead and improves performance.
  • Minimal Overhead: WireGuard’s packets have minimal overhead, meaning that the additional data added to each packet for security purposes is kept to a minimum. This helps in maintaining high throughput and low latency.

6. Roaming and Resilience

  • Seamless Roaming: WireGuard supports seamless roaming, allowing peers to change their IP addresses without breaking the connection. This is particularly useful for mobile devices that may move between different networks.
  • Resilience: If a peer temporarily loses connectivity, WireGuard can quickly re-establish the secure tunnel once the connection is restored, without requiring a full renegotiation of the session.

7. Firewall and NAT Traversal

  • UDP-Based: WireGuard operates over UDP, which makes it more efficient for firewall and NAT traversal compared to TCP-based VPNs. It can easily penetrate most firewalls and NAT configurations.
  • Portability: Since WireGuard operates at the network layer, it can be used to tunnel various types of traffic, including IPv4, IPv6, and custom protocols.

Summary

WireGuard works by leveraging modern cryptographic algorithms to establish secure, efficient, and low-latency VPN tunnels between peers. Its design emphasizes simplicity, performance, and security, making it suitable for a wide range of applications, from personal VPNs to enterprise networks. By operating in a stateless manner and using UDP for transport, WireGuard ensures robust and resilient connections with minimal overhead.

Recommended Online Training: VPN Tunneling Protocols on MikroTik with LABS

2476602 05dc 2show?id=oLRJ54lcVEg&offerid=1606991.2476602&bids=1606991

WireGuard vs. OpenVPN

WireGuard and OpenVPN are two popular VPN protocols, each with its own strengths and weaknesses. Here’s a comparison to help you understand the key differences and decide which one might be the best fit for your needs.

1. Simplicity and Codebase

  • WireGuard: Known for its simplicity, WireGuard has a very minimal codebase (around 4,000 lines of code), making it easier to audit and maintain. This simplicity reduces the potential for security vulnerabilities.
  • OpenVPN: In contrast, OpenVPN has a much larger and more complex codebase (hundreds of thousands of lines of code), which can make it more challenging to audit and maintain.

2. Performance

  • WireGuard: Generally offers better performance with lower latency and higher throughput. It is designed to be lightweight and efficient, using modern cryptographic techniques.
  • OpenVPN: While still performant, OpenVPN typically has higher latency and lower throughput compared to WireGuard, partly due to its more complex cryptographic operations and reliance on user-space processing.

3. Security

  • WireGuard: Uses state-of-the-art cryptography, including ChaCha20 for encryption and Poly1305 for authentication, ensuring robust security. Its simplicity also contributes to its security, as there are fewer places for bugs and vulnerabilities to hide.
  • OpenVPN: Also very secure, with support for a wide range of cryptographic algorithms (including AES-256). However, its larger codebase can potentially introduce more security risks.

4. Configuration and Ease of Use

  • WireGuard: Configuration is straightforward, involving simple text files for settings. This makes it user-friendly, especially for those who are less experienced with VPNs.
  • OpenVPN: Can be more complex to configure, with extensive options and settings available. This flexibility is powerful but can be overwhelming for new users.

5. Cross-Platform Support

  • WireGuard: Supported on multiple platforms, including Linux, Windows, macOS, iOS, and Android. It has strong integration with the Linux kernel, providing excellent performance on Linux systems.
  • OpenVPN: Also widely supported across various platforms and can run on many different operating systems. It has been around longer, so it benefits from extensive compatibility and community support.

6. Connection Establishment and Roaming

  • WireGuard: Designed for seamless roaming, allowing devices to change IP addresses without dropping the connection. This makes it ideal for mobile devices that frequently switch networks.
  • OpenVPN: Can handle roaming, but it may not be as seamless as WireGuard. Connection re-establishment can take longer if the device changes networks.

7. UDP vs. TCP

  • WireGuard: Operates solely over UDP, which is typically faster and more efficient for VPNs. This makes it less reliable on networks that block UDP traffic.
  • OpenVPN: Can operate over both UDP and TCP, giving it greater flexibility in environments where UDP traffic is restricted.

Final Thoughts

Both WireGuard and OpenVPN have their own advantages and use cases. WireGuard excels in performance, simplicity, and modern security features, making it an excellent choice for most users. However, OpenVPN’s flexibility, extensive configuration options, and mature ecosystem make it a reliable and versatile option, especially in complex or legacy environments.

If you’re looking for a more straightforward, efficient, and modern VPN solution, WireGuard is likely the better choice. If you need advanced features, extensive configuration options, and compatibility with a wide range of systems, OpenVPN might be more suitable.

Linux Server/Client 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 Linux 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

After installation, you are required to setup WireGuard VPN Server.

Setup WireGuard VPN Server

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

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

If you have setup WireGuard VPN Server correctly, then your request will be routed through the VPN tunnel.

A good book related to VPNs is VPNs is Zero Trust Networks: Building Secure Systems in Untrusted Networks (PAID LINK) by O’Reilly Media. We recommend that you should read this book if you want to work on VPNs.

Final Thoughts

WireGuard is a powerful and efficient VPN protocol that provides a secure and fast solution for encrypted communication. Its simplicity, combined with high performance and strong security, makes it an excellent choice for both personal and enterprise use. Setting up a WireGuard VPN server on CentOS 8 can significantly enhance your network security and privacy.

If you’re looking to implement WireGuard on your Linux server and need expert guidance, I offer a comprehensive service to help you with the setup. Whether you’re new to VPNs or need advanced configurations, I can ensure a smooth and secure installation process.

For professional assistance, please visit my Fiverr gig here. Let’s secure your network with WireGuard!

2 thoughts on “Setup WireGuard VPN Server on CentOS 8”
  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.

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

Leave a Reply

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