Here are a few quick facts about WireGuard, from the project website:
Project website: www.wireguard.com
Lead developer: Jason A. Donenfeld.
WireGuard and service
marks are registered trademarks of Jason A. Donenfeld.
I have just gone through yet another audit of my VPNs, making sure that
they work for all relevant clients and that the vpn-tester program can
competently report if they are or aren't working. Currently my two servers run
StrongS/WAN IPSec (strongswan-ipsec-5.9.3 on SuSE Tumbleweed) and OpenVPN
(openvpn-2.5.3 on SuSE Tumbleweed). The clients have Linux (same versions)
strongSwan VPN Client (version 2.3.3,
OpenVPN for Android (version 0.7.25,
de.blinkt.openvpn). Both VPNs work well when properly configured, but they
have a number of less than wonderful features:
/etc/ipsec.conf is just about the most arcane and confusing configuration file I know. Changes turn into a day of troubleshooting. The VICI (swanctl) file format and control interface is an improvement, taking it from abominable to merely unpleasant.
OpenVPN's configuration file is relatively sane, but there are so many features available, and I seem to need to configure more than my share of them. Particularly, I found internal routes to be a challenge: if a packet goes into the tunnel device, should it be sent to the other end (or be spit right back out), and should the other end put out the packet (versus sending it back to the other end of the tunnel, oopsie)? Usually the implicit iroutes get it right, but it's very frustrating when they don't.
The network paradigm for IPSec is, if an IPv6 packet has an IPSec header, the corresponding Security Association has the information (crypto algo, key, etc.) which the kernel can use to decrypt it. The headers thus revealed are than processed normally. Outgoing packets are selected by a Traffic Selector (different from normal routing) and the inverse transformation is performed, after which the encrypted packet is sent out through normal routing. IPv4 uses ESP and AH protocol packets instead. I found that it was often a challenge to get the Traffic Selector right.
OpenVPN uses a tun/tap device, and payload packets pop out of it or are stuffed into it by normal routes, as if it were a physical net interface. It's a lot easier to handle routing in this context, but there's got to be overhead dealing with the software interface.
IPSec connects very promptly, initially or after a net disruption, but OpenVPN takes several seconds to do this.
Both IPSec and OpenVPN have a lot of code in the packages: around 400,000 and 600,000 lines of code. This doesn't affect the end user directly, but I remeber a quote from Weitse Venema, the author of the Postfix mail transport agent: he says his code has about one bug per thousand lines in it, and if you introduce complexity (he was talking about TLS for mail transport) you should think about exploits against the bugs and accidental loss of service.
Responding to shortcomings in existing VPN software, Jason A. Donenfeld in 2015 began to develop WireGuard, a new VPN. It has these features; whether they're scored as good or bad depends on the user's goals.
Drastically reduced complexity; features not absolutely essential were sacrificed for this goal. He claims only 4000 lines of code.
A lot fewer configurable aspects; for example there is [currently] only one crypto algo, ChaCha20Poly1305, so no configuration and no negotiation with the peer. Negotiation is very complex for both IPSec and OpenVPN.
WireGuard does UDP only, no TCP and no unusual protocols like ESP. Check out udptunnel and udp2raw for add-on layers if you need TCP.
Very fast connection setup: the initiator sends and gets back a Diffie-Hellman key exchange; each side sends its public key; and you're ready for payload packets. [Verify this in detail]
The protocol isn't chatty: the only packets sent are payloads and key establishment (and rekeying). You can configure keepalive packets if your net needs them.
What are my goals for the VPNs, and how much hassle will it be to make WireGuard deliver what I need, so it can become one of them?
Resistance to bit-rot: changes in the system configuration tend to have a bad effect on operation of the VPNs, and I hope WireGuard will be affected less than IPSec and OpenVPN.
While I always use UDP if feasible, I've found that hotel Wi-Fi often blocks UDP in general and VPN ports in particular. Thus I support and use TCP on port 443, which the Wi-Fi access points have got to pass. (Note: some authoritarian nations block VPN ports nationally. 443/TCP can bypass this, but the Secret Police could recognize that it was fake, with baleful consequences for the perpetrator.)
There are three VPN routes:
The segment tunnel, from the main router Jacinth to a host in the cloud. See A Server in the Clouds for what is being accomplished here. Basically the local net's default route for IPv6 goes out via the cloud host.
Xena and Petra to Jacinth: Xena is my laptop, which roams, and Petra is a virtual machine on it for development. See Network for Xena's Virtual Machine. But how do other hosts know where to send packets destined for Xena and Petra? Solution: they always send via Jacinth, and Xena always has a VPN to Jacinth even when it's not roaming.
Selen to Jacinth. Selen is a cellphone with Android, and it also roams. To get to the webmail and PIM server from off-site it needs a VPN. See Jimc's Awesome PIM Server for the packages I'm using.
For authorization, VPNs can be set up two ways. In the original design each connection has individual credentials installed, typically in the form of pre-shared symmetric keys. Modern versions, such as IPSec and OpenVPN (starting in version 2.x), give a credential (normally a X.509 certificate and its asymmetric key) to the server and to each client; the client certs are all signed by one Certificate Authority (or intermediate cert) which the server requires in the client's trust chain. The server doesn't need the clients' certs individually. I don't really have a herd of users and I can handle either arrangement (I have my own Certificate Authority), but X.509 certs are what I'm using now.
For the symmetric cipher on the main channel, WireGuard uses only ChaCha20Poly1305, for which hardware acceleration is very rare. On the Intel Core® i5-10210U, jimc's tests score it as half as fast as hardware accelerated AES-256 (Rijndael), and twice as fast as software AES-256. This difference would only be significant for a server with thousands of clients.
ip link add dev wg0 type wireguard #Pick a name for the tunnel device ip address add dev wg0 192.168.2.1/24 [ peer 192.168.2.2 ] if only 1 peer wg setconf wg0 myconfig.conf (wg utility is provided) --or-- wg set wg0 listen-port 51820 private-key /path/to/private-key peer $itsname \ allowed-ips 192.168.88.0/24 endpoint 18.104.22.168:8172 ip link set up dev wg0
wg (with no args) is equiv to wg show (for all interfaces e.g. wg0) wg-quick [up|down|etc] ctlfile
Wireguard wants base64 encoded private and public keys in its own format, It does not use X.509 certificates to authenticate/authorize the peers. use "wg genkey } tee privatekey | wg pubkey > publickey"
You may test with their demo server.
So let's try to set something up. for timing purposes, I'm starting this at 2021-10-07 18:00. I'm going to use these basic steps:
Make sure there's a client for Android. Install it first but don't
try to use it yet. Yes there is one, called WireGuard, with the serpent
logo (®). Inception 2019-10-13, most recent update 11 days go,
offered by WireGuard Development Team.
You could import a configuration from a file, or a QR code (!), or create
it by hand. I looked but didn't create my connection. 7 mins including
reading the product info.
The required kernel module is called wireguard.ko and it is in the
standard kernel. To pass configuration information to it (plus displaying
connection info and generating keys) you need wireguard-tools-1.0.20210914
from the OpenSuSE Tumbleweed main distro. Older versions are available for
Leap 15.3 and 15.2. 72Kb to download, 145Kb installed. No dependent
packages; it only requires systemd and libc. The package only contains
wg-quick commands, and documentation.
wg-quick is a wrapper around wg for simple configurations. When either
command is given just an interface name such as
wg0, the corresponding
configuration file is sought in /etc/wireguard/wg0.conf, whereas if an absolute
pathname is given the interface is inferred from the basename of the conf file.
The interface name may be up to 15 bytes of [a-zA-Z0-9_=+.-] . (You don't
specify the interface name inside the conf file.)
About 20min to install the packages and read the man pages.
See the wg man page for the format and configurable options in the conf file. Here is the client's configuration file for testing. See the genkey subcommand for producing your own keys. The conf file contains your private key (not encrypted), so it should have appropriately restrictive permissions.
[Interface] PrivateKey = qwerty...= # 42 base64 bytes, about 256 bits. Keep the =. ListenPort = 4886 # Android wakeup port, which my firewall # allows, but I'll have to change this later. [Peer] PublicKey = asdfgh...= # 42 base64 bytes, about 256 bits. Endpoint = [2600:3c01:e000:306::8:1]:4886 # IPv6 in , colon its port AllowedIPs = # There can be multiple peers.
About 25min + to write the conf files.
Fix bugs. This will require assigning a new address range for client addresses. Fix bugs.
Using the newly installed NetworkManager plugin for WireGuard. Get Xena back on the net.
(Jacinth to Surya) from OpenVPN to WireGuard. Fix bugs.