Virtual private networks with WireGuard
This article brought to you by LWN subscribers Subscribers to LWN.net made this article — and everything that surrounds it — possible. If you appreciate our content, please buy a subscription and make the next set of articles possible. |
Virtual private networks (VPNs) offer a lot in the way of increased security and privacy. They have also tended to offer less desirable features like administrative complexity and reduced performance, though; as a result, many potential VPN users decide not to bother. A relatively new project called WireGuard hopes to address both of those problems with an in-kernel solution that is both simple and fast.
A VPN works by establishing an encrypted connection from an endpoint system to a trusted host elsewhere on the network. That host becomes the router through which some or all network traffic from the endpoint passes. Since this tunnel is encrypted, traffic that travels over the VPN is protected from eavesdroppers — until it reaches the trusted host, at least. Setting up the VPN connection in the first place requires authentication between the endpoints; that, in turn, allows hosts to place some trust in the packets coming over the VPN connection. It is thus a common configuration to only allow internal resources to be accessed via a VPN connection.
There are other advantages to VPNs as well. Today's youth tend to be well acquainted with the use of a VPN to bypass various types of content filtering. A VPN can be used to change a user's apparent network location, helping to circumvent annoyances like country-specific content blocking. The first eavesdropper many of us are likely to encounter is our own Internet service provider, which tends to take a great interest in collecting data on web traffic and such to sell to advertisers; using a VPN will frustrate this kind of prying.
Linux users have a number of VPN options available to them. In many cases, a set of OpenSSH tunnels will do the trick for specific applications. OpenVPN is a popular, open-core system that provides comprehensive VPN functionality. But OpenVPN suffers from a fair amount of complexity and, since it is a user-space implementation, it takes a toll on networking performance. IPsec is built into the kernel and has fewer performance problems, but it makes up for that with even more complexity.
Enter WireGuard
In June 2016, Jason Donenfeld showed up with a new VPN implementation called WireGuard that claims to avoid the problems associated with other options. It is an in-kernel implementation (though still out of tree) that has been developed with performance in mind. The implementation is quite small (about 4,000 lines of code), making it relatively easy to verify. Configuration of the system is relatively simple though, as with any sort of network configuration it seems, the "relatively" qualification is important.
Donenfeld has gone out of his way to make it easy to experiment with WireGuard; there are prebuilt packages available for a wide range of distributions. Those packages contain the source for the WireGuard implementation; it is built on the fly using the DKMS framework. Once the installation is done, the user is left with a kernel module (wireguard.ko) and the wg tool for configuration.
Every host connecting to a WireGuard implementation must use a public/private key pair for communication. The first step, thus, is to generate a new private key with a command like:
# wg genkey uHCQ+Damh4F5zNVr9PvHiflW2aRU1SE0GQCVYkvxiEc=
The keys are generated using the Curve25519 elliptic curve; as a result they are quite a bit shorter than keys used by other algorithms. The associated public key can be created from the private key with the wg pubkey command.
WireGuard presents itself as a new type of network interface that can be used to route packets into a VPN. Thus, setting up a WireGuard implementation requires creating and configuring this interface, using a command series like:
# ip link add wg0 type wireguard # ip addr add 10.0.0.1/24 wg0 # wg set wg0 private-key <private-key-file> # ip link set wg0 up
These commands create a new network interface called wg0, loading the wireguard kernel module in the process. This interface is assigned the network address 10.0.0.1, and its private key is set to a key generated with wg genkey. Just running a bare wg command at this point will produce output like:
# wg interface: wg0 public key: FNqV9pbUECLd7SNQ98jDlDRxqtppMTT9CEE8p1w6bTU= private key: (hidden) listening port: 41415
Like many recent protocols, WireGuard is based on UDP. Packets at one end are encrypted, then sent to the remote endpoint encapsulated within UDP packets, where they are decrypted and sent on their way. The above output tells us that port 41415 was chosen to listen for these UDP packets; the port number can also be explicitly configured with the wg command.
A command series like this must be carried out at both ends of the VPN connection; the IP addresses should be different, of course, but on the same subnet (10.0.0.0/24 in this case). Imagine we did something like that on the remote host, giving it IP address 10.0.0.2 and putting it on port 44556. The next step is to connect those two interfaces together so that they may pass packets back and forth. On the original machine (the one whose wg0 interface has address 10.0.0.1), we would run something like:
wg set wg0 peer <public-key> allowed-ips 10.0.0.2/32 endpoint <ip-addr>:44556
Here, ip-addr is the real-world (not VPN) address of the other end of the connection. A similar command would be required on that other system, using the appropriate public key and IP address. At that point, it will be possible to communicate between the two hosts by using the appropriate addresses. Once the connection has been established the IP addresses can change; if one end is a laptop, for example, the VPN will still work after moving to a new network.
In a sense, that's really about all there is to it. But the real world does tend to be a bit more complicated, of course. For example, it is common to want the endpoint to send all of its network traffic over the VPN. That could be accomplished by setting the allowed-ips parameter in the above command to 0.0.0.0/0 and using ip route to set the default route to go through wg0. A slightly more complex setup (turning on IP forwarding, probably setting up NAT) would then be required on the other end to make the routing work.
The advantage of the WireGuard approach can be seen here, though; it creates interfaces that can be connected to each other. After that all of the normal networking routing and traffic-control features can be used to cause that VPN link to be used in a wide variety of ways. There are also some special features designed to allow WireGuard interfaces to be used within network namespaces.
I ran a test, using WireGuard to set up a link between the desktop machine and a remote cloud instance. It took a little while, but that is mostly a matter of being extremely rusty with the ip command set. The VPN tunnel worked as advertised in the end. Before enabling the tunnel, a SpeedOf.Me test showed 137Mbps bandwidth down and 12.9Mbps up; the ping time to an LWN server was 76ms. With all traffic routing over the WireGuard VPN link, downward bandwidth dropped to 131Mbps and upward to 12.4Mbps; ping times were nearly unchanged. That is not a zero cost, but it is not huge and one should bear in mind that going through a NAT gateway at the far end will be a big chunk of the total performance hit. So WireGuard does indeed appear to be reasonably fast.
One test is not a comprehensive evaluation, of course. It will be interesting to try WireGuard at the next conference with an overloaded network to see how well it copes with packet loss, for example, and no attempt was made to verify the cryptographic aspects of the protocol. WireGuard does seem like a relatively simple and fast VPN implementation, though, that could go a long way toward making VPN use nearly universal on Linux systems.
Next steps
Getting to that point will require that WireGuard be merged into the mainline kernel, though. Donenfeld has stated that upstreaming the code was his intent from the beginning, but there have been almost no postings of the code on the kernel mailing lists. It is, thus, unsurprising that WireGuard remains out of tree. Donenfeld did post an upstreaming roadmap in November; it suggests that the code is unlikely to be merged right away since, for example, an overhaul of the cryptographic API is evidently a precondition. That overhaul has not yet happened, and neither has the promised near-term posting of the WireGuard code.
Chances are that this all will happen eventually, though. WireGuard seems to have generated a high level of interest, and it appears to have been deployed in many settings already. It has, for example, been integrated into OpenWrt with a set of configuration screen in the LuCi web interface. So there is clearly an audience for this functionality. Once the process of getting it upstream begins in earnest, it may run its course relatively quickly.
See this white
paper [PDF] for lots of details on how WireGuard works.
Index entries for this article | |
---|---|
Kernel | Networking/Virtual private networks |
Security | Encryption/Network |
Security | Linux kernel/Virtual private network (VPN) |
(Log in to post comments)
Virtual private networks with WireGuard
Posted Mar 6, 2018 15:28 UTC (Tue) by dezgeg (subscriber, #92243) [Link]
Virtual private networks with WireGuard
Posted Mar 6, 2018 15:44 UTC (Tue) by zx2c4 (subscriber, #82519) [Link]
Expect to see some patches in the spring for this. We're steadily moving ahead to our v1 submission. I should write another status update to netdev; thanks for encouraging me here.
Virtual private networks with WireGuard
Posted Mar 6, 2018 16:42 UTC (Tue) by Lekensteyn (subscriber, #99903) [Link]
WireGuard encapsulates IP packets in its transport messages and does no attempt on retransmission (leaving this up to the upper layers). The initial handshake consists of only two (small) UDP datagrams (one for each direction), there are no explicit acknowledgement messages.
Compare this to (for example), OpenVPN with its TLS authentication mode that requires many more UDP datagrams to transport the full TLS handshake (including large certificates), it seems likely that WireGuard is faster to establish a session.
Virtual private networks with WireGuard
Posted Mar 6, 2018 17:06 UTC (Tue) by yokem_55 (subscriber, #10498) [Link]
Will wireguard ever be more than just a linux thing?
Virtual private networks with WireGuard
Posted Mar 6, 2018 18:08 UTC (Tue) by dsix (guest, #111931) [Link]
Virtual private networks with WireGuard
Posted Mar 6, 2018 19:30 UTC (Tue) by zx2c4 (subscriber, #82519) [Link]
WireGuard is available for Ubiquiti equipment actually. For other operating systems, we're developing several cross-platform implementations. So we should have pretty good compatibility throughout.
Virtual private networks with WireGuard
Posted Mar 6, 2018 20:27 UTC (Tue) by SEJeff (guest, #51588) [Link]
Virtual private networks with WireGuard
Posted Mar 6, 2018 20:33 UTC (Tue) by zx2c4 (subscriber, #82519) [Link]
Specifically I mean: https://github.com/Lochnair/vyatta-wireguard/releases -- so their EdgeRouter devices.
Virtual private networks with WireGuard
Posted Mar 6, 2018 21:16 UTC (Tue) by SEJeff (guest, #51588) [Link]
Virtual private networks with WireGuard
Posted Mar 10, 2018 0:53 UTC (Sat) by coolhandluke (guest, #114151) [Link]
So it certainly looks like cross-platform interoperability is both desired and actively being worked on (as far as open-source devices go, of course). On closed platforms (IOS, JunOS, etc.), it would obviously be up to the vendor whether they decided to add support for WireGuard.
Personally, I'd love to support for WireGuard available in both FreeBSD and OpenBSD. I expect that this will happen eventually, likely some time after it is fully upstreamed in mainline and most of the kinks have been worked out.
[0]: https://lwn.net/Articles/748584/
Virtual private networks with WireGuard
Posted Mar 6, 2018 18:57 UTC (Tue) by dmoreno (subscriber, #46333) [Link]
Virtual private networks with WireGuard
Posted Mar 6, 2018 20:41 UTC (Tue) by zdzichu (subscriber, #17118) [Link]
Virtual private networks with WireGuard
Posted Mar 6, 2018 19:03 UTC (Tue) by Cyberax (✭ supporter ✭, #52523) [Link]
The userspace key agreement protocol (IKE) is another story, but you don't have to use it, ipsec actually has a standardized cross-platform API to manage the kernel-level keys.
Virtual private networks with WireGuard
Posted Mar 7, 2018 2:18 UTC (Wed) by amworsley (subscriber, #82049) [Link]
Another additional design features is that it has very few options and deliberately selected modern algorithms likely to be secure for much time in the future. Greatly reducing the chance of insecurity through mis-configuration versus ipsec.
Finally once a secure tunnel is set up the remote end can change IP as the public key is used to verify any new IP address automatically - removing another "brittleness" where transport network changes can kill the connectivity.
I am not aware of how it handles replay and denial of service attacks but hopefully when it is merged in there will be many chances to check for these and other issues.
Also if it is 4000 lines to implement it would be hard to add it to other platforms.
Presumably if it is popular Android phones could start using fairly quickly.
It would be interesting to know how it would handle the China's great firewall.
Virtual private networks with WireGuard
Posted Mar 7, 2018 14:12 UTC (Wed) by bavay (subscriber, #60804) [Link]
Mathias
PS: Yes, the data transfer itself is also encrypted, but better safe than sorry and encapsulate it within a VPN alongside masses of uninteresting data
Virtual private networks with WireGuard
Posted Mar 7, 2018 14:45 UTC (Wed) by smurf (subscriber, #17840) [Link]
I've been using it for months on my office VPN. Zero problems, it's a breeze to set up compared to OpenVPN (and much faster).
Virtual private networks with WireGuard
Posted Mar 10, 2018 0:20 UTC (Sat) by coolhandluke (guest, #114151) [Link]
This ensures that traffic will not be sent out if the VPN link dies for any reason.
Whether or not this approach is an acceptable solution for you obviously depends on your specific requirements.
Virtual private networks with WireGuard
Posted Mar 12, 2018 22:46 UTC (Mon) by james (subscriber, #1325) [Link]
I've seen people go one stage further and configure the router without a default gateway, just with routes to the public IP addresses of the VPN concentrators.Those routes to the VPN concentrators are the only routes over the WAN link(s): even without a firewall, the router won't know which way to send packets to the Internet until the VPN is up. Then routing protocols (configured to talk to the internal addresses of the VPN concentrators) can add more routes.
Virtual private networks with WireGuard
Posted Mar 7, 2018 14:57 UTC (Wed) by smurf (subscriber, #17840) [Link]
Android will get a userspace implementation.
Virtual private networks with WireGuard
Posted Mar 8, 2018 5:37 UTC (Thu) by thestinger (guest, #91827) [Link]
Virtual private networks with WireGuard
Posted Mar 6, 2018 20:36 UTC (Tue) by judas_iscariote (guest, #47386) [Link]
Current versions of systemd-networkd, (v237+) support setting up wireguard without any fiddling with "ip" atrocious command interface .. of course you still need the out of tree kernel modules.
Virtual private networks with WireGuard
Posted Mar 7, 2018 22:43 UTC (Wed) by flussence (subscriber, #85566) [Link]
Virtual private networks with WireGuard
Posted Mar 7, 2018 23:04 UTC (Wed) by smurf (subscriber, #17840) [Link]
With systemd, you add a .netdev file (the contents of which are almost identical to a wireguard config file) to /etc/systemd/network, and restart systemd-networkd.
Virtual private networks with WireGuard
Posted Mar 8, 2018 12:21 UTC (Thu) by Alphix (subscriber, #7543) [Link]
There's some examples in the Debian wiki Wireguard page.
Virtual private networks with WireGuard
Posted Mar 13, 2018 23:29 UTC (Tue) by Bronek (guest, #120079) [Link]
Virtual private networks with WireGuard
Posted Mar 19, 2018 15:43 UTC (Mon) by zuki (subscriber, #41808) [Link]
Host "names"
Posted Mar 7, 2018 8:38 UTC (Wed) by ejr (subscriber, #51652) [Link]
(I dodge DNS altogether for server->client lookups via occtl. Maybe not the best choice, but it certainly keeps things simple for connecting back to my RaspberryPi sensors.)
Virtual private networks with WireGuard
Posted Mar 9, 2018 8:37 UTC (Fri) by z3ntu (subscriber, #117661) [Link]
What lead to different designs in the past?
Posted Mar 9, 2018 10:00 UTC (Fri) by jarmar (guest, #103679) [Link]
> It intentionally lacks cipher and protocol agility. If holes are found in the underlying primitives, all endpoints will be required to update.
What lead to different designs in the past?
Posted Mar 9, 2018 12:16 UTC (Fri) by zdzichu (subscriber, #17118) [Link]
Within IPSec the appropaches are called "modes". There is a "transport mode", which encrypts data which would normally go unencrypted. And there is a "tunnel mode" which gives you separate network interface handling only encrypted traffic. Both have their advantages and disadvantages – for example transport mode gives you ability to encrypt only some of the streams between two hosts. And with tunnel mode you get another set of network address prefixes to deal with, which complicates routing.
WireGuard avoids complexivity of IPSec by making a sensible choices.
What lead to different designs in the past?
Posted Mar 13, 2018 3:33 UTC (Tue) by perennialmind (guest, #45817) [Link]
Much network-level flexibility is simply off the table if you stick to policy-based IPSec. Want failover? Don't count on routing protocols like OSPF or IS-IS to work over standard IPSec tunnels. Forget about Bidirectional Forwarding Detection helping you figure out whether your tunnel is actually good for handing off packets. Do not forget to take extra care with your firewall to distinguish between the pre- and post- encapsulation stages as packets get cloned and re-injected.
What lead to different designs in the past?
Posted Mar 16, 2018 9:55 UTC (Fri) by jengelh (subscriber, #33263) [Link]
Not necessarily. I have a tunnel mode setup running that looks like this, and no extra routes are needed.
conn x
leftid=@a
left=5.9.23.70/32
leftsubnet=5.9.23.70/32,88.198.1.160/29
rightid=@b
right=62.245.7.1
rightsubnet=62.245.7.1/32
Virtual private networks with WireGuard
Posted Mar 10, 2018 0:54 UTC (Sat) by pabs (subscriber, #43278) [Link]
Virtual private networks with WireGuard
Posted Mar 10, 2018 6:17 UTC (Sat) by smurf (subscriber, #17840) [Link]
Virtual private networks with WireGuard
Posted Mar 19, 2018 12:04 UTC (Mon) by biergaizi (guest, #92498) [Link]
If I remembered correctly, the lifetime of a single session key is 5 minutes, every five minutes the session key is rotated by X25519 Diffie-Hellman key exchange. The key exchange itself can be further protected by 256-bit ChaCha20 encryption using a pre-shared key, in case a massive quantum computer breaks ECC in the future (yes, it's explicitly designed for this use case) - a quick-and-dirty approach towards Post-Quantum Cryptography. And because the Diffie-Hellman is still there, losing the PSK doesn't affect every a single bit of security without considering quantum computers.
In 2050 when a giant quantum computer have been built by the NSA, all PGP, HTTPS, TLS, IPSec, etc-encrypted data will be broken, but your WireGuard traffic is still secured if your PSK is exchanged out-of-band.
WireGuard: Problem with routing all traffic through the tunnel
Posted Nov 27, 2018 14:01 UTC (Tue) by DarkMelman (guest, #128875) [Link]
1 Client also Ubuntu is working fine a all the traffic goes through the tunnel with config 0.0.0.0/0
When I am using my iPhone with the WireGuard App, with AllowedIPs = 0.0.0.0/0 I can ping the server an the other client but I can’t reach the internet.
When I configured AllowedIPs = 10.0.0.2/24 then I can connect the internet but an Iip-check shows, that its using the public ip from the iPhone and not from the server.
Did anyone have an idea what can be the issue?
Thanks a lot! Best Regards