TinySSH vs others

Comparison of Dropbear, OpenSSH and TinySSH
2016-01-26 sysadmin

This post follows Installing TinySSH.

Disclaimer: I’m in not a crypto expert! Don’t take anything below for granted.

Security features

The clear winner here is OpenSSH due to its maturity and privilege separation feature. Microsoft recently committed to support OpenSSH, albeit still in a fork.

Setup

Caveats

Preferred cipher stream protocol

Measurements

Cipher stream protocol preference was detected using:

ssh -vvv $HOST "exit 0" |& grep "debug1: kex: server->client"

Results

ServerHost.ssh/configCipher chosen
dropbearARMDefaultaes128-ctr with hmac-md5
dropbearARMStrictFailure to connect
dropbearx64Defaultaes128-ctr with hmac-md5
dropbearx64StrictFailure to connect
opensshARMDefaultaes128-ctr with hmac-sha1-etm
opensshARMStrictchacha20-poly1305@openssh.com
opensshx64Defaultaes128-ctr with hmac-md5-etm
opensshx64Strictchacha20-poly1305@openssh.com
tinysshARMDefaultchacha20-poly1305@openssh.com
tinysshARMStrictchacha20-poly1305@openssh.com
tinysshx64Defaultchacha20-poly1305@openssh.com
tinysshx64Defaultchacha20-poly1305@openssh.com

Connection latency

Connection latency is important for use case like a git server where repeated but short lived connections are frequently done. In practice, we’d aim for sub 200ms on a local network with high performance machines to reduce the perceptible overhead.

Measurements

Measurements are done by taking the median value of 5 repetitions via:

(for i in {0..4}; do time ssh $HOST "exit 0"; done) |& grep real | sort -n

Results

ServerHost.ssh/configAlgoLatency
dropbearARMDefaultRSA287ms
dropbearx64DefaultRSA95ms
opensshARMDefaultRSA206ms
opensshARMDefaultEd25519241ms
opensshARMStrictRSA218ms
opensshARMStrictEd25519252ms
opensshx64DefaultRSA310ms
opensshx64DefaultEd25519304ms
opensshx64StrictRSA309ms
opensshx64StrictEd25519334ms
tinysshARMDefaultEd25519192ms
tinysshARMStrictEd25519197ms
tinysshx64DefaultEd25519103ms
tinysshx64StrictEd25519132ms

The results clearly warrants a follow up with further diagnostics.

I/O Performance

Measurements

The test reads from /dev/zero and sends it over stdout. Since the stream is not compressed and network not encumbered, this measures the cipher stream performance with minimal CPU overhead and no disk I/O.

Measurements are done by taking the median value of 5 repetitions via:

(for i in {0..4}; do time ssh $HOST "dd if=/dev/zero count=1024 bs=1048576" > /dev/null; done) |& grep real | sort -n

Results

The Raspberry Pi2 has a 100mbit ethernet port connected over USB, so it’s bound to be significantly slower.

ServerHost.ssh/configAlgoTime to send 1GbSpeed
dropbearARMDefaultRSA155942ms6.6MiB/s
dropbearx64DefaultRSA10240ms100.0MiB/s
opensshARMDefaultRSA120216ms8.5MiB/s
opensshARMDefaultEd25519114913ms8.9MiB/s
opensshARMStrictEd25519114913ms8.9MiB/s
opensshx64DefaultRSA9464ms108.2MiB/s
opensshx64DefaultEd255199450ms108.4MiB/s
opensshx64StrictEd255199568ms107.0MiB/s
tinysshARMDefaultEd25519124963ms8.2MiB/s
tinysshx64DefaultEd255199319ms109.9MiB/s
tinysshx64StrictEd255199515ms107.6MiB/s

Memory use

Measurement

This is in no way scientific, I ssh’ed in and look at the ps output of the server process for the connection.

Results

The memory values are for up to 3 processes involved: daemon / priv separation / connection

The values varies a lot from one host to another (e.g. between two Ubuntu 14.04 x64 hosts) so take these with a large grain of salt.

ServerHost.ssh/configAlgoVirtual Memory SizeResident Set Size*
dropbearARMDefaultRSA2456 / N/A / 29081648 / N/A / 1860
opensshARMDefaultEd255197808 / 11072 / 110724388 / 4932 / 3104
opensshARMDefaultRSA7808 / 11072 / 110724388 / 4956 / 3048
tinysshARMDefaultEd25519N/A / N/A / 3176N/A / N/A / 2292
dropbearx64DefaultRSA11032 / N/A / 194641300 / N/A / 2268
opensshx64DefaultEd2551961376 / 109796 / 1097961304 / 6588 / 3904
opensshx64DefaultRSA61376 / 109796 / 1097961304 / 6556 / 4108
tinyssh**x64DefaultEd255194244 / N/A / 157201136 / N/A / 2792

5Mb on a <=1Gb machine is a welcome saving, yet OpenSSH’s privilege separation security benefit is undeniable.

Conclusion

It’s definitely too early to use TinySSH in production, wouldn’t it be because because privilege separation is not implemented and as far as I know nobody did an external review of the code. For security products, “it works” is not enough. I can see a niche on embedded devices, it could be a good choice performance wise especially for Linux based system using systemd, the gain in memory use is real and I/O performance significant. It could probably be a good case for specific use like boot time remote LUKS decryption for desktop use.

In particular, Dropbear doesn’t seem to use sound default values so replacing uses of Dropbear by TinySSH should be considered in the coming years. TinySSH is significantly faster than Dropbear in connection latency on ARM and in throughput on all platforms.

As I noted in my previous post, I’m concerned by TinySSH coding style (lacks of brackets around conditions: a recipe for another goto fail) but I like the philosophy and the fact that less secure algorithms (like md5) are simply not implemented. The coding style could probably be fixed if desired by the author.

There’s definitely caveats in moving from RSA keys to Ed25519. OSX 10.11 supports Ed25519 just fine yet Gnome keyring still doesn’t support Ed25519 key, one has to use OpenSSH’s agent. An Ed25519 key will also not be usable on older servers, requiring users to have 2 keys, one RSA, one Ed25519. But at the same time, if you connect to an old server not supporting Ed25519, you should question its security!

Updates:

2016-01-29: Added note about OSX 10.11 client default settings which fail with tinyssh.