SSH but faster

Keywords: #ops #maths

Il y a quelques jours je configurais mon serveur pour autoriser le X11 Forwarding, afin d’économiser le CPU de mon raspberry et d’avoir ma config firefox sur mon serveur, prête à l’emploi.

Si j’ai effectivement un gain significatif de CPU et RAM coté client, j’ai remarqué coté serveur que sshd est régulièrement à plus de 80% de CPU usage.

Je m’en viens à demander si je ne pourrais pas désactiver le chiffrement quand je forward X11 pour gagner un peu de performance.

Donc: Benchmarks !

Depuis la fameuse mise à jour de ssh en 2014, blowfish et arcfour notamment sont désactivés par défaut de ssh.(à raison hein, ils ont été prouvé vulnérable à différentes attaques dû aux blocks de 64bits, on y reviendra)

Le problème c’est que ces deux algorithmes sont rapide. Et c’est ce que je veux quand je forward X11.

Donc on va gaiment les réactiver.

On regarde les ciphers existant sur mon serveur:

$ ssh -Q cipher localhost | paste -d , -s -
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

et on y ajoute arcfour,blowfish-cbc dans /etc/ssh/sshd_config

$ echo 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,arcfour,blowfish-cbc >> /etc/ssh/sshd_config
$ sshd -t
/etc/ssh/sshd_config line 25: Bad SSH2 cipher spec '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,arcfour,blowfish-cbc'.

Bon. Ben non du coup.

Voyons le benchmark avec les ciphers existant:

cipher: 3des-cbc
209715200 bytes (210 MB, 200 MiB) copied, 37.4632 s, 5.6 MB/s
cipher: aes128-cbc
209715200 bytes (210 MB, 200 MiB) copied, 18.4185 s, 11.4 MB/s
cipher: aes192-cbc
209715200 bytes (210 MB, 200 MiB) copied, 23.4298 s, 9.0 MB/s
cipher: aes256-cbc
209715200 bytes (210 MB, 200 MiB) copied, 19.1144 s, 11.0 MB/s
cipher: aes128-ctr
209715200 bytes (210 MB, 200 MiB) copied, 18.3629 s, 11.4 MB/s
cipher: aes192-ctr
209715200 bytes (210 MB, 200 MiB) copied, 20.9736 s, 10.0 MB/s
cipher: aes256-ctr
209715200 bytes (210 MB, 200 MiB) copied, 21.0723 s, 10.0 MB/s
cipher: aes128-gcm@openssh.com
209715200 bytes (210 MB, 200 MiB) copied, 19.9906 s, 10.5 MB/s
cipher: aes256-gcm@openssh.com
209715200 bytes (210 MB, 200 MiB) copied, 20.8536 s, 10.1 MB/s
cipher: arcfour
Unknown cipher type 'arcfour'
cipher: arcfour128
Unknown cipher type 'arcfour128'
cipher: arcfour256
Unknown cipher type 'arcfour256'
cipher: blowfish-cbc
Unknown cipher type 'blowfish-cbc'
cipher: cast128-cbc
Unknown cipher type 'cast128-cbc'
cipher: chacha20-poly1305@openssh.com
209715200 bytes (210 MB, 200 MiB) copied, 18.1117 s, 11.6 MB/s

Ref ici

Juste par curiosité, voyons combien de temps pour un wget de 200MB:

pi@raspberrypi:~ $ wget https://hubert.dubois.com/tmp/200MB.bin .
--2022-11-08 11:52:52--  https://hubert.dubois.com/tmp/200MB.bin
HTTP request sent, awaiting response... 200 OK
Length: 209715200 (200M)
Saving to: ‘200MB.bin’
Total wall clock time: 27s
Downloaded: 1 files, 200M in 26s (7.58 MB/s)

TOUT ÇA POUR ÇA.

Vérifions la bande passante entre les deux machines:

pi@raspberrypi:~ $ iperf3 -c XXX.XX.XX.XXX -p 5201
Connecting to host XXX.XX.XX.XXX, port 5201
[  5] local 192.168.1.21 port 40676 connected to XXX.XX.XX.XXX port 5201
[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
[  5]   0.00-1.00   sec  12.9 MBytes   109 Mbits/sec    0    650 KBytes       
[  5]   1.00-2.00   sec  12.1 MBytes   101 Mbits/sec    0    687 KBytes       
[  5]   2.00-3.00   sec  11.9 MBytes  99.6 Mbits/sec    0    830 KBytes       
[  5]   3.00-4.00   sec  13.0 MBytes   109 Mbits/sec    0    830 KBytes       
[  5]   4.00-5.00   sec  11.3 MBytes  94.9 Mbits/sec    0    830 KBytes       
[  5]   5.00-6.00   sec  5.28 MBytes  44.3 Mbits/sec    0    830 KBytes       
[  5]   6.00-7.00   sec  3.60 MBytes  30.2 Mbits/sec    0    830 KBytes       
[  5]   7.00-8.00   sec  2.61 MBytes  21.9 Mbits/sec    0    830 KBytes       
[  5]   8.00-9.00   sec  7.21 MBytes  60.5 Mbits/sec    0    830 KBytes       
[  5]   9.00-10.00  sec  11.6 MBytes  97.0 Mbits/sec    0    830 KBytes       
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-10.00  sec  91.5 MBytes  76.7 Mbits/sec    0             sender
[  5]   0.00-10.03  sec  90.2 MBytes  75.4 Mbits/sec                  receiver

iperf Done.

et avec 3 threads sur le rpi:

pi@raspberrypi:~ $ iperf3 -c XXX.XX.XX.XXX -p 5201 -P 5
Connecting to host XXX.XX.XX.XXX, port 5201
[  5] local 192.168.1.21 port 40680 connected to XXX.XX.XX.XXX port 5201
[  7] local 192.168.1.21 port 40682 connected to XXX.XX.XX.XXX port 5201
[  9] local 192.168.1.21 port 40684 connected to XXX.XX.XX.XXX port 5201
[ 11] local 192.168.1.21 port 40686 connected to XXX.XX.XX.XXX port 5201
[ 13] local 192.168.1.21 port 40688 connected to XXX.XX.XX.XXX port 5201
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-10.00  sec  34.4 MBytes  28.8 Mbits/sec    0             sender
[  5]   0.00-10.05  sec  33.6 MBytes  28.1 Mbits/sec                  receiver
[  7]   0.00-10.00  sec  24.6 MBytes  20.7 Mbits/sec    0             sender
[  7]   0.00-10.05  sec  24.2 MBytes  20.2 Mbits/sec                  receiver
[  9]   0.00-10.00  sec  21.2 MBytes  17.7 Mbits/sec    0             sender
[  9]   0.00-10.05  sec  20.6 MBytes  17.2 Mbits/sec                  receiver
[ 11]   0.00-10.00  sec  19.6 MBytes  16.4 Mbits/sec    0             sender
[ 11]   0.00-10.05  sec  19.3 MBytes  16.1 Mbits/sec                  receiver
[ 13]   0.00-10.00  sec  24.3 MBytes  20.4 Mbits/sec    0             sender
[ 13]   0.00-10.05  sec  23.8 MBytes  19.9 Mbits/sec                  receiver
[SUM]   0.00-10.00  sec   124 MBytes   104 Mbits/sec    0             sender
[SUM]   0.00-10.05  sec   121 MBytes   101 Mbits/sec                  receiver

On a donc 75 Mbps = 9.375 MB/s et 100 Mbps = 12.5 MB/s.

Mon FairPhone3 donne 130 Mbps = 16.25 MB/s download et 115Mbit/s upload.

C’est donc bien uniquement le RPi le bottlneck réseau.

Actuellement le RPI boot sur une clef USB. Il s’agit d’un RPi3 donc sans d’usb3.

Testons la vitesse d’écriture pour voir:

pi@raspberrypi:~ $ dd if=/dev/zero of=/tmp/test1.img bs=1G count=1 oflag=dsync
Killed
pi@raspberrypi:~ $ dd if=/dev/zero of=/tmp/test1.img bs=500M count=1 oflag=dsync
1+0 records in
1+0 records out
524288000 bytes (524 MB, 500 MiB) copied, 204.716 s, 2.6 MB/s

Je perds l’accès à la souris pendant le dd hahahaha. Au revoir real time.

VS serveur:

$ dd if=/dev/zero of=/tmp/test1.img bs=500M count=1 oflag=dsync
1+0 records in
1+0 records out
524288000 bytes (524 MB, 500 MiB) copied, 2.53805 s, 207 MB/s

Aaaaaah oui, y’a peut-être un truc là.

Tous les tests X11, ssh et réseaux sont caduques tant que les perfs i/o locales ne seront pas correctes.

Effectivement le RPi est en PLS:

RPi htop

et même le tool de diag officiel fail:

RPi diag