A blogban leírtak a szerzők saját véleménye, és nem a munkáltatójuké.

IPSec VPN Windows 2008 RRAS és Linux között

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 protokollt
  • auto=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öli
    • leftfirewall=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 scriptet leftup és leftdown 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 jelenti
    • right= – 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. A pubkey 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 ifconfiggal 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. 🙂

Leave a Reply

 

 

 

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>