Whenever I’ve got a lot of data to transfer I usually kick off the
scp with the default
SSH settings and then, after an hour or so, wonder if I could have sped things up with a different cipher.
So I decided to find out now for my future self and maybe save some time.
A quick not about SSH Ciphers
SSH uses several ciphers and algorithms. I have encountered lots of sysadmins that think their choice of SSH key determines their transfer speed. SSH keys are only used by SSH to transmit the shared key that is used for the symmetric cipher which encrypts all of the session data. The admins SSH key does not affect the transfer speed only the choide symmetric cipher does.
The cipher can be manually set when starting an SSH session using the
-c <CIPHER> option.
The list of ciphers that your versions of SSH supports is printed with
ssh -A ciphers. On my two Ubuntu 20.04 test servers this is:
# ssh -Q ciphers 3des-cbc aes128-cbc aes192-cbc aes256-cbc email@example.com aes128-ctr aes192-ctr aes256-ctr firstname.lastname@example.org email@example.com firstname.lastname@example.org
So these are the ones I’m going to test.
First, all of these ciphers need enabling on both sides. I did this by editing
/etc/ssh/sshd_config and adding the following line:
Next, I generated a 500MB file of random data:
dd if=/dev/urandom of=rand.file bs=1MB count=500
Then, I spun up a couple of DigitalOcean droplets with a VLAN between them which I used for these tests.
First, I tested the how fast the disk was:
dd if=rand.file of=/dev/null
Then how fast an unencrypted transfer between the servers. I used netcat for that as follows:
Sender: dd if=rand.file | nc <IP> 8080 Receiver nc 8080 -l >/dev/null
And finally, using SSH with the following command:
dd if=rand.file | ssh -o 'Compression no' -c <CIPHER> <USER>@<IP> dd of=/dev/null
These are the numbers I got:
|Raw disk read||183 MB/s|
The CPU was at or around 100% during all of these transfers so it was all down the the efficiency of the ciphers.
The winner is
aes128-cbc. So if you are looking to speed up a transfer choose that one. Here are the commands for
rsync -e `ssh -c aes128-cbc` rand.file email@example.com:/home/user/rand.file
scp -c aes128-cbc rand.file firstname.lastname@example.org:/home/user/rand.file