Az SSH működése
Alapok
Az SSH működése 1.Az alapok Manapság az SSH egyike a legfontosabb biztonsági eszközöknek. Leggyakrabban távoli shell eléréshez használják, de alkalmas fájlok átvitelére, távoli X alkalmazások helyi megjelenítésére és biztonságosan elérhetők vele olyan szolgáltatások, amik egyébként nem használnak titkosítást. Sajnos sokan azok közül sem értik hogyan is működik valójában, akik minden nap használják. Köztudott hogy az SSH2 átvette az SSH1 szerepét, de hányan ismerik a beléptetés pontos menetét? Én sem ismertem, ezért utánajártam. Tisztázzuk az elején, hogy ez nem egy részletekbe menő technikai dokumentáció, hanem egy közérthető leírás. A lényeg, hogy megértsd a folyamatot, mintsem hogy elvessz a részletekben. Először áttekintjük, miben különbözik az SSH1 beléptetése az SSH2-étől, majd pedig röviden bemutatom a felhasználók hitelesítésére használt RSA/DSA kulcspár működését. Lássunk hozzá! Először is, az SSH-nak két fő verziója van – SSH1 és SSH2. Az SSH2 az újabb, és erősen ajánlott mindenkinek aki SSH szervert futtat, hogy csak ezt engedélyezze. Ehhez az sshd_config fájl elején a Protocols sorból ki kell törölni az 1-est. Ez biztosítja, hogy az ssh démon még akkor sem fog visszaváltani SSH1-re, ha a kliens nem támogatja az SSH2 protokollt. A kapcsolódás menete SSH1: Az sshd legelső indításakor a szerver generál egy host kulcspárt, aminek két részre bontható: nyilvános-(public) és privát(private) kulcs. A kulcspár nyilvános felével azonosítja magát a kliensek számára. A kapcsolat felépítéséhez egy másik kulcspár is szükséges, a szerver kulcspár, ami óránként cserélődik. Mikor egy kliens csatlakozik, a szerver elküldi neki mindkét kulcspár nyilvános felét, az állandó host kulcsot, és az óránként változó szerver kulcsot. Ezután a kliens ellenőrzi hogy a kulcs valóban a megadott szerverhez tartozik-e. Összehasonlítja a host kulcsot egy előző, ugyanezzel a szerverrel folytatott kapcsolat host kulcsával. Egyezés esetén, a kapcsolat felépítése szó nélkül folytatódik. Eltérés esetén azonban a kliensprogram figyelmeztet a host kulcs megváltozására. Ez lehet egy Man-In-The-Middle (MiM) támadás jele, vagy egyszerűen csak időközben frissítették a szervert. Ezek után a kliens generál egy 256 bites minél véletlenebb számot, és ezt titkosítja mindkét kapott kulccsal. A szerver nyilvános kulcsaival való titkosítás biztosítja azt, hogy csak a megadott gép tudja visszafejteni az üzenetet. A szerver ezzel a véletlen számmal generál egy session key-t, amit a szimmetrikus kódoláshoz fog használni. A továbbiakban a kommunikáció ilyen szimmetrikus kódolással (pl. 3DES vagy Blowfish) védetten folyik. Most kérdezhetnéd, hogy mi ezzel a baj? Szerintem semmi. Pusztán matematika. Az SSH1 is erős védelmet biztosít, de az a SSH2 még erősebbet. SSH2: Itt ugyanúgy jelen van a host kulcspár, mint az előző verzióban és a szerepe is ugyanaz. Viszont a nincsen szerver kulcs, mivel kapcsolat felépítése alapvetően eltér az előző verziótól. Az SSH1-nél a kliens vett egy nagyon nagy számot, titkosította mind a host, mind a server kulccsal, és a szerver ezt a számot használta a session kulcsok létrehozásához. Tehát szükség volt egy szerver kulcsra az aktuális kapcsolat felépítéséhez. A SSH2 nagy előnye, hogy nincsen szükség erre a plusz kulcsra, mivel ún. Diffie-Hellman protokollt használ a kapcsolódáshoz.
1
Az SSH működése
Diffie–Hellman
2. Diffie–Hellman: A Diffie–Hellman kulcscsere-protokollt (meglepő módon) Diffie és Hellman fejlesztette ki 1976ban. Az egész dolog lényege, hogy két fél átvigyen egy titkos, mások által ismeretlen adatot egy nyilvános csatornán anélkül, hogy előtte bármilyen közös jelszót közölnének egymással. (Végül is az SSH1 két kulcsos, véletlen számos módszere is erre szolgált.) Lássuk a működését: A protokoll két számra épül, melyeket Diffie–Hellmann-paramétereknek hívunk. Ez két, egymástól függő érték: egy nagyon nagy prímszám: "p" és egy ennél kisebb szám "g". A kapcsolatuk abban áll, hogy minden n természetes szám felírható n = g^k / p alakban. A feleknek ugyanazokat a p és g paramétereket kell használniuk, hogy a dolog működjön. Szükség van még egy harmadik, privát számra is. Ezt mindkét fél magának generálja, nevezzük "x"-nek. Az x értékét a p-vel és g-vel ellentétben nem közlik egymással. A nyilvános kulcsokat - amiket majd elküldenek egymásnak - a következőképpen állítják elő: y = g^x / p ...tehát a g-t az x-edik hatványra emeljük, majd osztunk p-vel. Az eredményül kapott y-t a felek átküldik egymásnak, ennek segítségével számítjuk ki a közös, titkos z számot. z = y^x / p ...más szóval fogjuk a kapott y nyilvános kulcsot, és az x-edik hatványra emeljük (x a privát kulcsunk) és elosztjuk a közös p-vel. Az eredmény a titkos érték, z lesz. A dolog szépsége, hogy ezzel a módszerrel mindkét fél ugyanazt a z-t kapja. És ez a z egy kiváló kulcs, akármilyen kódolási algoritmust is alkalmazzunk a továbbiakban. Miért? z = (g^x / p)^x' / p = (g^x' / p)^x / p Megjegyzés: A zárójelben lévő kifejezés a másik fél nyilvános kulcsa. Vedd észre, hogy ez tartalmazza a saját, privát kulcsát is. Ez teszi matematikailag lehetővé a közös titkos szám átvitelét anélkül, hogy magát a számot elküldtük volna. Fontos megjegyezni, hogy az SSH1 szerver kulcsának az szerepe mindössze az volt, hogy a kliens biztonságosan vissza tudja küldeni az általa generált véletlen számot. Tehát a z-t. A Diffie–Hellman módszer ugyanúgy egy titkos értéket közvetít a két fél között, csak mégis jobban. Láthattuk, hogyan működik a Diffie–Hellman protokoll általában. Most nézzük meg, milyen szerepe van az SSH2-ben. Kapcsolódáskor a kliens többekközt azt is közli a szerverrel, hogy milyen tartományba essen a p (minimum, pont jó, maximum formában). A szerver ez alapján kiválasztja a p-t, megkeresi a hozzá tartozó g-t, majd mindkettőt elküldi a kliensnek. A továbbiakban mindketten az így kiválasztott értékeket fogják használni. Ezután a kliens és a szerver is létrehozza a privát kulcsát, majd kiszámítják a nyilvános kulcsaikat, és a kliens elküldi a sajátját a szervernek. Eddig nem esett szó a szerverről, ami valójában sok mást is küld a kliensnek a nyilvános kulcsán kívül. Kapcsolódáskor a szerver veszi: · a kliens SSH version string-jét (kapcsolódáskor kapja) · a saját SSH version string-jét (ismert) · a kliens encryption protocol request (kapcsolódáskor kapja) 2
Az SSH működése
Diffie–Hellman
· a saját encryption protocol request (ismert) · a saját host kulcsát · a kliens által kért a minimális, megfelelő, és maximális p értéket · a p tényleges értékét · a g értékét · a kliens nyilvános kulcsát · a szerver nyilvános kulcsát (az y-t ha úgy tetszik) · a z közös titkos számot és egy hash műveletet hajt végre rajtuk. Ez tizenhárom eltérő érték, mindegyikük hosszú sztring vagy nagyon nagy szám. Utána a szerver aláírja ezt a hash-t a saját host kulcsával (az aláírás a kulcspár privát felével történik), majd elküldi a kliensnek a host kulcsa nyilvános részét és ezt az aláírást. A kliens először a host kulcs alapján ellenőrzi a szerver valódiságát (ez az az értesítés, amit akkor kapsz, mikor egy új szerverhez csatlakozol). Megnézi, hogy a kapott host kulcs eltér-e a /home/user/ssh/known_hosts fálban előzőleg eltárolttól, és ha nem találja ott, vagy megváltozott, akkor szól. NE hagyd figyelmen kívül ezeket az üzeneteket, mert a te védelmedet szolgálják a Man In the Middle támadással szemben. Miután megbizonyosodott róla, hogy a szerver az, akinek mondja magát, a kliens is kiszámolja a hash-t pontosan ugyanazon értékek alapján, mint a szerver. A z értéke tisztán sosem kerül kiküldésre, csak a tizenhárom adat aláírt hash-e közt. A z kiszámítását mindkét fél maga végzi, ezért a hash csak akkor lehet egyenlő, ha mindketten ugyanazt a z-t kapták. Továbbá azt is látnod kell, hogy mivel a kliens a szerver publikus kulcsát használja a dekódolásra, a hash aláírása csak a szerver host kulcsának privát részével történhetett. Ez garantálja a hash hitelességét. A folyamat végén, a szerveren és a kliensen is ott lesz a z. A kriptográfia gyönyörű dolog. A továbbiakban ezt a közös, titkos számot használják a kapcsolat titkosításához. Ez történhet AES, Blowfish, 3DES, vagy bármilyen szimmetrikus algoritmussal, amiben a gépek megegyeztek. Fontos felismerni hogy ez a közös titok az a probléma, amire a nyilvános kulcsú kriptográfia megoldást nyújt. Vegyünk például egy SSL kapcsolatot, olyat, mint ami te is használsz, amikor az Amazon.com-ról rendelsz. Mikor megnyitod a https://www.amazon.com-ot, a géped kiválaszt egy véletlen számot (mint az SSH1, vagy a Diffie-Hellman x-je), titkosítja az Amazon nyilvános kulcsával, és elküldi neki. Ettől fogva egy szimmetrikus algoritmust használsz. Az ilyen típusú (SSH és SSL) adatcseréknél a nyilvános kulcsú titkosítást használják arra, hogy a két fél, akiknek előtte nem volt semmilyen közös kulcsuk, létrehozzon egyet. Ezt a titkos kulcsot használják a tényleges kódolt kapcsolat felépítéséhez (RC4, 3DES, stb).
3
Az SSH működése
Az azonosítás és a kulcsok
3.Felhasználó azonosítása Ok, van egy titkosított kapcsolatunk, ideje beléptetni a felhasználót. Most már tudod, miért mondják azt, hogy az SSH titkosítva küldi el a jelszavad. Akár SSH1-gyel, akár SSH2-vel építetted fel a kapcsolatot, most meg kell győznöd a távoli rendszert, hogy jogosult vagy belépni. Ehhez a szervernek közölni kell a klienssel, hogy milyen hitelesítéseket engedélyez. Mondjuk, hogy elfogad jelszavakat és kulcsokat is. Tehát ha a kliens kulccsal próbál belépni, akkor a belépés kulcs alapú lesz. Ha a szerver kulcsra vár, de ezt a kliens nem támogatja, akkor a hitelesítés visszavált jelszó alapúra. Mikor kulcs alapú titkosítást szeretnél, de valamit félreállítasz, akkor shell helyett jelszó promptot kapsz. Ez azért van, mert a szerver alapból kulcsokat és jelszavakat is fogad, és ha nem talál megfelelő kulcsot, akkor jelszót kér. A jelszóellenőrzés elég egyértelmű: elküldöd a nevedhez tartozó jelszót, és a szerver ellenőrzi, hogy egyezik-e a /etc/shadow -ban tárolttal. (Igazából ennél kicsit bonyolultabb a dolog, de nem sokkal.) Kulcsok: A kulcs alapú azonosítás sokkal bonyolultabb, RSA/DSA publikus/privát kulcspárokkal történik. A hitelesítéshez a kliensprogram elküldi a felhasználó loginnevét és a nyilvános kulcsát a szervernek. A szerver ellenőrzi a nevet az authorized_keys fájlban. Ha a nyilvános kulcsok egyeznek, akkor a szerver fog egy véletlen számot, és titkosítja ezzel a kulccsal. Ez a próba (challenge). A kliens a privát kulcsával dekódolja ezt a számot. Végrehajt rajta egy MD5 hash algoritmust, és visszaküldi a szervernek az eredményt. A szerver megnézi, hogy egyezik-e ez az érték az eredeti, kiküldött szám MD5 hash-ével. Ha igen, akkor beengedi a felhasználót. Ok, most már tisztában vagyunk vele, hogyan is kéne ennek működnie. Most nézzünk meg, hogy épül fel egy konkrét SSH2 kapcsolat. A következőkben egy –v paraméterrel indított SSH kliens kimenete látható. A "verbose" paraméter hatására a program "debug 1" szintű üzeneteket közöl, amik sok fontos részletet elárulnak a kapcsolatról. user@mybox user $ ssh v herbox OpenSSH_3.7.1p2, SSH protocols 1.5/2.0, OpenSSL 0.9.7b 10 Apr 2003 debug1: Reading configuration data /etc/ssh/ssh_config debug1: Connecting to herbox [192.168.5.2] port 22. debug1: Connection established. debug1: identity file /home/user/.ssh/identity type 1 debug1: identity file /home/user/.ssh/id_rsa type 1 debug1: identity file /home/user/.ssh/id_dsa type 1 debug1: Remote protocol version 2.0, remote software version OpenSSH_3.7.1p2 debug1: match: OpenSSH_3.7.1p2 pat OpenSSH* debug1: Enabling compatibility mode for protocol 2.0 debug1: Local version string SSH2.0OpenSSH_3.7.1p2 debug1: SSH2_MSG_KEXINIT sent // encryption preference debug1: SSH2_MSG_KEXINIT received debug1: kex: server>client aes256cbc hmacmd5 none // 256bit AES (good stuff) debug1: kex: client>server aes256cbc hmacmd5 none debug1: SSH2_MSG_KEX_DH_GEX_REQUEST sent // the client requests ‘p’ and ‘g’ debug1: expecting SSH2_MSG_KEX_DH_GEX_GROUP // the server’s ‘p’ and ‘g’ debug1: SSH2_MSG_KEX_DH_GEX_INIT sent // the client sends its ‘y’ debug1: expecting SSH2_MSG_KEX_DH_GEX_REPLY /* the servers ‘y’, its host key, and the signature ofthose thirteen values */ debug1: Host 'herbox' is known and matches the DSA host key. // client verifies host key debug1: Found key in /home/user/.ssh/known_hosts:1 debug1: ssh_dss_verify: signature correct // the client verifies the signature debug1: SSH2_MSG_NEWKEYS sent // negotiating symmetric keys debug1: expecting SSH2_MSG_NEWKEYS debug1: SSH2_MSG_NEWKEYS received debug1: SSH2_MSG_SERVICE_REQUEST sent debug1: SSH2_MSG_SERVICE_ACCEPT received // service requested, authenticate a user ********************* herbox.org $her_banner *********************
4
Az SSH működése
Az azonosítás és a kulcsok
debug1: Authentications that can continue: publickey,password,keyboardinteractive debug1: Next authentication method: publickey debug1: Offering public key: /home/user/.ssh/mykey debug1: Server accepts key: pkalg sshdss blen 1858 debug1: Authentication succeeded (publickey). debug1: channel 0: new [clientsession] debug1: Entering interactive session. Last login: Thu Oct 16 04:30:37 2003 from 192.168.5.3 user@herbox user $
Jelszavak vagy kulcsok? Az USENET-en és más fórumokon gyakran vitáznak arról melyik a biztonságosabb. Lényeges dolog, hogy az SSH2 használatakor az azonosításhoz használt titkosított csatorna már létezik és eléggé biztonságos (a választott algoritmustól függően). Szóval nem az a kérdés, hogy a jelszót útközben lehallgatják-e, hanem sokkal inkább az, hogy a szerver így is sebezhető. Jelszavak használatakor, ha valaki feltöri a szervert, a jelszavak ellopása komoly problémákat okoz. Főleg ha figyelembe vesszük, hogy mennyire hasonló jelszavakat használunk egy adott környezetben. Ha kulcsokat használunk, az igazi azonosítási pont a saját privát kulcsunk, ami a mi gépünkön van, ezért a szerver feltörésével nem férhetnek hozzá. Ez a fő előnye a kulcs alapú hitelesítésnek, ha a biztonságról van szó. A cikk szerzője danielrm26[Neworder.box.sk], ezúton szeretném megköszönni neki, hogy publikálhattuk a cikkét. Köszönet illeti még Destiny-t a fordításban nyújtott segítségéért.
A cikk eredetije a http://www.remote.hu/articles.php?id=18&page=1 URL-en volt elérhető 2007. szeptemberében. Ezen dokumentum a cikk szerzőjének Gazdag Viktor [
[email protected]] engedélyével készült. 5