[Ninux-Calabria] OpenVPN su OpenWRT: howto, test, prestazioni, integrazione, etc.
Stefano De Carlo
stefanauss a gmail.com
Dom 20 Lug 2014 18:55:44 UTC
TL; DR: OpenVPN non ce la fa a criptare tunnel && mantenere throughput
su questi routerini. Le ragioni di tutto questo non sono ovvie. Tuttavia
si conferma la migliore alternativa.
====
Ciao a tutti,
Dopo aver manovrato con GRE [1] e L2TP [2], mi sono dedicato un po' ad
una configurazione di tunneling in OpenWRT fatta con il molto più
popolare OpenVPN.
Ai nuovi arrivati in ML spiego brevemente la premessa: stiamo cercando
il miglior meccanismo di tunneling possibile tra una serie di
alternative, con l'obbiettivo di integrarlo e supportarlo nel firmware
Ninux cosentino/calabrese (NinucsWrt) [3]. Questo meccanismo consentirà
ai Ninuxers di "scegliersi" il proprio gateway tra i vari nodi della
rete, e la principale utilità pratica di questa cosa è che significa
poter condividere la propria connessione *ad Internet* solo con chi si
desidera, e per il resto essere connessi tutti-con-tutti dentro Ninux.
Non è semplice perché ci sono molte variabili da considerare: stabilità,
facilità di configurazione, manutenibilità, prestazioni, spazio
occupato, etc.
Non ho ancora un tutorial passo-passo client-server come per GRE e L2TP:
mi sono dedicato principalmente a prendere io stesso confidenza con
OpenVPN, ma soprattutto a rispondere all'elefante nella stanza: il più
grande vantaggio di OpenVPN sulle altre alternative è la sicurezza, ma
OpenVPN cryptato su questi router domestici ha abbastanza prestazioni
per gestire la condivisione della tipica banda ADSL?
Nei test che ho fatto la risposta è stata: quasi sicuramente no.
PeppeLinux si era portato avanti col lavoro nelle scorse settimane e
aveva riportato che in un caso operativo l'utilizzo di OpenVPN su una
connessione a 900 KB/s gli aveva consentito solo di sfruttarne 350 KB/s
quando usato in modalità cifrata (openvpn-openssl). Aveva dunque
ripiegato sulla versione in plain-text (openvpn-nossl) ed era tornato al
100% di banda.
A me è suonato strano e ho voluto fare dei test più approfonditi.
SERVER: TL-WR1043NDv1 @ Capizzanux, AA 12.09 stock + openvpn-openssl
CLIENT: TL-WR1043NDv1 @ HPCC, NinucsWrt AA 14.07 beta +
openvpn-{openssl,polarssl,nossl}.
LINK: NanoStation di test in HPCC, -79/-80, CCQ 98%, Airmax C/Q 35/17
SETTINGS OPENVPN: compressione attiva, protocollo TCP, device tun
Innanzitutto, c'era da stabilire la baseline delle prestazioni del
router. Per far questo c'è l'apposito benchmark incluso nel pacchetto
openssl-utils
# openssl speed
OpenSSL 1.0.1g 7 Apr 2014
built on: Tue Apr 8 17:43:03 UTC 2014
options:bn(64,32) rc4(ptr,char) des(idx,cisc,2,long) aes(partial)
blowfish(ptr)
compiler: ccache_cc -fPIC -DOPENSSL_PIC -DZLIB_SHARED -DZLIB
-DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H
-I/build/ar71xx/generic/staging_dir/target-mips_r2_uClibc-0.9.33.2/usr/include
-I/build/ar71xx/generic/staging_dir/target-mips_r2_uClibc-0.9.33.2/include
-I/build/ar71xx/generic/staging_dir/toolchain-mips_r2_gcc-4.6-linaro_uClibc-0.9.33.2/usr/include
-I/build/ar71xx/generic/staging_dir/toolchain-mips_r2_gcc-4.6-linaro_uClibc-0.9.33.2/include
-DOPENSSL_SMALL_FOOTPRINT -DHAVE_CRYPTODEV -DOPENSSL_NO_ERR -DTERMIO -Os
-pipe -mips32r2 -mtune=mips32r2 -fno-caller-saves -fhonour-copts
-Wno-error=unused-but-set-variable -msoft-float -fpic
-fomit-frame-pointer -Wall -DSHA1_ASM -DSHA256_ASM -DAES_ASM
The 'numbers' are in 1000s of bytes per second processed.
type 16 bytes 64 bytes 256 bytes 1024 bytes 8192
bytes
md2 0.00 0.00 0.00 0.00
0.00
mdc2 0.00 0.00 0.00 0.00
0.00
md4 1337.23k 4809.70k 15041.46k 32107.76k
46368.45k
md5 1064.83k 3757.20k 10761.25k 21661.97k
29593.60k
hmac(md5) 1732.11k 5608.89k 14695.18k 24586.76k
30465.91k
sha1 1055.08k 3430.31k 8514.10k 13732.27k
17264.42k
rmd160 0.00 0.00 0.00 0.00
0.00
rc4 18328.98k 19548.02k 20286.68k 20678.97k
20756.95k
des cbc 2795.99k 2870.77k 2982.02k 2868.67k
2924.46k
des ede3 1023.99k 1033.51k 1050.51k 1037.87k
1051.16k
idea cbc 0.00 0.00 0.00 0.00
0.00
seed cbc 3640.35k 3790.84k 3840.18k 3971.45k
3870.01k
rc2 cbc 3358.52k 3558.51k 3491.34k 3468.89k
3536.55k
rc5-32/12 cbc 0.00 0.00 0.00 0.00
0.00
blowfish cbc 5773.93k 6349.70k 6478.39k 6630.76k
6508.25k
cast cbc 5856.78k 6375.54k 6488.18k 6562.22k
6550.73k
aes-128 cbc 4606.32k 5032.80k 5069.35k 5077.92k
5134.22k
aes-192 cbc 4040.48k 4341.22k 4553.13k 4437.22k
4526.08k
aes-256 cbc 3606.39k 3812.04k 3942.31k 3882.37k
3932.72k
camellia-128 cbc 0.00 0.00 0.00
0.00 0.00
camellia-192 cbc 0.00 0.00 0.00
0.00 0.00
camellia-256 cbc 0.00 0.00 0.00
0.00 0.00
sha256 1165.47k 2794.21k 5133.20k 6440.37k
6968.77k
sha512 349.74k 1382.64k 2070.35k 2824.91k
3245.29k
whirlpool 255.43k 501.51k 803.70k 939.13k
1013.30k
aes-128 ige 4608.48k 5287.40k 5537.48k 5580.26k
5542.97k
aes-192 ige 4018.42k 4547.74k 4701.36k 4762.67k
4784.36k
aes-256 ige 3626.96k 3937.06k 4008.14k 4188.34k
4173.88k
ghash 5440.17k 5565.77k 5676.30k 5745.31k
5840.38k
sign verify sign/s verify/s
rsa 512 bits 0.006894s 0.000578s 145.1 1729.7
rsa 1024 bits 0.034429s 0.001729s 29.0 578.5
rsa 2048 bits 0.210870s 0.006085s 4.7 164.3
rsa 4096 bits 1.461429s 0.022796s 0.7 43.9
sign verify sign/s verify/s
dsa 512 bits 0.005801s 0.006825s 172.4 146.5
dsa 1024 bits 0.016839s 0.020652s 59.4 48.4
dsa 2048 bits 0.060375s 0.074000s 16.6 13.5
di particolare interesse per noi è la riga relativa a "blowfish cbc",
che è l'algo di criptazione di default di OpenVPN, nonché il più
performante del set supportato [4], che mostra come il router è capace
di criptare a ritmi di 6500 KB/s in un test puramente di CPU. Si tratta
di 50 Mbit/s, quindi come algoritmo grezzo ci siamo.
Passo successivo, stabilire il throughput nudo del link: ~14.5 Mbps
stefanauss a barney:~$ iperf -c 10.87.7.1 -i 5 -t 250
------------------------------------------------------------
Client connecting to 10.87.7.1, TCP port 5001
TCP window size: 85.0 KByte (default)
------------------------------------------------------------
[ 3] local 10.87.80.127 port 50872 connected with 10.87.7.1 port 5001
[ ID] Interval Transfer Bandwidth
[ 3] 0.0- 5.0 sec 8.62 MBytes 14.5 Mbits/sec
[ 3] 5.0-10.0 sec 8.12 MBytes 13.6 Mbits/sec
[ 3] 10.0-15.0 sec 8.50 MBytes 14.3 Mbits/sec
[ 3] 15.0-20.0 sec 8.75 MBytes 14.7 Mbits/sec
[ 3] 20.0-25.0 sec 8.50 MBytes 14.3 Mbits/sec
[ 3] 25.0-30.0 sec 8.50 MBytes 14.3 Mbits/sec
[ 3] 30.0-35.0 sec 8.50 MBytes 14.3 Mbits/sec
[ 3] 35.0-40.0 sec 8.62 MBytes 14.5 Mbits/sec
Fatto questo, si passa a fare lo stesso percorso ma criptando il
traffico attraverso la VPN criptata+compressa: si nota che a causa del
link così-così l'effetto della compressione impiega un po' ad azionarsi
ma quando lo fa il buffering fa la differenza: ~22 Mbps!
stefanauss a barney:~$ iperf -c 100.67.0.1 -i 5 -t 250
------------------------------------------------------------
Client connecting to 100.67.0.1, TCP port 5001
TCP window size: 45.0 KByte (default)
------------------------------------------------------------
[ 3] local 10.87.80.127 port 42508 connected with 100.67.0.1 port 5001
[ ID] Interval Transfer Bandwidth
[ 3] 0.0- 5.0 sec 6.00 MBytes 10.1 Mbits/sec
[ 3] 5.0-10.0 sec 6.50 MBytes 10.9 Mbits/sec
[ 3] 10.0-15.0 sec 6.50 MBytes 10.9 Mbits/sec
[ 3] 15.0-20.0 sec 6.50 MBytes 10.9 Mbits/sec
[ 3] 20.0-25.0 sec 6.25 MBytes 10.5 Mbits/sec
[ 3] 25.0-30.0 sec 6.50 MBytes 10.9 Mbits/sec
[ 3] 30.0-35.0 sec 9.12 MBytes 15.3 Mbits/sec
[ 3] 35.0-40.0 sec 13.0 MBytes 21.8 Mbits/sec
[ 3] 40.0-45.0 sec 12.5 MBytes 21.0 Mbits/sec
[ 3] 45.0-50.0 sec 12.9 MBytes 21.6 Mbits/sec
[ 3] 50.0-55.0 sec 13.0 MBytes 21.8 Mbits/sec
In tutto questo "top" segnala CPU intorno al 50%. Tutto consistente col
benchmark iniziale! [5]
Il degrado comincia a sorgere proprio quando si passa ad utilizzare
l'endpoint VPN come default gateway.
Ecco uno speedtest direttamente da Capizzanux: ~1375 KB/s
root a CapizzanuxGRND:~# time wget --output-document=/dev/null
http://188.165.12.10
6/files/100Mio.dat
Connecting to 188.165.12.106 (188.165.12.106:80)
null 100% |********************************| 100M
0:00:00 ETA
real 1m 14.46s
user 0m 0.96s
sys 0m 3.03s
Ed ecco l'identico speedtest attraverso la VPN: 982 KB/s, ovvero il 72%
della capacità.
stefanauss a barney:~$ time wget --output-document=/dev/null
http://188.165.12.106/files/100Mio.dat
--2014-07-18 19:10:00-- http://188.165.12.106/files/100Mio.dat
Connessione a 188.165.12.106:80... connesso.
Richiesta HTTP inviata, in attesa di risposta... 200 OK
Lunghezza: 104857600 (100M) [application/octet-stream]
Salvataggio in: "/dev/null"
100%[=======================================>] 104.857.600 1,13MB/s in
1m 44s
2014-07-18 19:11:44 (982 KB/s) - "/dev/null" salvato [104857600/104857600]
real 1m44.430s
user 0m1.236s
sys 0m3.395s
Non raccapricciante come il 39% stimato dal caso di Peppe, ma comunque
probabilmente un deal-breaker quando si tratta di condividere l'ADSL.
Come prevedibile, senza la criptazione le cose evolvono nella direzione
giusta. Ho testato sia con openvpn-nossl, sia semplicemente aggiungendo
l'opzione cipher none in /etc/config/openvpn.
Chiaramente le baseline da Capizzanux (Ninux & ADSL throughput)
rimangono quelle riportate sopra.
Ecco il test di throughput attraverso VPN non criptata stavolta: saliamo
a 28 Mbps!
stefanauss a barney:~$ iperf -c 100.67.0.1 -i 5 -t
250------------------------------------------------------------
Client connecting to 100.67.0.1, TCP port 5001
TCP window size: 45.0 KByte (default)
------------------------------------------------------------
[ 3] local 10.87.80.127 port 42629 connected with 100.67.0.1 port 5001
[ ID] Interval Transfer Bandwidth
[ 3] 0.0- 5.0 sec 7.62 MBytes 12.8 Mbits/sec
[ 3] 5.0-10.0 sec 7.62 MBytes 12.8 Mbits/sec
[ 3] 10.0-15.0 sec 7.38 MBytes 12.4 Mbits/sec
[ 3] 15.0-20.0 sec 7.88 MBytes 13.2 Mbits/sec
[ 3] 20.0-25.0 sec 7.75 MBytes 13.0 Mbits/sec
[ 3] 25.0-30.0 sec 7.75 MBytes 13.0 Mbits/sec
[ 3] 30.0-35.0 sec 7.62 MBytes 12.8 Mbits/sec
[ 3] 35.0-40.0 sec 7.50 MBytes 12.6 Mbits/sec
[ 3] 40.0-45.0 sec 10.4 MBytes 17.4 Mbits/sec
[ 3] 45.0-50.0 sec 17.0 MBytes 28.5 Mbits/sec
[ 3] 50.0-55.0 sec 16.6 MBytes 27.9 Mbits/sec
[ 3] 55.0-60.0 sec 16.6 MBytes 27.9 Mbits/sec
[ 3] 60.0-65.0 sec 16.9 MBytes 28.3 Mbits/sec
[ 3] 65.0-70.0 sec 16.6 MBytes 27.9 Mbits/sec
[ 3] 70.0-75.0 sec 16.8 MBytes 28.1 Mbits/sec
[ 3] 75.0-80.0 sec 16.6 MBytes 27.9 Mbits/sec
E lo speedtest come default gateway stavolta svela risultati che vanno
precisati: si tratta di solo 100 KB/s in più, ma la cosa è da imputare
al jitter piuttosto alto del link wireless utilizzato (mi era
impossibile fare di meglio con le location a mia disposizione e senza
interrompere servizi): nei periodi "buoni" questo test ha segnato
velocità sostenute di 1.35 MB/s, quindi siamo al 99% di capacità! Coi
link in produzione queste sarebbero le nostre velocità standard.
stefanauss a barney:~$ time wget --output-document=/dev/null
http://188.165.12.106/files/100Mio.dat
--2014-07-18 19:15:30-- http://188.165.12.106/files/100Mio.dat
Connessione a 188.165.12.106:80... connesso.
Richiesta HTTP inviata, in attesa di risposta... 200 OK
Lunghezza: 104857600 (100M) [application/octet-stream]
Salvataggio in: "/dev/null"
100%[=======================================>] 104.857.600 1,20MB/s in
92s
2014-07-18 19:17:02 (1,08 MB/s) - "/dev/null" salvato [104857600/104857600]
real 1m32.608s
user 0m1.225s
sys 0m3.266s
A margine va detto che, quando client o server criptati erano serviti su
qualcosa di più carrozzato di OpenWrt, sono riuscito a sfruttare il 100%
della banda.
Server: 1043nd-Capizzanux / Client: rPi: 1.40 MB/s (100% della ADSL di
Peppe)
Server: PfSense-HPCC / Client: 1043nd-Stefanauss: 7.71 Mbps (100% della
ADSL di Stefanauss)
Premesso che: con un link wireless eccellente e un router più carrozzato
(1043v2/3600/4300) sarebbe probabilmente possibile ottenere qualcosa in
più del 72% di cui sopra anche con VPN criptata.
Non essendo, come detto sopra, la pura potenza di calcolo il problema,
le mie ipotesi più educate (amburgerismo @ Vin-San) sono:
- memory bandwidth infima del SoC: è durante il trasferimento da/alla
memoria del pacchetto criptato/decriptato/viceversa che la latenza
uccide il throughput
- qualche passaggio in userspace poco performante. I miei test si sono
svolti in AA, su BB non mi aspetterei niente di diverso ma se il
problema è qui potrebbero esserci delle sorprese.
È tutto. Manterrei questo thread per discutere delle problematiche di
integrazione e prestazionali di OpenVPN in OpenWRT; per il NinucsWrt
development ci sono gli altri thread.
Stefanauss.
[1] http://ml.ninux.org/pipermail/calabria/2014-June/003366.html
[2] http://ml.ninux.org/pipermail/calabria/2014-July/003455.html
[3] http://test.ninux.org/~stefanauss/NinucsWRT/
[4] Per sapere quali sono quelli supportati, lanciate openvpn con la
sola opzione --show-ciphers.
[5] Per riferimento, con un iperf da 10.87.1.0/24 (rete Ninux "fissa"
HPCC) a 10.87.7.1, Capizzanux, ottengo 21 Mbps di throughput puro Ninux,
durante il quale i router non vanno oltre il 6%-7% di CPU.
-------------- parte successiva --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
URL: <http://ml.ninux.org/pipermail/calabria/attachments/20140720/19a2406f/attachment.pgp>
Maggiori informazioni sulla lista
Calabria