What is WireGuard?

published
April 11, 2024
TABLE OF CONTENTS

WireGuard® is a leap forward in VPN technology, offering a blend of speed, simplicity, and security that is often sought but seldom achieved with traditional VPN solutions. It is designed to outperform other methods in terms of both performance and security, making it a favorable choice for IT professionals looking for a reliable and efficient VPN solution.

At its core, WireGuard utilizes state-of-the-art cryptographic techniques, such as the Noise protocol framework, Curve25519, ChaCha20, Poly1305, and BLAKE2, to ensure that the data transmitted over the network is secure and protected against threats. This focus on high-speed cryptography, combined with the protocol’s lean design, allows WireGuard to operate faster than IPsec and OpenVPN without compromising on security.

For IT service providers, the advantages of WireGuard extend beyond its performance and security features. The VPN solution is easy to configure and deploy, akin to setting up SSH. This simplicity is achieved through the exchange of public keys between peers, which is facilitated by the `wg` command-line tool. Moreover, WireGuard's minimalistic approach not only reduces the potential for security vulnerabilities but also makes it easier for IT professionals to audit and verify the code.

WireGuard Setup

Installing WireGuard

Start by ensuring your system's package repository is up-to-date. On a Debian or Ubuntu server, you would use:

sudo apt update && sudo apt upgrade -y

NOTE: When going through the update and upgrade process on any linux server, some cli prompts will show up and the user needs to go through the prompts manually. After finishing the upgrade process, a system reboot is recommended to load the latest kernel version and modules.

Linux reboot command:

sudo shutdown -r now

Then, install WireGuard:

sudo apt install wireguard -y

Repeat these steps on the client machine as well.

Generating Keypairs

To set up a WireGuard VPN, IT professionals start by generating private and public keys using the `wg genkey` and `wg pubkey` commands, ensuring secure communication between the VPN peers:

wg genkey | tee privatekey | wg pubkey > publickey

Managing Firewall and Forwarding

If a device in the network will forward traffic, then forwarding traffic must be enabled on the device. To check if traffic forwarding is enabled or disabled, this command can be used:

cat /proc/sys/net/ipv4/ip_forward

On Linux, this can be done by editing `/etc/sysctl.conf` or adding a `.conf` file under `/etc/sysctl.d/` folder with the following line:

nano /etc/sysctl.conf
touch /etc/sysctl.d/wg-forward.conf
nano /etc/sysctl.d/wg-forward.conf
net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1

For IPv4 -> net.ipv4.ip_forward=1

For IPv6 -> net.ipv6.conf.all.forwarding=1

Then apply the changes (when edit /etc/sysctl.conf):

sudo sysctl -p

Then apply the changes (when adding a `.conf` file under `/etc/sysctl.d/` folder):

service procps force-reload

Configuring Interfaces

Setup continues with the creation of a new network interface for WireGuard and assigning it an IP address:

ip link add dev wg0 type wireguard
ip address add dev wg0 192.168.2.1/24

NOTE: Different WireGuard IP addresses from the same IP network subnet need to be used when configuring the client machine. For example:

ip link add dev wg0 type wireguard
ip address add dev wg0 192.168.2.2/24

The configuration of WireGuard peers is handled through the `wg` utility, which allows for the specification of peer public keys, endpoints, and allowed IPs. This is a critical step in securing the VPN tunnel and ensuring that only authorized devices can connect. Public keys are exchanged between peers, while private keys are kept only on the source device:

NOTE: The <public key> should be replaced with the plaintext base64 public key of the peer. To retrieve the public key from client machine, this command can be used on the client machine:

wg set wg0 listen-port 51820 private-key /path/to/private-key 
wg set wg0 peer <public key> allowed-ips 192.168.2.0/24 endpoint <public IP of peer>:<wireguard port 

For machines behind NAT or firewalls, WireGuard supports persistent keepalives to maintain the connection, a feature configured by setting the persistent-keepalive option for each peer.

Finally, turning the interface on completes the VPN setup:

ip link set up dev wg0

Now we can verify the connection between the two machines by pinging each other using the following command:

ping 192.168.2.2

# ping 192.168.2.2   (from the server machine)

Or

# ping 192.168.2.1   (from the client machine)

WireGuard's integration into various platforms and operating systems, from Linux to macOS and Windows, coupled with its comprehensive documentation and straightforward configuration process, makes it an appealing solution for IT service providers aiming to deliver secure, high-performance VPN services to their clients.

Comparison of WireGuard with Other VPN Protocols

WireGuard stands out amongst VPN protocols for its blend of speed and security. Unlike OpenVPN, which has been the gold standard for years due to its security features and support for high encryption standards like 256-bit AES, WireGuard offers a more modern approach to cryptography and protocol design.

The performance of WireGuard is notably superior, particularly in terms of connection speed and reliability. This can be attributed to its streamlined codebase, which is smaller than that of OpenVPN, reducing the potential for security vulnerabilities and bugs, while making it easier to audit. For IT professionals, this means improved VPN performance across devices and networks with fewer resources consumed, and more trust.

Using Wg-Quick with WireGuard

WireGuard's configuration simplicity is also evident in its ability to fit the entire client configuration into a small text file, enabled by the “wg-quick” utility, making the setup process much faster.

Consider how this can streamline the deployment process for IT service providers managing a plethora of client devices, significantly reducing the time and potential for errors typically involved in manually configuring VPN clients using the command line.

Ahead of time, you will need to generate public and private keypairs for each machine using the commands in the previous section, and add these to the files appropriately.

Configuring the Server

Create a WireGuard configuration file in `/etc/wireguard/` named `wg0.conf`. Replace `wg0` with whatever name you prefer, but ensure consistency in naming:

sudo nano /etc/wireguard/wg0.conf

Input the following configuration, substituting placeholders `<ServerPrivateKey>`, `<ClientPublicKey>`, `<ServerIP>`, and `<ClientIP>` with actual values:

[Interface]
PrivateKey = <ServerPrivateKey>
Address = <ServerIP>/24
ListenPort = 51820
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer]
PublicKey = <ClientPublicKey>
AllowedIPs = <ClientIP>/32

This configuration specifies the server's private key, the public key of the client allowed to connect, and the IP addresses assigned to these interfaces. The `PostUp` and `PostDown` scripts manage NAT and firewall rules to allow traffic forwarding.

Configuring the Client

On the client side, create a configuration file, for example, `wg0.conf`, with the following content. Again, replace placeholders `<ClientPrivateKey>`, `<ServerPublicKey>`, `<ServerIP>`, and `<ClientIP>` with your specific values:

[Interface]
PrivateKey = <ClientPrivateKey>
Address = <ClientIP>/24

[Peer]
PublicKey = <ServerPublicKey>
Endpoint = <ServerEndpointIP>:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25

This configuration targets the server at its public IP and port, forwarding all client traffic through the VPN, with `PersistentKeepalive` keeping the connection alive.

Generating a QR code for mobile client setup

For generating WireGuard QR codes from configuration, a configuration file must be created first. And then qrencode package must be installed first using:

sudo apt install qrencode -y

Then a QR code can be generated using the following command (make sure the wg0-client.conf file is already created following the steps above):

qrencode -t ansiutf8 < /etc/wireguard/wg0-client.conf

The static nature of WireGuard's network configuration, while seen as a downside for dynamic environments, is a feature in controlled scenarios. It eliminates the need for ongoing negotiations after the initial setup, thereby reducing overhead and potential points of failure. IT professionals can leverage this predictability in environments where network settings are stable and predefined, focusing on securing and optimizing the network rather than managing complex dynamic configurations.

Cryptographic Underpinnings of WireGuard

WireGuard’s choice of Curve25519 for key exchange is important, offering 128 bits of security and is designed to be resistant against timing attacks, a critical consideration for secure communications.

Encryption and authentication are handled via CHACHA20 and Poly1305, respectively. This combination is known for its high-speed performance and strong security properties. Encrypting a message in WireGuard, while abstracted away by the tool, fundamentally involves generating a nonce, associated data, and utilizing the private and public keys to ensure confidentiality and integrity.

For hashing, WireGuard utilizes BLAKE2s, a fast cryptographic hash function that is favored for its simplicity and security. An example of its usage includes deriving keys from nonces or performing hash operations as part of the protocol's handshake process.

The additional inclusion of SipHash for hashtable key management allows users to mitigate common attack vectors like hash flooding.

Command Line Instructions to Check the Connection Status with WireGuard

To ensure WireGuard VPN tunnels are operational and to troubleshoot connectivity issues, IT professionals can utilize the `show wireguard` command within the TNSR CLI. This powerful command allows for a comprehensive view of all configured WireGuard tunnels, providing detailed insights such as interface names, instance numbers, descriptions, source addresses, and public/private keys, among other critical details. By leveraging this command, network administrators can effectively monitor and manage WireGuard VPN tunnels, ensuring secure and reliable connectivity across the network infrastructure.

For a broad overview of the WireGuard tunnel status, executing `tnsr# show wireguard` without specifying any additional parameters will display the status of all WireGuard instances configured on the system. This is particularly useful for getting a quick snapshot of the entire WireGuard setup. For example:

tnsr# show wireguard

Interface: wg1
    Instance: 1
    Description: WireGuard P2P - R1-R2
    Source address: 203.0.113.2
    Port: 51820
    Public key: K/l2cD3PCCioSnerIe7tOSAqyRQ8dB1LAoeiJqn0uiY=
    Private key: IPbehUo58KvYl/qmA+50bAaWeXgB+eP+8QqmDkLV9XA=
    Peer ID: 1
        Description: R2
        Endpoint IP: 203.0.113.25
        Port: 51820
        Flags: 0x2 ESTABLISHED
        Public key: kIGM3jon1y43ZiCh9YryxNNfda/Qh5d1aBHSfKZbYTA=

Interface: wg2
    Instance: 2
    Description: WireGuard P2P - R1-R3
    Source address: 203.0.113.2
    Port: 51821
    Public key: o5dG8Wy4gsc4bmzF+h4DIO/rNHQHjSjsbw1sM2JghQc=
    Private key: WOy604Y5RemUbsWz7kayXZhZfPhlzobZMu9MxeNBL1k=
    Peer ID: 2
        Description: R3
        Endpoint IP: 203.0.113.17
        Port: 51821
        Flags: 0x2 ESTABLISHED
        Public key: qSXl+mo80nOiIi+La5dkJhV5B1bVJlzqK3rvPlUBb1Q=

For more targeted troubleshooting or monitoring, network administrators can specify an individual WireGuard instance to view its status. This is particularly useful when working with multiple tunnels and needing to focus on a specific connection for configuration verification or issue resolution. The syntax includes the instance number as an argument to the `show wireguard` command, as illustrated below:

show wireguard 2

WireGuard Integration with Firewalls and Routing

For those managing networks, the integration of WireGuard within iptables-based Linux firewalls is a common scenario. Suppose you've set up a WireGuard VPN on a server with its interface named `wg0`. To allow traffic to flow through the server and reach the intended destinations, you must configure iptables to accept and forward the VPN traffic. This involves setting up NAT (Network Address Translation) rules and enabling IP forwarding. Here's an example of how you can achieve this:

# Enable IP forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward

# Append a rule to accept traffic on the WireGuard interface
iptables -A INPUT -i wg0 -j ACCEPT

# Append a rule to accept forwarded traffic from wg0 to the Ethernet interface
iptables -A FORWARD -i wg0 -o eth0 -j ACCEPT

# Append a NAT rule for outgoing traffic on the Ethernet interface
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

In this example, `eth0` represents the server's Ethernet interface connected to the internet. These commands ensure that the server accepts incoming VPN connections on the `wg0` interface and correctly forwards traffic between the VPN and the internet.

Integrating WireGuard with advanced firewall solutions, such as those found in pfSense or OPNsense, involves creating interface assignments and setting up rules through their respective web interfaces. Here's a brief overview of the process for pfSense:

1. After configuring WireGuard and establishing a tunnel, navigate to `Interfaces > Assignments` in the pfSense web interface.

2. Assign the WireGuard interface (`wg0`) to an available network port.

3. Create firewall rules under `Firewall > Rules` on the newly assigned interface to permit the necessary traffic.

For example, if you want to allow all traffic from the VPN to access the LAN:

Action: Pass
Interface: WG_VPN (assuming WG_VPN is your assigned WireGuard interface)
Address Family: IPv4
Protocol: Any
Source: Any
Destination: LAN net

By meticulously configuring your firewall and routing settings to work with WireGuard, you can establish a secure, efficient network infrastructure. Remember, the specific commands and steps may vary depending on your operating system and firewall solution, so always refer to the official documentation for the most accurate guidance.

Best Practices for Maintaining a Secure WireGuard Deployment

Maintaining a secure WireGuard deployment involves a combination of vigilant monitoring, regular updates, and following best practices for configuration and key management. WireGuard, known for its simplicity and high performance, offers a robust foundation for creating secure network tunnels. However, its security is heavily dependent on how it's configured and maintained.

To begin with, always ensure that your WireGuard installation is up to date. This can be achieved by regularly checking the official WireGuard website for updates or using package managers like apt for Debian/Ubuntu systems with `sudo apt update && sudo apt upgrade wireguard`, or yum for CentOS with `sudo yum update wireguard`. Regular updates ensure that any vulnerabilities discovered in previous versions are patched.

When configuring WireGuard, use strong, unique private keys for each peer. The `wg genkey` command generates a secure private key, which can be piped directly into `wg pubkey` to create the public key, as follows:

wg genkey | tee privatekey | wg pubkey > publickey

Storing these keys securely is paramount. Ideally, private keys should be kept on the respective machines only and not transmitted over the network. Implement file permissions to restrict access to the WireGuard configuration files, for example, using `chmod 600 /etc/wireguard/wg0.conf` to ensure that only root can read and write the file.

Implement IP whitelisting to limit control over who can access your WireGuard server. This is done by specifying the allowed IPs for each peer in the configuration file. For instance:

[Peer]
PublicKey = thepeerpublickey
AllowedIPs = 192.168.1.12/32

This ensures that only a peer with the specified IP address can communicate through the tunnel, enhancing the security of your VPN tunnel.

  • From a network management perspective, leveraging WireGuard's `PersistentKeepalive` feature judiciously helps in maintaining the connection alive, particularly useful when traversing NAT (Network Address Translation). However, it's crucial to use it sparingly to avoid unnecessary network traffic, setting it to a reasonable interval, e.g., `PersistentKeepalive = 25`, for 25 seconds.
  • Firewall rules also play a critical role in securing your WireGuard deployment. Ensure that your firewall is configured to allow traffic only on WireGuard’s port (default is UDP port 51820) and block unwanted inbound and outbound traffic. For iptables, you can use:
iptables -A INPUT -p udp --dport 51820 -j ACCEPT
iptables -A OUTPUT -p udp --sport 51820 -j ACCEPT
  • Regularly inspect your WireGuard logs for unauthorized access attempts or other suspicious activity. Although WireGuard does not log by default due to its design for privacy and minimalism, monitoring can be achieved through firewall logs or custom logging setups.
  • Lastly, consider setting up a kill switch that blocks all traffic if the VPN connection drops unexpectedly. This can be critical for preventing data leaks, especially in sensitive environments. A simple script that monitors the WireGuard interface and blocks outbound traffic if the interface goes down can serve as a basic kill switch.

Performance Benchmarks of WireGuard and Ease of Use

WireGuard, as a modern VPN protocol, distinguishes itself through a blend of high-speed performance and simplicity, making it an appealing choice for IT professionals tasked with maintaining secure, efficient networks. Designed to outperform its predecessors like OpenVPN and IPSec in both throughput and responsiveness, WireGuard utilizes state-of-the-art cryptographic principles, offering not just performance gains but also a simplified approach to VPN configuration and management.

The lean nature of WireGuard's codebase—around 4,000 lines—facilitates both ease of security audits and integration into various platforms. This compact size directly translates into performance advantages. For instance, encryption and decryption are faster, substantially reducing latency and increasing throughput. In contrast, traditional VPN protocols might involve tens of thousands of lines of code, complicating audits and potentially diminishing performance.

From an empirical standpoint, WireGuard has shown to excel in real-world application scenarios. Benchmarks illustrate that WireGuard can significantly outperform OpenVPN in terms of throughput and ping times. For example, on identical hardware and network conditions, WireGuard has been observed to deliver throughput speeds upwards of 1 Gbps, while OpenVPN struggles to match this, often maxing out at around 300 Mbps under optimal conditions. Additionally, the latency experienced with WireGuard is remarkably lower, which is crucial for applications requiring real-time data transmission.

The ease of use aspect of WireGuard cannot be overstated. It offers a more straightforward approach to setup and configuration, which can be a relief for IT professionals accustomed to the complexities of older VPN solutions. Configuring a WireGuard server can be as simple as installing the WireGuard package, generating public and private keys, and setting up a basic configuration file.

WireGuard is a registered trademark of Jason A. Donenfeld.

More posts

GET STARTED

A WireGuard® VPN that connects machines securely, wherever they are.
Star us on GitHub
By clicking “Accept”, you agree to the storing of cookies on your device to enhance site navigation, analyze site usage, and assist in our marketing efforts. View our Privacy Policy for more information.