|
|
Subscribe / Log in / New account

Virtual private networks with WireGuard

Benefits for LWN subscribers

The primary benefit from subscribing to LWN is helping to keep us publishing, but, beyond that, subscribers get immediate access to all site content and access to a number of extra site features. Please sign up today!

By Jonathan Corbet
March 6, 2018
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
KernelNetworking/Virtual private networks
SecurityEncryption/Network
SecurityLinux 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]

It might be worth noting that even the Penguin Chief himself has expressed his opinion on wanting WireGuard merged: https://lkml.org/lkml/2018/2/13/752

Virtual private networks with WireGuard

Posted Mar 6, 2018 15:44 UTC (Tue) by zx2c4 (subscriber, #82519) [Link]

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

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 (guest, #99903) [Link]

> It will be interesting to try WireGuard at the next conference with an overloaded network to see how well it copes with packet loss.

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]

The nice thing about ipsec vpn's is that there is a fair amount of intervendor interoperability that is possible. A mixed vendor ipsec network with Cisco, Juniper and Ubiquiti endpoints is possible. OpenVPN is portable to lots of different platforms.

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 (subscriber, #111931) [Link]

While there is no guarantee of adoption, there is a page and a plan for cross-platform userspace implementations: https://www.wireguard.com/xplatform/

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]

Assuming you mean it would work with the Unified Security Gateway and/or EdgeRouter series of equipment? Anything else (I overlap in current Ubiquiti owner + potential fan of wireguard after seeing Thomas Ptacek say such nice things about it.)

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]

Ah thanks! They both run EdgeOS, so it will probably work on the security gateway as well. I might give it a go and let upstream know.

Virtual private networks with WireGuard

Posted Mar 10, 2018 0:53 UTC (Sat) by coolhandluke (guest, #114151) [Link]

Just to chime in for the possible benefit of others and in addition to the other comments here, Jason (zx2c4) previously stated [0] that "Mac and Windows support ... [is] already mostly done" but that "there may still be a bit of work to do here".

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]

Using the included wg-quick (https://git.zx2c4.com/WireGuard/about/src/tools/wg-quick.8) makes configuration and management a bit easier, giving away some control.

Virtual private networks with WireGuard

Posted Mar 6, 2018 20:41 UTC (Tue) by zdzichu (subscriber, #17118) [Link]

Moreover, systemd-networkd includes support for WireGuard for couple of versions. The config file format is of course the same. So basically Linux distribution will support WireGuard almost universally the moment it's included in kernel.

Virtual private networks with WireGuard

Posted Mar 6, 2018 19:03 UTC (Tue) by Cyberax (✭ supporter ✭, #52523) [Link]

What is the advantage compared to IPSec? The in-kernel ipsec encryption is perfectly adequate for most purposes (just ignore the crappy ciphers).

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]

The key advantage as stated was a vastly smaller implementation (4000 lines) making vastly easier to check for flaws.
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]

I am absolutely naive with VPNs, so my questions might be totally off, but one thing I find potentially dangerous is the ability to silently loose a VPN connection. If you are transmitting sensitive data over a link that you know is most probably under surveillance, you absolutely don't want the VPN to disconnect and your data transfer to resume over the non-VPN network (when accessing public IPs). Is it something that is addressed at the VPN level or should it be addressed at another level? Does WireGuard offers something to prevent it?

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]

Wireguard does not "lose a connection" the way a VPN link dies. The connection and the rest of the kernel setup are is still there, packets simply get dropped until the connection is re-established.

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]

In the case where all traffic absolutely *must* go over a VPN (or else not be sent at all), I have previously configured firewall rules (both on the host itself as well as its upstream router, for an additional layer of defense) to only permit outbound IP traffic destined to the VPN gateway and drop any other traffic.

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]

Wireguard simply throws away packets it can't decrypt. It works at wire speed (for some definition of "wire", anyway) so even if you saturate the link with bogus encrypted packets, that's no worse than saturating it with any other kind of packet.

Android will get a userspace implementation.

Virtual private networks with WireGuard

Posted Mar 8, 2018 5:37 UTC (Thu) by thestinger (guest, #91827) [Link]

It's worth noting that as of Android 8.0, there's a toggle to block connections not made via the always-on VPN to deal with issues like an OpenVPN app dying. A kernel implementation is more efficient but there's a sane way to use userspace VPN implementations.

Virtual private networks with WireGuard

Posted Mar 6, 2018 20:36 UTC (Tue) by judas_iscariote (guest, #47386) [Link]

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

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]

What does the systemd equivalent of the example command in the article look like? I don't run it, just curious.

Virtual private networks with WireGuard

Posted Mar 7, 2018 23:04 UTC (Wed) by smurf (subscriber, #17840) [Link]

There is no special command; if you need the command line, continue to use "wg".

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]

Would be nice to also have the support for WireGuard interfaces added to netctl

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]

One very useful aspect of the Anyconnect-style (at least ocserv) certificate management is that I can embed a host name in the key and not need to worry about setting up my own mapping. As far as I can tell, WireGuard punts that to higher-level tools. The choice is fine but may slow deployment.

(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]

Are you sure "ip addr add 10.0.0.1/24 wg0" shouldn't be "ip addr add 10.0.0.1/24 dev wg0"?

What lead to different designs in the past?

Posted Mar 9, 2018 10:00 UTC (Fri) by jarmar (guest, #103679) [Link]

I am not a kernel programmer, but reading through the introduction and motivation in the white paper, this (behaving like any other network interface) seems like the "obvious" way to implement VPNs (as also evidenced by the small amount of code required). For that reason, it would be interesting to read why previous offerings *didn't* use this solution. What are the downsides of this approach? The whitepaper mentions:

> 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]

This isn't innovative. There were always two approaches, WireGuard just choose one of them.

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]

IPSec tunnels encapsulate packets much as do other tunnels, but they behave very differently in practice. IPSec policy, for both tunnel and transport mode, imposes a colleciton of special cases on the normal routing path. I tend think of it as another, particularly rigid firewall/NAT layer. I find it much easier to internalize the "route-based" and "point-to-point" IPSec modes: VTI and BEET respectively. The former has broad industry support and allows you to largely opt-out of key elements of the original IPSec design. That's about as politic as I can be on the subject.

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]

>with tunnel mode you get another set of network address prefixes to deal with, which complicates routing.

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]

Does WireGuard have forward secrecy?

Virtual private networks with WireGuard

Posted Mar 10, 2018 6:17 UTC (Sat) by smurf (subscriber, #17840) [Link]

Yes. You can also add a pre-shared key for further data confabulation.

Virtual private networks with WireGuard

Posted Mar 19, 2018 12:04 UTC (Mon) by biergaizi (guest, #92498) [Link]

I believe WireGuard offers the most robust, latest state-of-art cryptography and the highest performance and best quality of implementation compared to any other solutions. Even the humble base64 encoding is implemented in cryptographic-grade constant-time code.

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]

I have a working setup with WireGuard „Server“ on a Ubuntu 18.04.1 System.
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


Copyright © 2018, Eklektix, Inc.
This article may be redistributed under the terms of the Creative Commons CC BY-SA 4.0 license
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds