DJB Salt Quicktun Nacl VPN
18.10.2017 20:52 in technical-notes
Our last post, on 23.06.2015 15:23 in technical-notes, we wrote:
Subsequent to the Court of Record letter to Google, "Heartbleed" and other vulnerabilities of OpenSSL were reported and fixed. In that letter, there is the following suggestion:
We also suggest that Dan J Bernstein’s work (of qmail fame, http://cr.yp.to) be adopted as the standard to measure up to: http://nacl.cr.yp.to/ and http://curvecp.org/ are a must.
Why?
Dan Bernstein: "An attacker who spends a billion dollars on special-purpose chips to attack Curve25519, using the best attacks available today, has about 1 chance in 1000000000000000000000000000 of breaking Curve25519 after a year of computation."
An interesting collection of things that use Curve25519 and things that use Ed25519 show that developers are paying attention.
After some research, we settled on Quicktun as a point to point VPN that is written with Tweet Nacl. The fact that it is pure source and no libraries is a plus.
Quicktun from OpenBSD to FreeBSD
We have an OpenBSD gateway which already runs an OpenVPN tunnel to our server. This link was under heavy attack by dedicated team of government level spooks who were boasting about AES weaknesses and about MIKEY.
We are talking about U.S. nuclear submaries, undersea cable splicing and ISP route changes as part of the attack vectors that were visible to us.
Obtain and compile Quicktun
cd /usr/local/src
git clone https://github.com/UCIS/QuickTun
cd QuickTun
./build.sh
cp -p out/quicktun* /usr/local/sbin
Our systems already have DJB's Daemontools running.
mkdir /var/svc.d/quicktun
Create a salty keypair
# quicktun.keypair
UCIS QuickTun 2.2.6 (c) 2010-2017 Ivo Smits <Ivo@UCIS.nl>
More information: http://wiki.ucis.nl/QuickTun
SECRET: 6f3fc114a9fbb2848d0f2ea405a938e78a3b1069b17d2608fa144d449e1de193
PUBLIC: f2dadc686fbd0098fdddd62e12693364d1fe1a5fe9288cf615c42773e164082b
#
Do not use the above keypair, it is just an example. The keys are the hexadecimal notation numbers next to SECRET and PUBLIC. The secret key is copied and pasted to a 'keypriv' keyfile locally and the public key is pasted to the field PUBLIC_KEY= in the daemontools run file of the opposite end of the tunnel.
Create the quicktun user on both sides:
pw groupadd quicktun
pw useradd quicktun -g quicktun -d /nonexistent -s /bin/false
The contents of the Daemontools run file is below. The POINTTOPOINT and LOCAL_ADDRESS are swapped for the other side.Replace the xxx.xxx.xxx.xxx ip address and the port number nnnn with your values. Any port above 1024 should be fine.
#!/bin/sh
ifconfig tunX destroy
ifconfig tunX create up
export TUN_MODE=1
export PROTOCOL=salty
export REMOTE_ADDRESS=xxx.xxx.xxx.xxx
export LOCAL_ADDRESS=0.0.0.0
export REMOTE_PORT=nnnn
export PRIVATE_KEY_FILE=./keypriv
export PUBLIC_KEY=<paste here the hex public key from the other end of the link>
export ADDRESS=192.168.101.2
export POINTTOPOINT=192.168.101.1
export SETUID=quicktun
export INTERFACE="/dev/tunX"
export TUN_UP_SCRIPT=./tunup.sh
exec /usr/local/sbin/quicktun.salty 2>&1
The quicktun.salty binary is used so that we can be sure that any of the lesser modes are not used. The folks who created Quicktun may as well not bother with the others.
salty | Secure with PFS | 20 bytes + control packets | Requires at least one endpoint to have a fixed address | The IP or ethernet packet is encrypted using the curve25519xsalsa20poly1305_box function, with temporary keys and nonces which are periodically regenerated and exchanged; this protocol provides Perfect Forward Secrecy and does not depend on clock synchronization for replay protection; the current implementation does not work well if both endpoints are floating |
---|
Since there are overhead bytes, the MTU and MSS of the interface must be changed:
# cat /service/quicktun/tunup.sh
#!/bin/sh
ifconfig tunX 192.168.101.2 192.168.101.1 mtu 1000 up
route add 0/1 192.168.101.1
route add 128/1 192.168.101.1
The tunup.sh on the remote must have the ifconfig point-to-point addresses reversed, i.e. swap .2 with .1.
# cat /service/quicktun1/tunup.sh
#!/bin/sh
ifconfig tunX 192.168.101.1 192.168.101.2 mtu 1000 up
There are no routes on the remote server.
In addition the packets must be scrubbed by the routers in /etc/pf.conf:
On OpenBSD clent router:
match all scrub (random-id max-mss 1000)
On FreeBSD server (interface specific):
scrub on tunX all random-id max-mss 1000 fragment reassemble
That's all folks!