
The time has come when a VPN is no longer an exotic tool for bearded sysadmins. Users have different needs, but the fact is, VPNs have become necessary for everyone.
The problem with current VPN solutions is that they are difficult to set up correctly, expensive to maintain, and filled with questionable legacy code.
A few years ago, Canadian cybersecurity expert Jason A. Donenfeld decided it was time to put an end to this and began working on . Currently, WireGuard is being prepared for inclusion in the Linux kernel, and it has even received praise from and in .
The stated advantages of WireGuard over other VPN solutions are:
- Easy to use.
- Uses modern cryptography: Noise protocol framework, Curve25519, ChaCha20, Poly1305, BLAKE2, SipHash24, HKDF, etc.
- Compact, readable code, easier to audit for vulnerabilities.
- High performance.
- Clear and well-thought-out .
Is a silver bullet truly found? Is it time to bury OpenVPN and IPSec? I decided to investigate this, and in the process, I created .
Operating principles
The operating principles can be described as follows:
- A WireGuard interface is created, assigned a private key and IP address. The settings of other peers are loaded: their public keys, IP addresses, etc.
- All IP packets arriving at the WireGuard interface are encapsulated in UDP and to other peers.
- Clients specify the server's public IP address in their settings. The server automatically learns the clients' external addresses when correctly authenticated data arrives from them.
- The server can change its public IP address without interrupting service. It will send a notification to connected clients, and they will update their configuration on-the-fly.
- The concept of routing is employed . WireGuard accepts and sends packets based on the peer's public key. When the server correctly decrypts an authenticated packet, it checks its src field. If it matches the configuration
allowed-ipsIf a peer is authenticated, the packet is accepted by the WireGuard interface. When sending an outgoing packet, the corresponding procedure takes place: the dst field of the packet is taken and based on it, the corresponding peer is selected, the packet is signed with its key, encrypted with the peer's key, and sent to the remote endpoint.
The main logic of WireGuard occupies less than 4 thousand lines of code, while OpenVPN and IPSec have hundreds of thousands of lines. To support modern cryptographic algorithms, it is proposed to include a new cryptographic API in the Linux kernel. . Currently, there is a discussion about how successful this idea is.
Performance
The maximum performance advantage (compared to OpenVPN and IPSec) will be noticeable on Linux systems, as WireGuard is implemented as a kernel module there. Additionally, macOS, Android, iOS, FreeBSD, and OpenBSD are supported, but in those, WireGuard runs in userspace with all the ensuing performance implications. Support for Windows is promised to be added in the near future.
Benchmark results from :

My experience with using
I am not an expert in configuring VPNs. Once, I configured OpenVPN manually and it was very tedious, and I never even tried IPSec. Too many decisions need to be made, and it's very easy to shoot yourself in the foot. Therefore, I have always used ready-made scripts for server setup.
So, from my perspective, WireGuard is absolutely ideal for users. All low-level decisions are made in the specification, so the process of setting up a typical VPN infrastructure takes just a few minutes. It's practically impossible to mess up the configuration.
Installation Process on the official site, I want to particularly highlight the excellent .
Encryption keys are generated by the utility wg:
SERVER_PRIVKEY=$( wg genkey )
SERVER_PUBKEY=$( echo $SERVER_PRIVKEY | wg pubkey )
CLIENT_PRIVKEY=$( wg genkey )
CLIENT_PUBKEY=$( echo $CLIENT_PRIVKEY | wg pubkey )Next, you need to create the server config /etc/wireguard/wg0.conf with the following content:
[Interface]
Address = 10.9.0.1/24
PrivateKey = $SERVER_PRIVKEY
[Peer]
PublicKey = $CLIENT_PUBKEY
AllowedIPs = 10.9.0.2/32and bring up the tunnel with the script wg-quick:
sudo wg-quick up /etc/wireguard/wg0.confIn systems with systemd, you can use sudo systemctl start wg-quick@wg0.service.
On the client machine, create the config /etc/wireguard/wg0.conf:
[Interface]
PrivateKey = $CLIENT_PRIVKEY
Address = 10.9.0.2/24
[Peer]
PublicKey = $SERVER_PUBKEY
AllowedIPs = 0.0.0.0/0
Endpoint = 1.2.3.4:51820 # External IP of the server
PersistentKeepalive = 25 And bring up the tunnel in the same way:
sudo wg-quick up /etc/wireguard/wg0.confNow we need to configure NAT on the server so that clients can access the Internet, and everything will be ready!
This level of ease of use and compactness of the codebase has been achieved by eliminating the key distribution functionality. There is no complex certificate system or all that corporate nonsense; short encryption keys are distributed similarly to SSH keys. However, this raises a challenge: WireGuard may not be easy to implement in some existing networks.
One downside to note is that WireGuard won't work through an HTTP proxy, as it relies solely on the UDP protocol for transport. This raises the question of whether the protocol can be obfuscated. While this isn’t a direct task for a VPN, for example, OpenVPN has methods to disguise traffic as HTTPS, which helps residents of totalitarian countries access the Internet fully.
Conclusions
In summary, this is a very interesting and promising project; it can already be used on personal servers. What’s the benefit? High performance on Linux systems, ease of setup and maintenance, and a compact, readable codebase. However, it’s still too early to switch a complex infrastructure to WireGuard; it’s best to wait for its inclusion in the Linux kernel.
To save my (and your) time, I developed . With its help, you can set up a personal VPN for yourself and your acquaintances even without any prior knowledge.
Source: habr.com
