(https://git.zx2c4.com/WireGuard) WireGuard is an extremely simple yet fast and modern VPN that utilizes state-of-the-art cryptography. It aims to be faster, simpler, leaner, and more useful than IPSec, while avoiding the massive headache. It int ends to be considerably more performant than OpenVPN. WireGuard is designed as a general purpose VPN for running on embedded interfaces and super computers alike, fit for many different circumstances. Initially released for the Linux kernel, it plans to be cross-platform and widely deployable. It is currently under heavy development, but already it might be regarded as the most secure, easiest to use, and simplest VPN solution in the industry.
Simple & Easy-to-use
WireGuard aims to be as easy to configure and deploy as SSH. A VPN connection is made simply by exchanging very simple public keys – exactly like exchanging SSH keys – and all the rest is transparently handled by WireGuard. It is even capable of roaming between IP addresses, just like Mosh. There is no need to manage connections, be concerned about state, manage daemons, or worry about what's under the hood. WireGuard presents an extremely basic yet powerful interface.
WireGuard has been designed with ease-of-implementation and simplicity in mind. It is meant to be easily implemented in very few lines of code, and easily auditable for security vulnerabilities. Compared to behemoths like *Swan/IPsec or OpenVPN/OpenSSL, in which auditing the gigantic codebases is an overwhelming task even for large teams of security experts, WireGuard is meant to be comprehensively reviewable by single individuals.
High Performance
A combination of extremely high speed cryptographic primitives and the fact that WireGuard lives inside the Linux kernel means that secure networking can be very high-speed. It is suitable for both small embedded device like smartphones and fully loaded backbone routers.
Well Defined & Thoroughly Considered
WireGuard is the result of a lengthy and thoroughly considered academic process, resulting in the technical whitepaper, an academic research paper which clearly defines the protocol and the intense considerations that went into each decision.
Conceptual Overview
If you'd like a general conceptual overview of what WireGuard is about, read onward here. You then may progress to installation and reading the quickstart instructions on how to use it.
If you're interested in the internal inner workings, you might be interested in the brief summary of the protocol, or go more in depth by reading the technical whitepaper, which goes into more detail on the protocol, cryptography, and fundamentals. If you intend to implement WireGuard for a new platform, please read the cross-platform notes.
WireGuard securely encapsulates IP packets over UDP. You add a WireGuard interface, configure it with your private key and your peers' public keys, and then you send packets across it. All issues of key distribution and pushed configurations are out of scope of WireGuard; these are issues much better left for other layers, lest we end up with the bloat of IKE or OpenVPN. In contrast, it more mimics the model of SSH and Mosh; both parties have each other's public keys, and then they're simply able to begin exchanging packets through the interface.
Simple Network Interface
WireGuard works by adding a network interface (or multiple), like eth0 or wlan0, called wg0 (or wg1, wg2, wg3, etc). This network interface can then be configured normally using ifconfig(8) or ip-address(8), with routes for it added and removed using route(8) or ip-route(8), and so on with all the ordinary networking utilities. The specific WireGuard aspects of the interface are configured using the wg(8) tool. This interface acts as a tunnel interface.
WireGuard associates tunnel IP addresses with public keys and remote endpoints. When the interface sends a packet to a peer, it does the following:
This packet is meant for 192.168.30.8. Which peer is that? Let me look... Okay, it's for peer ABCDEFGH. (Or if it's not for any configured peer, drop the packet.)
Encrypt entire IP packet using peer ABCDEFGH's public key.
What is the remote endpoint of peer ABCDEFGH? Let me look... Okay, the endpoint is UDP port 53133 on host 216.58.211.110.
Send encrypted bytes from step 2 over the Internet to 216.58.211.110:53133 using UDP.
When the interface receives a packet, this happens:
I just got a packet from UDP port 7361 on host 98.139.183.24. Let's decrypt it!
It decrypted and authenticated properly for peer LMNOPQRS. Okay, let's remember that peer LMNOPQRS's most recent Internet endpoint is 98.139.183.24:7361 using UDP.
Once decrypted, the plain-text packet is from 192.168.43.89. Is peer LMNOPQRS allowed to be sending us packets as 192.168.43.89?
If so, accept the packet on the interface. If not, drop it.
Behind the scenes there is much happening to provide proper privacy, authenticity, and perfect forward secrecy, using state-of-the-art cryptography.
Cryptokey Routing
At the heart of WireGuard is a concept called Cryptokey Routing, which works by associating public keys with a list of tunnel IP addresses that are allowed inside the tunnel. Each network interface has a private key and a list of peers. Each peer has a public key. Public keys are short and simple, and are used by peers to authenticate each other. They can be passed around for use in configuration files by any out-of-band method, similar to how one might send their SSH public key to a friend for access to a shell server.
For example, a server computer might have this configuration:
In the server configuration, each peer (a client) will be able to send packets to the network interface with a source IP matching his corresponding list of allowed IPs. For example, when a packet is received by the server from peer gN65BkIK..., after being decrypted and authenticated, if its source IP is 10.10.10.230, then it's allowed onto the interface; otherwise it's dropped.
In the server configuration, when the network interface wants to send a packet to a peer (a client), it looks at that packet's destination IP and compares it to each peer's list of allowed IPs to see which peer to send it to. For example, if the network interface is asked to send a packet with a destination IP of 10.10.10.230, it will encrypt it using the public key of peer gN65BkIK..., and then send it to that peer's most recent Internet endpoint.
In the client configuration, its single peer (the server) will be able to send packets to the network interface with any source IP (since 0.0.0.0/0 is a wildcard). For example, when a packet is received from peer HIgo9xNz..., if it decrypts and authenticates correctly, with any source IP, then it's allowed onto the interface; otherwise it's dropped.
In the client configuration, when the network interface wants to send a packet to its single peer (the server), it will encrypt packets for the single peer with any destination IP address (since 0.0.0.0/0 is a wildcard). For example, if the network interface is asked to send a packet with any destination IP, it will encrypt it using the public key of the single peer HIgo9xNz..., and then send it to the single peer's most recent Internet endpoint.
In other words, when sending packets, the list of allowed IPs behaves as a sort of routing table, and when receiving packets, the list of allowed IPs behaves as a sort of access control list.
This is what we call a Cryptokey Routing Table: the simple association of public keys and allowed IPs.
Any combination of IPv4 and IPv6 can be used, for any of the fields. WireGuard is fully capable of encapsulating one inside the other if necessary.
Because all packets sent on the WireGuard interface are encrypted and authenticated, and because there is such a tight coupling between the identity of a peer and the allowed IP address of a peer, system administrators do not need complicated firewall extensions, such as in the case of IPSec, but rather they can simply match on "is it from this IP? on this interface?", and be assured that it is a secure and authentic packet. This greatly simplifies network management and access control, and provides a great deal more assurance that your iptables rules are actually doing what you intended for them to do.
Built-in Roaming
The client configuration contains an initial endpoint of its single peer (the server), so that it knows where to send encrypted data before it has received encrypted data. The server configuration doesn't have any initial endpoints of its peers (the clients). This is because the server discovers the endpoint of its peers by examining from where correctly authenticated data originates. If the server itself changes its own endpoint, and sends data to the clients, the clients will discover the new server endpoint and update the configuration just the same. Both client and server send encrypted data to the most recent IP endpoint for which they authentically decrypted data. Thus, there is full IP roaming on both ends.
Ready for Containers
WireGuard sends and receives encrypted packets using the network namespace in which the WireGuard interface was originally created. This means that you can create the WireGuard interface in your main network namespace, which has access to the Internet, and then move it into a network namespace belonging to a Docker container as that container's only interface. This ensures that the only possible way that container is able to access the network is through a secure encrypted WireGuard tunnel.
WireGuard is not yet complete. You should not rely on this code. It has not undergone proper degrees of security auditing and the protocol is still subject to change. We're working toward a stable 1.0 release, but that time has not yet come. There are experimental snapshots tagged with "0.0.YYYYMMDD", but these should not be considered real releases and they may contain security vulnerabilities (which would not be eligible for CVEs, since this is pre-release snapshot software). If you are packaging WireGuard, you must keep up to date with the snapshots.
However, if you're interested in helping out, we could really use your help and we readily welcome any form of feedback and review. There's currently quite a bit of work to do on the project roadmap.
Setting up wireguard-tools (0.0.20180118-1) ...
Setting up wireguard (0.0.20180118-1) ...
Processing triggers for libc-bin (2.23-0ubuntu3) ...
root@RegalMusty-VM:~# which wg
/usr/bin/wg
root@RegalMusty-VM:~# which wg-quick
/usr/bin/wg-quick
root@RegalMusty-VM:~#
(说明安装成功)
在mac上,则运行:brew install wireguard-tools
会显示:
==> Downloading https://homebrew.bintray.com/bottles/wireguard-tools-0.0.2017122
######################################################################## 100.0%
==> Pouring wireguard-tools-0.0.20171221.sierra.bottle.tar.gz
==> Caveats
Bash completion has been installed to:
/usr/local/etc/bash_completion.d
==> Summary
🍺 /usr/local/Cellar/wireguard-tools/0.0.20171221: 7 files, 99.2KB
yudeMacBook-Air:~ brite$ cd /usr/local/Cellar/wireguard-tools
yudeMacBook-Air:wireguard-tools brite$ ls
0.0.20171221
yudeMacBook-Air:wireguard-tools brite$ cd 0.0.20171221
yudeMacBook-Air:0.0.20171221 brite$ ls
COPYING README.md etc
INSTALL_RECEIPT.json bin share
yudeMacBook-Air:0.0.20171221 brite$ ls bin
wg
yudeMacBook-Air:0.0.20171221 brite$ which wg
/usr/local/bin/wg
yudeMacBook-Air:0.0.20171221 brite$
sudo ip link add dev wg0 type wireguard
sudo ip address add dev wg0 10.100.0.1/24
sudo ip link set wg0 up
sudo wg setconf wg0 /etc/wireguard/wg0.conf
sudo iptables -A FORWARD -i wg0 -j ACCEPT
sudo iptables -A FORWARD -o wg0 -j ACCEPT
sudo iptables -t nat -A POSTROUTING -o wg0 -j MASQUERADE
sudo iptables -t nat -A POSTROUTING -o ens4 -j MASQUERADE
sudo ip link add dev wg0 type wireguard
sudo ip address add dev wg0 10.100.0.101/24
sudo ip link set wg0 up
sudo wg setconf wg0 /etc/wireguard/wg0.conf
sudo ip route add 12.34.56.78 via 192.168.1.1
sudo ip route del default
sudo ip route add default dev wg0
PING 10.100.0.1 (10.100.0.1) 56(84) bytes of data.
64 bytes from 10.100.0.1: icmp_seq=1 ttl=44 time=103.50 ms
64 bytes from 10.100.0.1: icmp_seq=2 ttl=44 time=103.50 ms
64 bytes from 10.100.0.1: icmp_seq=3 ttl=44 time=103.50 ms
64 bytes from 10.100.0.1: icmp_seq=4 ttl=44 time=103.50 ms
64 bytes from 10.100.0.1: icmp_seq=5 ttl=44 time=103.50 ms
64 bytes from 10.100.0.1: icmp_seq=6 ttl=44 time=103.50 ms
64 bytes from 10.100.0.1: icmp_seq=7 ttl=44 time=103.50 ms
64 bytes from 10.100.0.1: icmp_seq=8 ttl=44 time=103.50 ms
^C
--- 10.100.0.1 ping statistics ---
8 packets transmitted, 8 received, 0% packet loss, time 828ms
rtt min/avg/max/mdev = 103.50/103.50/103.50/0.00 ms
导入WireGuard配置。打开TunSafe,选择Options,选择Import File…导入单个配置,或者可以拖动单个配置文件到TunSafe窗口完成导入。如果想一次性导入多个文件,可以在Options里选择Browse In Explorer,就会打开C:\Program Files\TunSafe\Config这个文件夹,然后将配置文件一起复制到这个文件夹即可
搜了搜,有这篇文章:Why Can’t I Browse the Internet when Using a GRE Tunnel?- http://www.cisco.com/c/en/us/support/docs/ip/generic-routing-encapsulation-gre/13725-56.html
按上述配置,假定的网络环境如下: 服务器:IP 1.1.1.1,WireGuard内网 IP 192.168.10.1,公网环境 节点1: IP 2.2.2.2,WireGuard内网 IP 192.168.10.40,LAN IP 192.168.1.0/24 节点2: IP 3.3.3.3,WireGuard内网 IP 192.168.10.50,LAN IP 192.168.2.0/24
# 在机器A 上
ip link add dev wg0 type wireguard
umask 077
wg genkey > privateA
wg pubkey < privateA > publicA
cat publicA
wg set wg0 listen-port 51920 private-key ~/privateA peer <PEER_PUBLIC_KEY publicB> allowed-ips 192.168.2.0/24 endpoint <OTHER_SERVER_IP IP_B>:51920
ip link set up dev wg0
ip addr add 192.168.2.1/24 dev wg0
# 在机器B 上
ip link add dev wg0 type wireguard
umask 077
wg genkey > privateB
wg pubkey < privateB > publicB
cat publicB
wg set wg0 listen-port 51920 private-key ~/privateB peer <PEER_PUBLIC_KEY publicA> allowed-ips 192.168.2.0/24 endpoint <OTHER_SERVER_IP IP_A>:51920
ip link set up dev wg0
ip addr add 192.168.2.2/24 dev wg0
配置方法 2. 一端有一端无
# 在机器A(有公网IP) 上
ip link add dev wg0 type wireguard
umask 077
wg genkey > privateA
wg pubkey < privateA > publicA
cat publicA
wg set wg0 listen-port 51920 private-key ~/privateA peer <PEER_PUBLIC_KEY publicB> allowed-ips 192.168.2.0/24
ip link set up dev wg0
ip addr add 192.168.2.1/24 dev wg0
# 在机器B(无公网IP) 上
ip link add dev wg0 type wireguard
umask 077
wg genkey > privateB
wg pubkey < privateB > publicB
cat publicB
wg set wg0 listen-port 51920 private-key ~/privateB peer <PEER_PUBLIC_KEY publicA> allowed-ips 192.168.2.0/24 endpoint <OTHER_SERVER_IP IP_A>:51920
ip link set up dev wg0
ip addr add 192.168.2.2/24 dev wg0
#!/bin/bash
cd /root
source /etc/profile
ip link add wg0 type wireguard
ip link set wg0 up
ip addr add dev wg0 10.1.2.3/24
wg set wg0 private-key privateA peer icaB5UTzeOykCAx80HgbMLOnFhu6btRf4EQdKXUUimc= endpoint 192.227.213.182:51820 allowed-ips 0.0.0.0/0
ip route add 10.1.1.3 via 10.1.2.1
# 然后将脚本置于某一目录,然后在 /etc/network/interfaces 中公网网卡的条目下增加 post-up 即可
# Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: WireGua
r This script will start WireGuard tunnels as specified # in /etc/wireguard/*.conf ### END INIT INFO
. /lib/lsb/init-functions test $DEBIAN_SCRIPT_DEBUG && set -v -x WGQUICK=/usr/bin/wg-quick DESC="WireGuard vir
tual private network daemon" CONFIG_DIR=/etc/wireguard test -x $WGQUICK || exit 0 test -d $CONFIG_DIR || exit 0
nf
case "$1" in start) log_daemon_msg "Starting $DESC" for wg in $CONFIG_DIR/*.c
o do $WGQUICK up `basename $wg .conf` done ;; stop)
$WGQUICK down `basename $wg
log_daemon_msg "Stopping $DESC" for wg in $CONFIG_DIR/*.conf do
.conf` done ;; *)
WARNING WARNING WARNING WARNING WARNING WARNING WARNING W G W You are running this software on a Linux kernel, G W which is probably unnecessary and foolish. This G W is because the Linux kernel has built-in first G W class support for WireGuard, and this support is G W much more refined than this slower userspace G W implementation. For more information on G W installing the kernel module, please visit: G W https://www.wireguard.com/install G W G W If you still want to use this program, against G W the advice here, please first export this G W environment variable: G W WG_I_PREFER_BUGGY_USERSPACE_TO_POLISHED_KMOD=1 G W G WARNING WARNING WARNING WARNING WARNING WARNING WARNING
会得到类似这样的结果: root@ovzhost:/etc/wireguard# wg-quick up wg0
[#] ip link add wg0 type wireguard RTNETLINK answers: Operation not supported [!] Missing WireGuard kernel module. Falling back to slow userspace implementation. [#] wireguard-go wg0 WARNING WARNING WARNING WARNING WARNING WARNING WARNING W G W You are running this software on a Linux kernel, G W which is probably unnecessary and foolish. This G W is because the Linux kernel has built-in first G W class support for WireGuard, and this support is G W much more refined than this slower userspace G W implementation. For more information on G W installing the kernel module, please visit: G W https://www.wireguard.com/install G W G WARNING WARNING WARNING WARNING WARNING WARNING WARNING INFO: (wg0) 2019/04/19 09:45:50 Starting wireguard-go version 0.0.20190409-9-gd024393 [#] wg setconf wg0 /dev/fd/63 [#] ip address add 10.0.0.1/24 dev wg0 [#] ip link set mtu 1420 up dev wg0 [#] iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o venet0 -j MASQUERADE
As an alternative to IPsec, WireGuard is an extremely simple (less than 5,000 lines of code) yet fast and modern VPN that utilizes state-of-the-art and opinionated cryptography (Curve25519, ChaCha20, Poly1305) and whose protocol, based on Noise, has been formally verified. It is currently available as an out-of-tree module for Linux but is likely to be merged when the protocol is not subject to change anymore. Compared to IPsec, its major weakness is its lack of interoperability.
It can easily replace strongSwan in our site-to-site setup. On Linux, it already acts as a route-based VPN. As a first step, for each VPN, we create a private key and extract the associated public key:
$ wg genkey
oM3PZ1Htc7FnACoIZGhCyrfeR+Y8Yh34WzDaulNEjGs=$echo oM3PZ1Htc7FnACoIZGhCyrfeR+Y8Yh34WzDaulNEjGs=| wg pubkey
hV1StKWfcC6Yx21xhFvoiXnWONjGHN1dFeibN737Wnc=
Then, for each remote VPN, we create a short configuration file:1
A new ListenPort value should be used for each remote VPN. WireGuard can multiplex several peers over the same UDP port but this is not applicable here, as the routing is dynamic. The AllowedIPs directive tells to accept and send any traffic.
The next step is to create and configure the tunnel interface for each remote VPN:
$ ip link add dev wg3 type wireguard
$ wg setconf wg3 wg3.conf
WireGuard initiates a handshake to establish symmetric keys:
$ wg show wg3
interface: wg3 public key: hV1StKWfcC6Yx21xhFvoiXnWONjGHN1dFeibN737Wnc= private key: (hidden) listening port: 5803peer: Jixsag44W8CFkKCIvlLSZF86/Q/4BovkpqdB9Vps5Sk= endpoint: [2001:db8:2::1]:5801 allowed ips: 0.0.0.0/0, ::/0 latest handshake: 55 seconds ago transfer: 49.84 KiB received, 49.89 KiB sent
Like VTI interfaces, WireGuard tunnel interfaces are namespace-aware: once created, they can be moved into another network namespace where clear traffic is encapsulated and decapsulated. Encrypted traffic is routed in its original namespace. Let’s move each interface into the private namespace and assign it a point-to-point IP address:
$ ip link set netns private dev wg3
$ ip -n private addr add 2001:db8:ff::/127 dev wg3
$ ip -n private link set wg3 up
The remote end uses 2001:db8:ff::1/127. Once everything is setup, from one VPN, we should be able to ping each remote host:
$ ip netns exec private fping 2001:db8:ff::{1,3,5,7}2001:db8:ff::1 is alive2001:db8:ff::3 is alive2001:db8:ff::5 is alive2001:db8:ff::7 is alive
BIRD configuration is unmodified compared to our previous setup and the BGP sessions should establish quickly:
$ birdc6 -s /run/bird6.private.ctl show proto | grep IBGP_
IBGP_V2_1 BGP master up 20:16:31 EstablishedIBGP_V2_2 BGP master up 20:16:31 EstablishedIBGP_V3_1 BGP master up 20:16:31 EstablishedIBGP_V3_2 BGP master up 20:16:29 Established
Remote routes are learnt over the different tunnel interfaces:
$ ip -6 -n private route show proto bird
2001:db8:a1::/64 via fe80::5254:33ff:fe00:13 dev eth2 metric 1024 pref medium2001:db8:a2::/64 metric 1024 nexthop via 2001:db8:ff::1 dev wg3 weight 1 nexthop via 2001:db8:ff::3 dev wg4 weight 12001:db8:a3::/64 metric 1024 nexthop via 2001:db8:ff::5 dev wg5 weight 1 nexthop via 2001:db8:ff::7 dev wg6 weight 1
From one site, you can ping an host on the other site through the VPNs:
$ ping -c 22001:db8:a3::1
PING 2001:db8:a3::1(2001:db8:a3::1) 56 data bytes64 bytes from 2001:db8:a3::1: icmp_seq=1 ttl=62 time=1.54 ms64 bytes from 2001:db8:a3::1: icmp_seq=2 ttl=62 time=1.67 ms--- 2001:db8:a3::1 ping statistics ---2 packets transmitted, 2 received, 0% packet loss, time 1001msrtt min/avg/max/mdev = 1.542/1.607/1.672/0.065 ms
As with the strongSwan setup, you can easily snoop unencrypted traffic with tcpdump:
$ ip netns exec private tcpdump -c3 -pni wg5 icmp6
tcpdump: verbose output suppressed, use -v or -vv for full protocol decodelistening on wg5, link-type RAW (Raw IP), capture size 262144 bytes08:34:34 IP6 2001:db8:a3::1 > 2001:db8:a1::1: ICMP6, echo reply, seq 4008:34:35 IP6 2001:db8:a3::1 > 2001:db8:a1::1: ICMP6, echo reply, seq 4108:34:36 IP6 2001:db8:a3::1 > 2001:db8:a1::1: ICMP6, echo reply, seq 423 packets captured3 packets received by filter0 packets dropped by kernel
You can find all the configuration files for this example on GitHub.
Update (2018.11)
It is also possible to transport IPv4 on top of IPv6 WireGuard tunnels. The lab has been updated to support such a scenario.
from https://vincent.bernat.ch/en/blog/2018-route-based-vpn-wireguard
----------------------------
from https://mp.weixin.qq.com/s/OvqpL9aO6oMSL4GgjE6zbw
------------------------------------------------
Why Not WireGuard
The latest thing that is getting a lot of attention is WireGuard - the new shooting star in terms of VPN. But is it as great as it sounds? I would like to discuss some thoughts, have a look at the implementation and tell you why WireGuard is not a solution that will replace IPsec or OpenVPN.
In this article I would like to debunk the myths. It is a long read. If you are in need of a tea or coffee, now is the time to make it. Thanks to Peter for proof-reading my chaotic thoughts.
I do not want to discredit the developers of WireGuard for their efforts or for their ideas. It is a working piece of technology, but I personally think that it is being presented as something entirely different - as a replacement for IPsec and OpenVPN which it simply is not.
As a side-note, I think that the media is responsible for this and not the WireGuard project itself.
There has not been much positive news around the Linux kernel recently. They have reported of crushing processor vulnerabilities that have been mitigated in software, Linus Torvalds using too harsh language and just boring developer things. The scheduler or a zero-copy network stack are not very approachable topics for a glossy magazine. WireGuard is.
It sounds great on paper, it is exciting new technology.
Let's have a closer look.
The WireGuard Whitepaper
This article is based on the WireGuard Whitepaper written by Jason Donenfeld. In there he explains the concept, objective and technical implementation in the Linux kernel.
The first sentence says:
WireGuard [...] aims to replace both IPsec for most use cases, as well as popular user space and/or TLS-based solutions like OpenVPN, while being more secure, more performant, and easier to use.
Of course the biggest selling points of some new technology are that it is easy. VPNs also need to be performant and secure.
What else would they say here?
If that is not your design goal, then you will probably have no chance. However, those are exactly the same goals for literally every other VPN technology, too.
The more interesting part of that sentence is "for most use cases". That has been removed by the press and here we are in the middle of this mess.
Will WireGuard replace my (IPsec) site-to-site VPN?
No. There is no chance the big vendors like Cisco, Juniper, etc. will pick up WireGuard. They do not jump onto trains like this unless there is a big necessity.
I will later cover a couple of reasons why they probably can't ship WireGuard even if they wanted to.
Will WireGuard replace my roadwarrior from my laptop to the data centre?
No. Right now, WireGuard has a huge backlog of features that it needs to implement to be suitable for this use-case. It does not, for example, allow using a dynamic IP address on the server side of the tunnel which breaks a whole use-case.
IPFire is often used on a cheap Internet uplink like a DSL or cable connection. For branch offices and small to even medium businesses, this makes sense and saves money on an expensive fibre uplink which isn't needed by everyone. However, DSL, cable, LTE and all other sorts of wireless connections come with dynamic IP addresses. Sometimes it does not change that often, but it still is dynamic.
There is a sub-project called "wg-dynamic" which adds a user-space daemon to overcome this shortcoming. A massive design flaw because of the use-cases stated above, but it is even worse that IPv6 is all about dynamic addressing.
From a distributor's point of view, this is also quite disappointing. One of the design goals was to keep the protocol lean and simple.
Unfortunately it has become too simple that more software is now necessary to make it work in the real world.
So it is easy to use then?
Not yet. I am not saying that WireGuard won't reach a point where it is a good alternative for host-to-net connections, but so far it just is an alpha version of what it aims to be.
But what does it actually try to solve? Is IPsec really hard to use?
No, it clearly is not if the vendor has done their homework right and provides an interface that is easy to use - like IPFire.
To setup an IPsec VPN tunnel you will need to have five pieces of information that you will have to type in: Your own public IP address, the public IP address of your peer, the subnets that you want to make available through this VPN for each side and a pre-shared-key. That way, the VPN is set up within minutes and it is compatible with every vendor out there.
Unfortunately there are some exceptions out there. Everyone who has ever tried to create an IPsec tunnel to an OpenBSD machine can probably tell a tale of that. There are some more black sheep out there, but there are just as many good examples.
On Protocol Complexity
The end-user does not have to worry about the complexity of the protocol.
If that was an issue we would have definitely gone rid of SIP and H.323, FTP and other protocols that don't cope well with NAT and are decades old.
There are reasons why IPsec is more complex than WireGuard: It does so many more things. User-authentication using username/password or a SIM card with EAP. It is extensible that new cryptographic primitives can be added.
WireGuard does not have that.
That means WireGuard will break at some point, because one of the cryptographic primitives will weaken or entirely break at some point. The author says:
Finally, WireGuard is cryptographically opinionated. It intentionally lacks cipher and protocol agility. If holes are found in the underlying primitives, all endpoints will be required to update. As shown by the continuing torrent of SSL/TLS vulnerabilities, cipher agility increases complexity monumentally.
The last sentence is absolutely true.
Negotiating what cipher to use makes protocols like IKE and TLS more complex. But is it too complex? Indeed vulnerabilities have often been found in the protocol handshake. There is no alternative to this.
On Ignoring Real-World Problems
Imagine you have a VPN server with 200 road warrior clients somewhere out there in the world - which is a very normal use-case. If you were to change the cipher you are using from one day to the next one, you would need to upgrade your WireGuard software on all those laptops, phones, etc. at the same time. That is literally impossible. Administrators who have tried this needed months to deploy configuration changes. Sometimes even middle-sized companies need years to conduce a process like this.
IPsec and OpenVPN offer cipher negotiation. So for a while you will turn on the new cipher and gradually update all clients. After that is done you will turn off using the broken cipher and you are done. The clients won't even notice.
This is a very common task in large deployments and OpenVPN has been a pain with this, too. Compatibility matters and although you are using some weaker cipher, for many this is no reason to shut down their business and cut off hundreds of sales people from doing their job.
WireGuard made their protocol easier, but entirely unusable for people who are not in permanent control of both peers. In my experience this is by far the most likely case.
Cryptography!
But what are all those exciting new ciphers that WireGuard is using?
WireGuard utilizes Curve25519 for key exchange, ChaCha20 for encryption, and Poly1305 for data authentication, SipHash for hashtable keys, and BLAKE2s for hashing.
ChaCha20-Poly1305 is standardised for both, IPsec and OpenVPN (through TLS).
It is obvious that Daniel J. Bernstein's work is being used here a lot. BLAKE2 is the successor of BLAKE, a SHA-3 finalist which did not win because of its close similarity to SHA-2. If SHA-2 would have been broken, there is a good chance that BLAKE breaks, too.
IPsec and OpenVPN do not need SipHash because of their design. So the only thing that is currently not usable with those is BLAKE2 until it is standardised. That is not much of a disadvantage, because VPNs use HMACs for integrity, which still is considered strong even with MD5.
I would conclude that practically the same cryptography is available for all VPNs here. Therefore WireGuard is not more or less secure than the others when it comes to encryption or data integrity.
But that isn't the focus, according to the whitepaper. Speed is.
Is WireGuard faster than other VPN solutions?
Simple answer: It isn't.
ChaCha20 is a stream cipher which are easier to implement in software. They encrypt one bit at a time. Block ciphers like AES encrypt a block of 128 bits at a time. That would need many more transistors when implemented in hardware, so larger processors come with AES-NI - an instruction set extension that performs some tasks of the encryption process to speed it up.
AES-NI was not expected to land in smartphones and ChaCha20 was developed as a lightweight and battery-saving alternative. So it might surprise you that every smartphone that you can buy today has some sort of acceleration for AES and perform it faster and more energy-efficiently than ChaCha20.
Obviously virtually every desktop/server CPU bought in the last couple of years has AES-NI.
Hence I expect AES to outperform ChaCha20 in every single scenario. The WireGuard whitepaper mentions due to AVX512, ChaCha20-Poly1305 will outperform AES-NI1, but that instruction set extension will only be available on large processors which again won't help with smaller and mobile hardware that will always be faster with AES-NI.
I am not sure if this could have been foreseen when WireGuard was drafted, but today it is already a disadvantage that it is nailed to one cipher which might not perform very well.
IPsec allows you to freely choose what cipher is best for your setup. Certainly that is necessary when you want to transfer 10G or more over a VPN connection.
Issues integrating into Linux
So although WireGuard has chosen modern cryptography, this has already causes loads of problems. Instead of using what the Linux kernel provides, the integration of WireGuard was delayed by years due to lack of those primitives in Linux.
I am not sure what the situation is like in other operating systems, but probably not very different.
What does the real world look like?
Unfortunately every time, when a customer asks me to help them setting up a VPN, the credentials that they are getting are using old ciphers. 3DES in combination with MD5 is a common candidate as well as AES-256 with SHA1. Although the latter is better, it is still not what I would like to use today.
For the key exchange RSA is always being used, which is slow, but still secure enough.
These customers have connections with customs authorities or other government agencies and large corporations in the world which names we all know. They all use an order form that has been created decades ago and an option for "SHA-512" has simply never been added. It is isn't always the technology that is stopping innovation, but slow corporate processes.
It hurts me to see this because IPsec has support for Elliptic Curves since around 2005. Curve25519 is newer and available, too. Alternatives to AES like Camellia and ChaCha20 are also specified, but obviously not all of them are implemented by the big vendors like Cisco and so on.
That is however what people are using out there. There is a lot of Cisco boxes out there, and those that are not Cisco are made to work with Cisco. They are the market leader in this segment and not very much interested in driving innovation.
This is awful, but we won't see that change with WireGuard. The vendors will probably not see any performance issues with their existing choice of ciphers, no interoperability issues when using IKEv2 - and therefore there is little pressure for them to offer alternatives.
The whitepaper benchmarks WireGuard. Although it is not a scientific paper, I would still expect a scientific approach to a benchmark. It is worthless if it cannot be repeated and it is worthless when it does not examine the software in a realistic lab setup.
In the Linux implementation, WireGuard is gaining an advantage by using GSO - Generic Segmentation Offloading. It creates a huge packet of 64 kilobytes and encrypts or decrypts it in one go. That way, overhead of initialising and calling cryptographic operations is being saved. If you want to maximise throughput that is a good idea to do.
However, things are again not so easy in reality. Sending such a large packet to the network adapter will require that it is being cut into many smaller packets. Usually of 1500 bytes. 64 kilobytes would result in 45 packets (1480 bytes payload and 20 bytes IP header per packet). Those will then block the adapter for quite some time, because they all will be sent in one go. Packets that should be prioritised like VoIP calls will have to wait.
So the high throughput that WireGuard claims to achieve is being bought by making other applications slower. This needs to go and the WireGuard team has already acknowledged it2.
But they went further.
The benchmark in the whitepaper shows a throughput of 1011 MBit/s.
Impressive.
Especially because the maximum theoretical throughput of a one Gigabit Ethernet link is 966 MBit/s at a packet size of 1500 bytes, minus 20 bytes IP header, 8 bytes UDP header and 16 bytes WireGuard header, another IP header in the encapsulated packet and another TCP header of 20 bytes. Where is this extra bandwidth coming from?
With jumbo frames enabled and the GSO advantages from above, the theoretical maximum at 9000 bytes frame size would be 1014 MBit/s. Normally, that won't be achievable in reality because there is more overhead. So I can only assume that the benchmark was made using even larger jumbo frames at 64 kilobytes with a theoretical maximum of 1023 MBit/s, which is supported by some network adapters. However, that is absolutely not practical in reality, but can be used with a direct link between the two systems executing the benchmark.
Since a VPN is usually built to connect two hosts over the Internet, which supports no jumbo frames at all, this is not a fair benchmark. It is an unrealistic lab setup which could never be applied in the real world.
Not even inside a data center I would expect to be able to transmit frames larger than 9000 bytes.
This benchmark is absolutely broken and I think that the author has discredited himself a lot for obvious reasons.
A last glimmer of hope
WireGuard's website talks a lot about containers. And clearly this is what this is designed for.
A simple and fast VPN, that takes nothing to set up and can be rolled out and configured by large orchestration tools like Amazon would have them for their cloud. They are using latest hardware features like AVX512 to be fast, but not tie themselves to x86 or another architecture.
They optimise for throughput and packets that are larger than 9000 bytes - that would be jumbo frames being encapsulated when two containers are talking to each other, or to backup, snapshot and deploy container images. Even dynamic IP addresses will not matter in this scenario.
Well done. Brilliant implementation and very lean and almost elegant protocol.
But it simply is not made for a world outside of the data centre in which you control everything. Otherwise you start making compromises on the design and implementation of the protocol.
Conclusion
It is not very hard for me to conclude that WireGuard is not ready - yet.
It has been drafted as a lightweight and fast solution to some problems of the existing solutions. Unfortunately it has sacrificed many features that will be relevant for many users and therefore will not be able to replace IPsec and OpenVPN.
For that we need to add at least IP address assignment, pushing configuration like DNS servers and routes. Obviously this needs cipher negotiation, too.
Security is my top priority and I have currently no reason to believe that IKE or TLS are intrinsically broken. Modern ciphers are supported in both of them and they have all been audited over decades. Just because something is newer, does not mean that it is better.
Interoperability is important when you connect with third parties that you do not control. IPsec is established as the de-facto standard and is virtually supported everywhere. It works. As it even looks, WireGuard might not even be compatible with itself in the future.
Cryptography breaks and things need to be replaced and updated.
Denying any of this and still wanting to use WireGuard to connect your iPhone to your home is a masterclass of putting your head in the sand.
No comments:
Post a Comment