Speeding up Secure Shell client (SSH) on Ubuntu

When running graphical processes on another Linux host, it is common to use the X11 protocol to display back to the desktop of your local client. (Although there are other ways, which may be better depending on circumstances.) However, you may be achieving a connection speed much slower than your equipment and network can actually support.

An example would be to run firefox:

ssh -X anotherhost
firefox
<play a YouTube video>

But the ssh session (usually OpenSSL on Ubuntu 18.04) which forms the encrypted connection for the graphical X11 traffic, does not necessarily utilise any hardware encryption features of the CPU on the remote host or your local client (to find out if a Linux client can utilise hardware encryption, see cyberciti.biz).

The ssh -Q cipher command will show supported ciphers on a machine, although they may not use hardware encryption. cat /proc/cpuinfo – the presence of aes in the flags or features section, indicates hardware encryption support.

Using ssh -vv anotherhost pwd 2>&1 | grep cipher to establish a temporary connection, shows which cipher is actually chosen:

debug2: ciphers ctos: chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com
debug2: ciphers stoc: chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com
debug2: ciphers ctos: chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com
debug2: ciphers stoc: chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com
debug1: kex: server->client cipher: chacha20-poly1305@openssh.com MAC: <implicit> compression: none
debug1: kex: client->server cipher: chacha20-poly1305@openssh.com MAC: <implicit> compression: none  

This returns the ciphers supported (in order of preference) by the local client first, then ciphers supported by the remote server, then the chosen cipher (in this example  chacha20-poly1305@openssh.com).

chacha20-poly1305 is an efficient and secure cipher, so has become widely used. However it is not as fast as the AES-GCM cipher when implemented as hardware instructions in higher end CPUs (e.g. Intel I5 and I7 since 2010).

An example test using ssh-cipher-benchmark.sh on an Intel I5-6600 @3.3GHz, running Ubuntu 18.04.3 LTS:

ssh -c chacha20-poly1305@openssh.com localhost (cipher implemented in software)
299.401 MB/s

ssh -c aes256-gcm@openssh.com localhost (cipher implemented in hardware)
1020.41 MB/s

A tripling of throughput, and with less CPU load.

Where you are inside a firewall, so not necessarily bothered about encryption for internal X display traffic, this is a bit of a no-brainer.

The default order of preference when choosing a cipher can be defined in the client’s /etc/ssh/ssh_config file, such as:
Ciphers aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,3des-cbc

By default the Ciphers line is usually commented out, so you should uncomment it, and add aes256-gcm@openssh.com at the beginning.

The Arm CPUs in the Raspberry Pi (all models, including the Pi 4B) do not have hardware AES encryption, so chacha20-poly1305@openssh.com is usually the fastest option.

Here we have used hardware encryption of ssh to speed up X display traffic, but benefit will also be seen in other tools which also utilise ssh, such as  SFTP, rsync…