A hallgatói VPN idáig PPTP alapon ment, ám időközben a labort és hallgatói virtuális gépek hálózatát kiszolgáló Saruman szervert nyugdíjaztuk, a rajta futó Win2003 Serverrel együtt, helyét most Win2008 R2 Server vette át. Ezzel kezdődött a bonyodalom, mert a régi jól bevált PPTP VPN az új RRAS (Routing and Remote Access Service, ez felelős Windows alatt többek között a VPN szerver-oldali szolgáltatásért) változattal már nem ment olyan simán. Sőt egyáltalán nem akart menni.
Hogy megérthessük, hogy pontosan mi is változott, először egy kis “VPNológia”
Kicsit leegyszerűsítve a legtöbb VPN megoldásnak 3 része van: fej, tor, potroh
- Autentikációs protokoll – ez hitelesíti a becsatlakozó klienst, ellenőrzi a felhasználónevet, jelszót, illetve ezzel hitelesítheti a kliens a szerver is.
- Kulccsere protokoll – egy közös titkosító kulcsban itt állapodik meg a két fél, valamint egyéb kapcsolati paramétereket is egyeztetnek, például IP címet.
- Forgalomtovábbító (tunneling) protokoll – a tényleges forgalmat ez viszi át, előfeltétele, hogy legyen közös kulcs.
Néhány fajta VPN megoldásnál ezek nem különülnek el, nincs mindenféle kombinációs lehetőség, mindegyikből egyféle van. Ilyen “három-az-egyben” csomagot kapunk pl. az OpenVPN és a Microsoft új SSL alapú VPN protokollja, az SSTP esetében. A PPTP és az IPSec viszont nem ilyen.
A PPTP a kapcsolat paraméter egyeztetést valamint a kapcsolat állapotkövetését végzi csak el, a forgalom GRE (General Routing Encapsulation) protokoll felett zajlik, ahol ráadasul még többféle opció is van a titkosításra, tömörítésre; jelenleg az MPPE és az MPPC használható ezekre a feladatokra.
Az IPSec szerepét tekintve talán leginkább a GRE-hez hasonlítható, önmagában csak a forgalomtovábbításért felelős. A hiányzó funkciókat más protokollokkal kell megoldani, vagy fixen kiosztott kulcsokkal kézzel két oldalon felhúzni a kapcsolatot. Az IPSec esetén a kulcs és konfigurációs adatok egyeztetésére találták ki az IKEv1 és IKEv2 (Internet Key Exchange) protokollokat.
Nem esett még szó a hitelesítésről: IPSec és PPTP esetén az autentikációra MSCHAP, MSCHAPv2, EAP-MSCHAPv2, EAP-MD5, EAP-TLS, LEAP, PEAP, PAP és más hasonló protokollok választhatók. Ezek közül jónéhány idejétmúlt és nagyon nem biztonságos. Biztonságosnak tekintik ma a PEAP, EAP-MSCHAPv2 és EAP-TLS-t.
És akkor most a bonyodalom
Az új RRAS szerverben alapértelmezetten letiltották azokat a hitelesítési protokollokat, amikről időközben kiderült, hogy nem biztonságosak. Vissza lehetne ugyan kapcsolni őket, de nyilvánvaló, hogy ez a megoldás nem volt az ínyünkre. A probléma főként a Linuxot futtató klienseket érinti, WinXP SP3 támogatja a PPTP újabb hitelesítési módjait, Vista és Win 7 pedig már az SSTP-t is.
Linux alatt jelenleg a PPTP kliens viszont csak a nem biztonságos autentikációs módszereket valósítja meg. PEAP és EAP-MSCHAPv2 támogatás jelenleg nincs, EAP-TLS is csak külön patch formájában érhető el. Ráadásul ez utóbbi a klienseket is tanúsítvány alapján azonosítaná, minden felhasználónak személyi tanúsítványt osztani pedig nem kellemes feladat.
Második lehetőségként felmerült az SSTP, mint a Microsoft “PPTP-t leváltó következő generációs VPN” rendszere. Jelenleg nem ismeretes Linux alatt használható SSTP implementáció, de még olyan projektet sem találtam amely ennek implementálását tűzte volna ki célul.
Kizárásos alapon marad az IPSec
Megmondom őszintén elsőre eléggé fáztam tőle, mert a kluccsere és autentikációs protokollok, valamint opcionálisan implementálható (és emiatt eléggé következetlenül támogatott) lehetőségek dzsungelében egy jó adag szenvedés kinézett nekem. Az IPSec sosem arról volt híres, hogy egyszerű lenne összelőni. Másrészt az IKEv2 fő előnye pont az, hogy rengeteg korábban opcionális vagy le nem rögzített részletet kötelezően előírtak, így – elviekben – két IKEv2 implementációnak garantáltan képesnek kell lennie együttműködésre. Persze ilyet sokszor hallottunk már…
A Windows Server 2008 R2-ben található RRAS támogat IPSec + IKEv2 + EAP-MSCHAPv2 kombinációt. Linux alatt két nyílt forrású projekt valósítja meg többé-kevésbé ezt a kombinációt az Openswan és a StrongSwan. Én az utóbbival álltam neki, igazából nem tudom, hogy az Openswannal is működne-e, a leírások alapján az IKEv2 ott kevésbé van készen.
StrongSwan IPSec konfigurálása
Viszonylag sokat kerestem kész leírást arról, hogy Win2008, mint VPN szerver és StrongSwan, mint kliens között hogyan kell IPSec-et beállítani, de meglepő módon ilyet sehol nem találtam. Reményre adott okot, hogy a fordított felállás: StrongSwan, mint szerver és Windows 7, mint kliens dokumentáltan működik. Létezik mintakonfiguráció EAP-MSCHAP-V2 autentikáció használatára is, ebből indultam el, néhány paramétert azonban így is ki kellett találni.
A Strongswan telepítését most balladai homályban hagyom, ki-ki kedvenc disztribúciójához keresse ki, hogy hogyan kell, legrosszabb esetben fordítsa forrásból (én is így tettem).
Alapvetően három konfigurációs fájlt kell szerkeszteni:
-
/etc/strongswan.conf
-
/etc/ipsec.conf
-
/etc/ipsec.secrets
A /etc/strongswan.conf
tartalma elvileg alapértelmezetten jó kell hogy legyen:
charon { # number of worker threads in charon threads = 16 # plugins to load in charon # load = curl aes des sha1 md5 md4 sha2 pem pkcs1 hmac gmp random pubkey xcbc x509 stroke kernel-netlink fips-prf eap-mschapv2 eap-identity updown socket-default plugins { sql { # loglevel to log into sql database loglevel = -1 # URI to the database # database = sqlite:///path/to/file.db # database = mysql://user:password@localhost/database } } } pluto { # plugins to load in pluto # load = aes des sha1 md5 sha2 hmac gmp random pubkey } libstrongswan { # set to no, the DH exponent size is optimized # dh_exponent_ansi_x9_42 = no }
A lényeg, hogy legyen benne charon rész (Charon a kódneve az IKEv2 démonnak, Pluto az IKEv1-esnek), valamint arra figyeljünk, hogy a load=
maradjon kikommentezve, a mintakonfiguráció itt ugyanis hibás! Ha nincs megadva load=
, akkor magától betölti az összes szükséges modult, ha viszont van és kihagyunk valami lényegeset a listából, akkor a logban például ilyen hibaüzeneteket kapunk:
charon: 14[NET] no socket implementation registered, receiving failed
A konkrét kapcsolat beállítása a /etc/ipsec.conf
fájlban történik:
# ipsec.conf - strongSwan IPsec configuration file # basic configuration config setup # plutodebug=all # crlcheckinterval=600 # strictcrlpolicy=yes # cachecrls=yes # nat_traversal=yes # charonstart=no plutostart=no # Add connections here. conn %default ikelifetime=60m keylife=20m rekeymargin=3m keyingtries=1 keyexchange=ikev2 conn studentvpn leftfirewall=yes leftauth=eap eap_identity=<felhasználó neve> right=<szerver IP címe> rightauth=pubkey rightid="<Subject fully qualified name a szerver tanúsítványából>" rightsubnet=<a VPN kapcsolatra kiosztott IP alhálózat> auto=add leftsourceip=%config
A lényeges beállítások ezek:
keyexchange=ikev2
– nem kell hozzá sok magyarázat, kiválasztja az IKEv2 protokolltauto=add
– ez egy kapcsolatra megadja, hogy az ipsec démon indításakor (ami normális esetben init scriptből történik) csak töltse be a konfigurációt, de ne indítsa el a kapcsolatot automatikusan.left*
– ez a helyi végpont beállításait jelölileftfirewall=yes
– ha van tűzfal a gépen, akkor adja hozzá az IPSec kapcsolathoz szükséges szabályt. Elvileg lehetne ezt saját tűzfalmódosító shell scripttel is csinálni, ilyenkor a saját scriptetleftup
ésleftdown
paraméternél lehet megadni. Ha nincs tűzfal, akkor is hagyhatjuk engedélyezve.leftauth=eap
– a kliens EAP protokollal próbálja a szerver felé hitelesíteni magát. Az EAP olyan okos, hogy ezen belül a két végpont le tudja egyeztetni a közösen használt autentikációs eljárást, így automatikusan megegyeznek, hogy EAP-MSCHAPv2-t fognak használni. Ezt egyébként kézzel is meg lehetne adni:eap=mschapv2
.leftsourceip=%config
– megmondja, hogy az IKE konfiguráció egyeztetési fázisban a kliens kérjen IP címet a szervertől. Ez egy nagyon kritikus beállítás, sajnos sehol nem írják le, hogy RRAS elvárja, hogy a kliens IP-t kérjen, különben hibajelzéssel bontja a kapcsolatot. Enélkül kliens oldalon ilyen (sokatmondó) hibaüzenetet kapunk:AUTH payload missing
, ebből nem volt egyszerű visszanyomozni, hogy valójában mi is a probléma.
right*
– ez a távoli végponthoz tartozó beállításokat jelentiright=
– itt kell megadni a szerver IP címét.rightauth=pubkey
– ez most aleftauth
fordított irányban, az itt megadott módon próbálja hitelesíteni a kliens a szervert. Apubkey
azt jelenti, hogy tanúsítvánnyal megadott nyilvános kulcsú hitelesítést használ. A tanúsítványt majd később telepíteni kell.rightid=
– ez lényegében csak egy string, amit a szerver elküld a kliensnek, a kliens pedig ellenőrzi, hogy azt kapta-e, amit elvárt. Ennél persze bonyolultabb a hozzátartozó magyarázat, viszont a sok inkompatibilis megvalósítás miatt a Strongswan alatt bármire beállíthatjuk. Ha nem jól állítjuk be vagy egyáltalán nem állítjuk be (alapértelmezetten a kapcsolat nevét ill. IP címét használja), akkor a kliens nem fog kapcsolódni. Szintén elég nehéz feladat volt azt kitalálni, hogy a Win2008 RRAS szervere mit küld el ID gyanánt, lévén hogy ez a beállítás ott kézzel nem állítható. Végülis a Microsoft viszonylag logikusan a szerverre beállított tanúsítványból a Subject fully quailified name mezőt választotta, annak tartalmát kell ide beírni, idézőjelek között.rightsubnet=
– igazából opcionális, ezzel megadható, hogy milyen IP alhálózatot érhetünk el a VPN kapcsolaton keresztül. Enélkül is működött, feltehetően arra való, hogy felülbírálhassuk amit a paraméteregyeztetés során kapna a másik végponttól.
eap_identity=
– a felhasználónevet itt adjuk meg, nem szabad semmi idézőjelet használni. Érdekesség, hogy bár az RRAS szervert futtató gép nem Active Directory tartományvezérlő, de tartományi tag, és a felhasználókat az AD-ből hitelesíti, mégsem kell a felhasználónévnél megadni a tartomány nevét.
Hátra van még a jelszó elhelyezése a /etc/ipsec.secrets
fájlban:
# /etc/ipsec.secrets - strongSwan IPsec secrets file username : EAP "password"
Végül pedig telepíteni kell a szerver tanúsítványát aláíró főtanúsítványt (Certification Authority Certificate), ha nem valamelyik hiteles tanúsítványszolgáltató által kiadott tanúsítványt használunk. Egyszerűen be kell másolni a fájlt a /etc/ipsec.d/cacerts
könyvtárba, DER és PEM formátumban is elfogadja, így konvertálni sem kell.
Összefoglalva a mintakonfigurációkban eddig le nem írt beállítások ezek voltak:
- load=-t ne adjunk meg
- leftsourceip=%config legyen
- rightid= a szerver tanúsítványából a subject mező legyen
A kapcsolat felépítéséhez a következőket kell tenni:
IPSec démon indítása (akár lehet automatikusan init scriptből minden bootoláskor):
sudo /etc/rc.d/ipsec start
Kapcsolat indítása:
sudo ipsec up studentvpn
Ha jól sikerült, akkor a sok konzolra írt log üzenet végén, valami ilyesmit látunk:
installing DNS server 10.40.1.10 to /etc/resolv.conf installing new virtual IP 10.40.210.2
Viszont hiába keressük, nem látjuk ennek semmi nyomát az ifconfig illetve route parancsok kimenetében. Normális esetben az ember azt várná, hogy egy VPN kapcsolat kiépülésekor megjelenik egy új hálózati interfész, pl.: PPTP VPN esetén ppp0
vagy OpenVPN-nél tun0
és ez veszi fel a megfelelő IP címet. Itt nincs semmiféle ipsec0
vagy hasonló interfész. Pedig a kapcsolat működik.
Régebben még valóban úgy működött az IPSec Linux alatt, ahogy imént írtam, most azonban az IPSec tunnelen keresztül elérhető IP címet az a hálózati interfész veszi fel, amelyiken keresztül megy a forgalom, pl eth0
. Viszont ifconfig
gal az eth0
esetén sem látjuk a VPN-en keresztül kiosztott IP címet, ugyanis az IPSec esetén egy transzformáción (ESP-be csomagolás, titkosítás) esik át a forgalom; az ilyen módon beállított IP végpontot pedig egy külön táblázat tárolja a kernelben. Az ifconfig
, route
és egyéb “hagyományos” linuxos hálózati konfigurációs eszközök ezt nem támogatják és nem is fogják támogatni, helyette itt az idő átszokni az új parancsra: ip
.
Az ip addr list
parancs kimenetén látjuk az eth0
-hoz rendelt második IP címet és hasonlóképpen az útvonalválasztási szabályt az ip route show table 220
paranccsal nézhetjük meg.
A kapcsolat (IPSec szóhasználatban SA, azaz Security Association) állapota így is lekérdezhető:
sudo ipsec statusall
Végül a kapcsolat bontása:
sudo ipsec down studentvpn
Slusszpoén:
Az IPSec NAT-T (NAT traversal) üzemmódja IKEv2 esetén már nem opcionális, hanem kötelezően megvalósítandó elem, így elvileg a NAT-oló routerek mögül is gond nélkül működhet IPSec VPN. Ez esetben ugyanis nem ESP datagramokat használ közvetlenül IP felett, hanem UDP-be ágyazza be az ESP-t (persze némi teljesítményvesztés árán), így a NAT-oló eszközök számára is emészthető lesz a forgalom.
Én ennél egy még sokkal elvetemültebb módon teszteltem: egy OpenVPN tunnel fölött húztam fel az IPSec tunnelt és NAT-T üzemmódban ez minden további nélkül működött is. 🙂