MirageVPN updated (AEAD, NCP)
Updating MirageVPN
As announced earlier this month, we've been working hard over the last months on MirageVPN (initially developed in 2019, targeting OpenVPN™ 2.4.7, now 2.6.6). We managed to receive funding from NGI Assure call (via NLnet). We've made over 250 commits with more than 10k lines added, and 18k lines removed. We closed nearly all old issues, and opened 100 fresh ones, of which we already closed more than half of them. :D
Actual bugs fixed (that were leading to non-working MirageVPN applications)
In more detail, we had a specific configuration running over all the years, namely UDP mode with static keys (no TLS handshake, etc.). There were several issues (bitrot) that we encountered and solved along the path, amongst others:
- related to the static-key mode and TCP/IP,
- the order of ACK between the client and the server,
- outgoing TLS packets.
To avoid any future breakage while revising the code (cleaning it up, extending it), we are now building several unikernels as part of our CI system. We also have setup OpenVPN™ servers with various configurations that we periodically test with our new code (we'll also work on further automation thereof).
New features: AEAD ciphers, supporting more configuration primitives
We added various configuration primitives, amongst them configuratble tls ciphersuites, minimal and maximal tls version to use, tls-crypt-v2, verify-x509-name, cipher, remote-random, ...
From a cryptographic point of view, we are now supporting more authentication hashes via the configuration directive auth
, namely the SHA2 family - previously, only SHA1 was supported, AEAD ciphers (AES-128-GCM, AES-256-GCM, CHACHA20-POLY1305) - previously only AES-256-CBC was supported.
NCP - Negotiation of cryptographic parameters
OpenVPN™ has a way to negotiate cryptographic parameters, instead of hardcoding them in the configuration. The client can propose its supported ciphers, and other features (MTU, directly request a push message for IP configuration, use TLS exporter secret instead of the hand-crafted (TLS 1.0 based PRF), ...) once the TLS handshake has been completed.
We are now supporting this negotiation protocol, and have been working on the different extensions that are useful to us. Namely, transmitting the supported ciphers, request push (which deletes an entire round-trip), TLS-exporter. This will also be part of the protocol specification that we're working on while finishing our implementation.
Cleanups and refactorings
We also took some time to cleanup our code base, removing Lwt.fail
(which doesn't produce proper backtraces), using lzo from the decompress package (since that code has been upstreamed a while ago), remove unneeded dependencies (rresult, astring), avoiding assert false
in pattern matches by improving types, improve the log output (include a timestamp, show log source, use colors).
Future
There is still some work that we want to do, namely a QubesOS client implementation, an operators manual, extending our specification, resurrecting and adapting the server implementation, supporting more NCP features (if appropriate), etc. So stay tuned, we'll also provide reproducible binaries once we're ready.
Don't hesitate to reach out to us on GitHub, by mail or me personally on Mastodon if you're stuck.