Raspberry Pi és az OpenVPN

Amint említettem már, egy Raspberry Pi sok dologra alkalmas. A „vas” lehetőségei természetesen szerények, így hamar elérhetjük a rendelkezésre álló teljesítmény korlátait. Ebben a cikkben egy ilyen korlátról írnék, azaz milyen sávszélesség érhető el egy Raspberry Pi (RPi) alkalmazásával a titkosított OpenVPN hálózaton. Előre bocsátom, az alapértelmezett beállításokkal elérhető sávszélesség szánalmas, de kis finomhangolással megsokszorozható!

Miért OpenVPN?

Raspberry Pi VPNHa nem vagyunk befolyással a VPN szerver és a VPN kliens között valamennyi routerre, akkor könnyen hiábavaló szélmalomharcot kezdhetünk a hálózatok üzemeltetőivel. Kérhetjük ugyan, hogy engedjék át, NAT-olják a GRE, IPsec vagy egyéb protokollokat. Legtöbbször azonban csak a vállrándítós „nálunk minden rendben, oldjátok meg, ahogy akarjátok” lesz a jutalmunk, de ettől persze a VPN-ünk még nem kezd el működni. Küzdhetünk, de a legtöbbször nem érdemes. Az elmúlt 20 év tapasztalata alapján jelentem ki, hogy a fehér tollszín gyakoribb a hollóknál, mint a hozzáértés az informatikai szakembereknél. Vállalom a kövezést…

Az OpenVPN, szemben a PPTP és L2TP/IPsec megoldásokkal csupán egyetlen UDP vagy TCP portot igényel a működéséhez. Sokkal egyszerűbb dolgunk van ezzel a sok „koca-rendszergazda”, „hozzáértő szomszéd” és „informatika tanár” által üzemeltetett hálózaton. Ez is szempont, sőt, néha ez a leglényegesebb. Ilyen világban élünk.

OpenVPN beállítások

Az OpenVPN telepítéséről, kulcsok generálásáról vannak jól használható leírások (linkek a cikk végén), így erre most nem térek ki. Nézzük a konkrét konfigurációs állományokat.

OpenVPN szerver (Ubuntu) beállításai (/etc/openvpn/server.conf)

port 1194
dev tun
proto udp
persist-key
persist-tun
ca ca.crt
cert ubuntu-server.crt
key ubuntu-server.key
dh dh1024.pem
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
keepalive 10 120
status openvpn-status.log
verb 3

OpenVPN kliens (Raspbian) beállításai (/etc/openvpn/client.conf)

client
dev tun
proto udp
remote ubuntu-server 1194
resolv-retry infinite
nobind
persist-key
persist-tun
ca ca.crt
cert raspberry.crt
key raspberry.key
ns-cert-type server
verb 3

OpenVPN

A tömörítést első körben nem kapcsoltam be (comp-lzo), mert elsődlegesen a nyers átvitel érdekelt. A VPN kapcsolat felépítése után teszteltem az elérhető sebességet, egy iperf gyorsteszt első körben elegendő volt.

root@ubuntu-server:~# iperf -s
root@raspberrypi:~# iperf -c 10.8.0.1 -r

Az átvitel első látásra szánalmas, másodikra pedig már-már kétségbeejtő.

12 / 15 Mb/s

Tizenkettő megabit másodpercenként. Régen ez még lobogó haj érzésével lett volna egyenértékű, de azóta eltelt 10+ év.

Néhány teszt után egyértelművé vált, hogy a Raspberry Pi CPU teljesítménye limitálja leginkább a kapcsolat sebességét. Nosza, kikapcsoltam a titkosítást és a csomagok aláírását.

cipher none
auth none

Újra teszteltem, remélve, hogy legalább a titkosítatlan kapcsolat rendben lesz.

22,5 / 27 Mb/s

Gyorsult a kapcsolat, de nem annyival, amennyivel kellene. Hová lett a két gép közötti 100 Mb/s körüli sávszélesség kb. 70%-a? Elővettem ismét a manuált, hátha. Az olvasás végére egy tippem volt:

fast-io

A konfigurációs állományokat bővítettem ezzel az opcióval, majd újraépítettem a VPN kapcsolatot. Az újabb teszt is lefutott.

23,9 / 30,6 Mb/s

Remek, mert gyorsult, de alig, titkosítás nélkül még a szánalmas szinten maradt.

Jöhetett az újabb kör, körülnéztem a fejlesztői listákon, felhasználói fórumokon. Mindig elfelejtem, hogy ezek csak arra jók, hogy elüssünk 1-2 órát, és végül meggyőződjünk róla, nem csak mi futottunk gondba. Jó, ha nem vagyunk egyedül a gondunkkal, de megoldást a legritkább esetben kapunk. Most sem volt ez másként. Leginkább azt olvashattam, hogy igen, gyenge hardveren bizony-bizony lassú a VPN. Lassú, de ennyire? Nem hittem el. Eltelt néhány óra a különféle trace-ek kimenetének bámulásával, mire körvonalazódott a helyzet.

Ez a kutyatetem több helyen van elásva

1. A Raspberry Pi ethernet interfésze nem a legjobb. Gyakorlatilag egy USB 2.0 buszra kötött, „gyengécske” smsc95xx. Nem sok terhet képes átvenni a CPU válláról, erről az alábbi parancs kimenete is árulkodik.

root@raspberrypi:~# ethtool -k eth0

Második probléma az RPi USB vezérlője. Az USB 2.0 elvileg 480 Mb/s átvitelre is képes, és ennek a felét valóban képes is elérni egy RPi, de ennek ára van. Az USB busz használata is jelentős mértékben terheli a CPU-t.

A fentiek már bőven elegendő indokkal szolgáltak arra, hogy a 100 Mb/s sebességet LAN-on, VPN és egyéb csalafintaságok nélkül, egy irányban sem képes elérni a Raspberry Pi.

Sokan kritizálják az RPi ezen részét (USB + ETH), de ők nem gondolnak bele, hogy egy jobb ethernet kártya ára bizony a Raspberry Pi teljes árának többszöröse.

2. A VPN kapcsolat egy virtuális hálózati interfészen keresztül bonyolódik, amelynél nyilván a CPU-t terheli valamennyi feladat. Az OpenVPN nem áll jól az optimális kódok tekintetében, ami csak tovább rontja a helyzetet.

A fenti okokra vezethető vissza az, hogy a VPN kapcsolaton elérhető sebesség a közelében sincs az elfogadható szintnek. A legkézenfekvőbb megoldást, a Raspberry Pi túlhajtását elvetettem, hiszen nem az a célom, hogy az eszköz idő előtt menjen a kukába.

Milyen lehetőségek maradtak?

A helyzet egyszerű, meg kell takarítani valahol egy kis erőforrást, hiszen minden megtakarítás növeli az elérhető sebességet. Fontos tudni, hogy az OpenVPN a titkosítást csomagonként végzi, és az OpenSSL algoritmusok erőforrásigénye függ a titkosítandó blokkok méretétől és számától is. Algoritmustól függő, de általában kevesebb erőforrást igényel 1db 16 kilobyteos blokk titkosítása, mint 16 db 1 kilobyteos blokké.

1. Valamivel takarékosabb titkosítási algoritmus

cipher AES-128-CBC
auth MD4

Az AES-128-CBC cipher és az MD4 digest (auth) néhány teszt után került kiválasztásra. A teszteléshez az OpenSSL algoritmusok összehasonlító tesztjét használtam.

root@raspberrypi:~# openssl speed

2. Az MTU érték növelése a virtuális interfészeken

tun-mtu 9000
fragment 0
mssfix 0

A tunnel MTU értéke alapesetben a linken elérhető MTU értékéből származtatott, ami jelen esetben, az ethernet hálózaton szokásos 1500 byte-os érték lenne. A virtuális, tun interfészen a fizikai kapcsolattól függetlenül emelhető az MTU értéke, tehát a VPN szerver és kliens között ezzel nem lesz gond. A fragment és mssfix opciókkal az OpenVPN belső fragmentálását kapcsoltam ki. Magától értetődően a fenti beállítások szerver és kliens oldalon is szükségesek voltak.

A VPN újrakapcsolódás után teszt már szebb képet mutatott, az átviteli sebességek javultak.

34.2 / 36.6 Mb/s

Közel háromszor gyorsabb lett a VPN, mint az alapértelmezett beállításokkal. Elvégeztem magasabb tunnel MTU értékekkel is a tesztet. A tesztek eredményét az alábbi táblázatban összefoglaltam.

OpenVPN Teszt

Ha a csomagoknak át kell menniük valahol egy a tun-mtu paraméterben megadottnál szűkebb interfészen, mondjuk a VPN szerver mögötti hálózaton lévő gépeket is el kell érni, akkor érkezni fog egy Fragmentation Needed ICMP üzenet. Persze ebben az esetben a megemelt MTU előnyeiből nem profitálunk. A 9000-es MTU még a legtöbb fizikai hálózaton is elérhető, de természetesen csak jumbo frameket támogató hálózati eszközökkel.

A végleges VPN kapcsolaton engedélyeztem a tömörítést, ehhez csak az alábbi sort kellett hozzáadni a kliens és szerver beállításaihoz.

comp-lzo

Ezt és a 60000-es tun-mtu értéket kombinálva már elég szép értékeket mutatott az iperf teszt.

160 / 217 Mb/s

Természetesen tudom, hogy ez nem teljesen valós érték, hiszen ritkán adódik annyira jól tömöríthető forgalom, mint a szintetikus, iperf teszt által generált. A fenti eredményen lehetne még kissé tuningolni, pl. a link és a tunnel MTU értékek egymáshoz hangolásával, hogy maximálisan kihasználjuk az 1500-as csomagokat. Ennek azonban a sok, eltérő kapcsolaton lévő végpont miatt nem láttam értelmét.

Legjobb megoldás természetesen egy tisztességes, megfelelően optimalizált VPN szerver/kliens szoftver használata volna. A jelenleg elérhető, opensource megoldások között ilyen sajnos nincs, legyen szó L2TP over IPsec, PPTP vagy egyéb protokollok implementációiról. Csak 1-2 kevésbé rossz van a nagyon rosszak között, nálam jelenleg az OpenVPN a befutó.

Hivatkozások:

http://openvpn.net/
https://wiki.debian.org/OpenVPN
https://help.ubuntu.com/13.10/serverguide/openvpn.html