In todays networking world, virtual private networks are unmissable. With IT needs growing exponentially in the current modern era, it is essential to make the right choices on what VPN software you are going to use. While IPSec tunnels are commonly deployed and proven to deliver good performance while being stable at the same time, are there any other alternatives?
Yes there are. Here are some VPN solutions I have deployed in the past:
- OpenVPN, both in peer-to-peer and remote access configurations
- PPTP (with pptpd on Linux)
- SoftEther (Has its own VPN protocol over an SSL connection)
Recently - on a long journey on Google - I came across WireGuard. They claim to have the networking code of their VPN software running in kernel-space for optimal performance, so that seems all good. I decided to dig deeper into WireGuard, so I could write a guide/tutorial on the getting started and configuration process.
My test environment
My test environment consists over two Linux servers in the cloud, they are directly connected to each other over a private network:
- server-01: 10.129.29.151
- server-02: 10.129.30.154
For benchmarking networking speeds I used iperf, and this is the traffic speed test result I got over this private network:
This step is pretty straight forward, just copy and paste this code into your terminal:
add-apt-repository -y ppa:wireguard/wireguard apt update apt install -y wireguard-dkms wireguard-tools
If you don't use Ubuntu on your servers, check out this page on the WireGuard website to find out how to install it on your Linux distribution of preference.
Initialisation of WireGuard's virtual interfaces
Configuring a simple peer-to-peer tunnel on WireGuard is not that complicated.
First of all, let's create the wg0 interface on both servers - this will be the virtual interface for your virtual private network between both servers:
ip link add dev wg0 type wireguard
Your virtual network also needs an IP address for each node so that machines can communicate between each other over IP:
# For server-01: ip address add dev wg0 192.168.2.1/24 # For server-02: ip address add dev wg0 192.168.2.2/24
Generating a configuration for each node
WireGuard uses a key-based VPN solution for communication between nodes. This system insists of a private key and a public key for each node. You can generate these keys on each node with the following command:
# For server-01: wg genkey | tee privatekey01 | wg pubkey > publickey01 # For server-02 wg genkey | tee privatekey02 | wg pubkey > publickey02
Create a configuration file named wireguard.conf and store it somewhere safe with the right Linux permissions applied on this file (chown/chmod). Here's what you need to put in this configuration file:
# On server-01: [Interface] ListenPort = 4820 PrivateKey = privatekey01's content goes here [Peer] Endpoint = ip:port of endpoint (10.129.30.154:4820) PublicKey = publickey02's content goes here AllowedIPs = 0.0.0.0/0
# On server-02: [Interface] ListenPort = 4820 PrivateKey = privatekey02's content goes here [Peer] Endpoint = ip:prt of endpoint (10.129.29.151:4820) PublicKey = publickey01's content goes here AllowedIPs = 0.0.0.0/0
Link the configuration to the interface on all nodes:
wg setconf wg0 wireguard.conf
Bring the interface up on all nodes:
ip link set up dev wg0
You are now connected, you can test connectivity by sending ICMP echo packets:
Run this command on the first node (server-01 in my case):
Run this command on the second node (server-02 in my case):
iperf -c 192.168.2.1
These are the results I got over the tunnel:
Pretty good results for just a dual-core server. I'm sure that there are possibilities/tweaks to make WireGuard perform even better, we'll see...