Alla inlägg av Christer

Effektiv SSH med rätt algoritm

Jag skulle överföra stora mängder lokalt lagrade data till en ny Synology DS415+ NAS. För detta använde jag rsync över ssh. Initialt kom jag upp i ca 70-80 MB/s. På NASen låg CPU-lasten på ca 70%, framförallt SSH. Det fick mig att fundera på om krypteringsalgoritmen har betydelse.

I korthet så fungerar aes128-gcm@openssh.com bäst för mina överföringar till en Synology DS415+.

Både datorn och NAS:en har en CPU som stöder hårdvaruaccelerering (AES-NI).

nas> grep aes /proc/cpuinfo
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr pdcm sse4_1 sse4_2 movbe popcnt tsc_deadline_timer aes rdrand lahf_lm 3dnowprefetch arat epb dtherm tpr_shadow vnmi flexpriority ept vpid tsc_adjust smep erms

Genom att köra

ssh -v nas

kunde jag se att aes128-ctr används:

debug1: kex: server->client aes128-ctr hmac-sha1-etm@openssh.com none

Läge att jämföra den råa prestandan för de olika algoritmerna:

openssl speed -elapsed -evp aes-128-ctr
openssl speed -elapsed -evp aes-128-gcm

NAS

type 16 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes
aes-128-ctr 150684.16k 334513.56k 486158.76k 553676.46k 581135.02k
aes-128-gcm 108917.29k 219577.81k 291686.91k 319687.00k 328081.41k

Lokalt

type 16 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes
aes-128-ctr 590559.55k 1648565.89k 2948549.21k 3609877.85k 3992999.25k
aes-128-gcm 367441.70k 927592.85k 1221258.41k 1328180.22k 1336317.27k

(The ’numbers’ are in 1000s of bytes per second processed.)

Provade även att slå av AES-NI och kan då se betydligt sämre prestanda:

OPENSSL_ia32cap=”~0x200000200000000″ openssl speed -elapsed -evp aes-128-ctr
type 16 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes
aes-128-ctr 134160.20k 145078.31k 551143.34k 608067.93k 637536.94k

Teoretiskt borde CTR vara snabbare än GCM. Men teori och praktik är olika saker.

Överföring med aes128-ctr

$ dd if=/dev/zero bs=1M count=20000 conv=sync | ssh -c aes128-ctr -o Compression=no nas ”cat – >/dev/null”;
20000+0 records in
20000+0 records out
20971520000 bytes (21 GB) copied, 238,251 s, 88,0 MB/s

Top på NAS:en

PID PPID USER STAT VSZ %MEM %CPU COMMAND
27797 27778 root R 56960 2.7 70.2 sshd: dsadmin@notty

Överföring med aes128-gcm@openssh.com

$ dd if=/dev/zero bs=1M count=20000 conv=sync | ssh -c aes128-gcm@openssh.com -o Compression=no nas ”cat – >/dev/null”;
20000+0 records in
20000+0 records out
20971520000 bytes (21 GB) copied, 185,63 s, 113 MB/s

Top på NAS:en

PID PPID USER STAT VSZ %MEM %CPU COMMAND
29162 29143 root S 23272 1.1 19.0 sshd: dsadmin@notty

Prestanda som motsvarar den förväntade med tanke på gränsen för Gigabit-ethernet. CPU-belastningen är betydligt bättre.

När jag kör SSH-testet ovan mot localhost på den stationära så får jag prestanda som överträffar Gigabit-ethernet. I detta fall görs både kryptering och dekryptering på samma maskin, vilket naturligtvis drar ner resultatet.

c@localhost:~$ dd if=/dev/zero bs=1M count=20000 conv=sync | time ssh -c aes128-ctr c@localhost -o Compression=no ”cat – >/dev/null”;
Enter passphrase for key ’/home/christer/.ssh/id_rsa’:
Enter passphrase for key ’/home/christer/.ssh/id_rsa’:
20000+0 records in
20000+0 records out
20971520000 bytes (21 GB) copied, 65,9113 s, 318 MB/s
38.74 user
14.99 system
1:05.91 elapsed
81% CPU (0avgtext+0avgdata 3268maxresident)k
0inputs+0outputs (0major+953minor)pagefaults 0swaps

c@localhost:~$ dd if=/dev/zero bs=1M count=20000 conv=sync | time ssh -c aes128-gcm@openssh.com c@localhost -o Compression=no ”cat – >/dev/null”;
20000+0 records in
20000+0 records out
20971520000 bytes (21 GB) copied, 42,0884 s, 498 MB/s
22.02 user
14.77 system
0:42.08 elapsed
87% CPU (0avgtext+0avgdata 3276maxresident)k
0inputs+0outputs (0major+957minor)pagefaults 0swaps

Det är intressant att det är framförallt ”user”-tiden som skiljer sig.

Kör motsvarande på NAS:en.

nas> dd if=/dev/zero bs=1M count=20000 conv=sync | time ssh -c aes128-ctr -p 2222 admin@localhost -o Compression=no ”cat – >/dev/null”;
20000+0 records in
20000+0 records out
real 5m 13.44s
user 8m 37.22s
sys 0m 41.28s

Motsvarar: 64 MB/s

nas> dd if=/dev/zero bs=1M count=20000 conv=sync | time ssh -c aes128-gcm@openssh.com -p 2222 admin@localhost -o Compression=no ”cat – >/dev/null”;
20000+0 records in
20000+0 records out
real 2m 11.41s
user 1m 21.78s
sys 0m 37.58s

Motsvarar: 152 MB/s

Jag inspirerades av följande sida, som hjälpte mig på rätt väg:
Openssh 6.7 disables a number of ciphers

Edit: Det verkar stämma:
OpenSSH ciphers performance benchmark (update 2015)

Svenska tecken i filnamn och git

Jag har irriterat mig på att statusen från git ersätter sökvägar med ”escapes”. T.ex. för en fil ”Försäkringar/Hälsa/x.pdf”.

On branch master
Your branch is ahead of 'origin/master' by 4 commits.
(use "git push" to publish your local commits)

Changes not staged for commit:
(use "git add/rm ..." to update what will be committed)
(use "git checkout -- ..." to discard changes in working directory)

deleted: "F\303\266rs\303\244kringar/H\303\244lsa/x.pdf"

Detta löses genom konfigurationen core.quotepath

git config [--global] core.quotepath off

Utnyttja ext2, ext3 och ext4 till max

Jag skulle säkerhetskopiera en diskavbild till en extern hårddisk. Jag skapade en partition som var tillräckligt stor för att rymma min diskavbild. Efter att ha kopierat filen fick jag följande resultat av ’df’:

Filesystem     1K-blocks      Used Available Use% Mounted on
/dev/sdc3      231824408 228332108         0 100% /media/disk_backup

Notera att den är 100% full, fast Used < 1K-blocks. Tydligen reserveras 5% som default för priviligerade processer i ext2, ext3, ext4. Detta för att t.ex. sysylogd, ska fortsätta fungera även efter en användare fyllt disken, men även för att minska fragmentering. Om man har en ren lagringsdisk är det ganska onödigt med så mycket reserverat. På en 100 GB disk, reserveras då 5 GB som standard.

Detta går att ändra med tune2fs:

$ sudo tune2fs -m 1 /dev/sdc3
tune2fs 1.42 (29-Nov-2011)
Setting reserved blocks percentage to 1% (588800 blocks)
$ df /dev/sdc3
Filesystem     1K-blocks      Used Available Use% Mounted on
/dev/sdc3      231824408 228332108   1137100 100% /media/disk_backup

Transformera web.config/app.config beroende på målmiljö

När man utvecklar applikationer är det naturligt att ha olika målmiljöer som utveckling, test och produktion. Att modifiera manuellt i konfigurationsfiler är alltid en dålig idé.

Utvecklar man web-projekt i Visual Studio finns automatiskt stöd:
http://msdn.microsoft.com/en-us/library/dd465326(VS.100).aspx

Har man en normal applikation med en app.config kan åstadkomma samma sak genom att följande guide:
http://mitasoft.wordpress.com/2011/09/28/multipleappconfig/

Makro i Excel-ark som är skyddat av lösenord

Har man ett Excel-ark som har makron och är skyddat av ett (okänt) lösenord så går det inte att aktivera makron om man inte har ett Anti-virus-program som integreras med Microsofts API (AVG har det inte). Detta för att skydda från att okända makron körs i och med att de är krypterade.

Det går i Excel 2007 att gå runt detta genom att i regedit lägga till ett DWORD ”ExcelBypassEncryptedMacroScan” med värde 1 i:
HKEY_CURRENT_USER\Software\Microsoft\Office\12.0\Excel\Security

NUnit i Visual Studio

Att köra NUnit i Visual Studio sparar mycket tid. Det första man behöver är tillägget NUnitForVS

För att tillägget ska känna igen projektet som ett NUnit-projekt måste man redigera csproj-filen. Gör man det från Visual Studio måste man först göra ”Unload Project”. Därefter kan man redigera XML-en. Man måste där lägga till en GUID för projekttypen enligt följande:

<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>

Ladda projektet på nytt. När det väl är klart ska testen dyka upp under ”Test View”. Eventuellt behöver du trycka på ”Refresh”.

Ett tag hade jag problem med att min projekt inte laddades.  I ”Output” visades ”’xyz.dll’ is not NUnit Test”.

Genom att kompilera om källkoden till NUnitForVS kunde jag förstå att något var fel med mina ”settings”.  Det visade sig att filen %APPDATA%\NUnit\NUnitSettings.xml var tom. Genom att radera den och starta om så lyckades laddningen av NUnit-projektet.