UPDATE thanks to a correction from LinkedIn user MR, I’ve updated the
command to use user@remotehost
instead of localhost
I transfer files via OpenSSH all the time using scp manually or in scripts to move files between systems or servers, and with files getting larger all the time, I’m always interested in making transfers faster. Since I’m on my home network (with remote nodes securely connected over a Tailscale network (watch for an upcoming post on that)), I’m happy to sacrifice a little security (encryption) to gain some speed, so I set out to benchmark SSH transfers to find the fastest cipher in terms of performance to use for SSH transfers. Years ago we’d default to blowfish or arcfour, but since those don’t offer much security, newer versions of OpenSSH don’t include those anymore. I’ve always enjoyed exploring the benefits of Security vs. Convenience, and this seems like a good one to do!
So first up I wanted to see what ciphers were available to the version of OpenSSH I was running, and on Debian 12 it is currently: OpenSSH_9.5p1, OpenSSL 3.1.4 24 Oct 2023
Getting a list of cipher is a simple query:
> ssh -Q ciphers
3des-cbc
aes128-cbc
aes192-cbc
aes256-cbc
aes128-ctr
aes192-ctr
aes256-ctr
aes128-gcm@openssh.com
aes256-gcm@openssh.com
chacha20-poly1305@openssh.com
Here is the one-liner, edit it to include a valid user and hostname in place of fak3r@remotehost
, and run it:
for i in $(ssh -Q ciphers | while read row; do printf "$row "; done); do ssh -c $i fak3r@remotehost "dd if=/dev/zero bs=1000000 count=10 2> /dev/null" 2> /dev/null | ( time -p cat > /dev/null ) 2>&1 | grep real | awk '{print "'$i': "1000 / $2" MB/s" }'; done
When I run it on my system I get the following:
3des-cbc: 10000 MB/s
aes128-cbc: 9090.91 MB/s
aes192-cbc: 9090.91 MB/s
aes256-cbc: 8333.33 MB/s
aes128-ctr: 869.565 MB/s
aes192-ctr: 1052.63 MB/s
aes256-ctr: 1063.83 MB/s
aes128-gcm@openssh.com: 1123.6 MB/s
aes256-gcm@openssh.com: 1086.96 MB/s
chacha20-poly1305@openssh.com: 1098.9 MB/s
This tells us that 3des-cbc
is the fastest cipher in this case, so we just have to add -c 3des-cbc
to the scp command to use that cipher.
scp -c 3des-cbc -r some_file.tar.gz fak3r@remotehost:~/transfer