OAuth2: Miért?
Amikor Tatu Ylönen 1995-ben feltalálta az SSH-t a legtöbb terminál 80x25 karakter méretű volt és a Netscape Navigator egy éves születésnapját ünnepelte. A webes single sign-on rendszerek még a láthatáron sem voltak. Az SSH protokoll természetesen fejlődött az évek alatt, de a legfrissebb RFC is van vagy 10 éves.
Hagyományosan a nagyobb cégek (pl. telkok) a tűzfalaikra és az azok által izolált hálózati szegmensekre támaszkodtak az SSH hozzáférés bekorlátozására az Internet felől. Néhány helyen ugyan implementáltak központi azonosítást pl. LDAP segítségével vagy konfiguráció-menedszmenttel, de ez inkább a kivétel mintsem szabály. A legtöbb helyen csak akkor került implementálásra, ha valamilyen külső szabály (pl. PCI-DSS) megkövetelte.
Az elmúlt években azonban már a nagyobb cégek is kimozdultak a saját, jól ellenőrzött hálózati környezetükből és lépéseket tettek a felhők felé, amivel együtt a hozzáférés-korlátozás nagyobb kihívást kezdett jelenteni. Maga a hozzáférés-kezelés természetesen nem újkeletű probléma, így pl. a SAML mint SSO megoldás is több, mint 15 éves múltra tekint vissza. A születési korának megfelelően persze a SAML egy XML szörnyetek, amit ember legyen a talpán aki hiba nélkül implementál.
Az utóbbi időben az OpenID Connect (OIDC), mint az OAuth2 kiterjesztése, egyre nagyobb teret nyert. (Ez nem összekeverendő az OpenID-val, a kettő teljesen más.) Mára már a Microsoft Active Directory Federation Services is támogatja a SAML 2.0 mellett, és akár a Kuberneteshez is használhatjuk felhasználói azonosításra.
Egy dolog azonban fájóan hiányzik: az SSH. Az a protokoll, amivel a Kubernetes alatti, vagy éppen "hagyományos" szolgáltatásainkat futtató szerverekhez hozzáférünk.
A GSSAPI természetesen megoldást jelenthet, ha a gépünk egy Windows Domain tagja, de a Bring Your Own Device korában ez talán egy picit túlhaladott.
OAuth2: Hogyan?
OK, szóval már nem 1995-öt írunk, hogyan vesszük rá az SSH-t, hogy böngészőn keresztül autentikáljon?
A dolog nyitja a keyboard-interactive autentikáció, ami az RFC 4256-ban került szabványosításra. Ezt az azonosítási megoldást szinte minden SSH kliens támogatja és lehetővé teszi, hogy az SSH szerver egy kérdés-listát küldjön a kliensnek, amit a felhasználónak meg kell válaszolnia. Ezen felül a szerver küldhet egy utasítás-szöveget is, amelyet arra tudunk felhasználni (abuzálni), hogy megjelenítsük a felhasználónak az OAuth2 azonosítás linkjét.
Innentől viszonylag egyszerű a játék: az első opció az un. authorization code flow, amelyben a felhasználó bejelentkezik a böngészőjében, majd egy kódot vissza kell másolnia az SSH konzolba. A kód alapján a szerver ezek után lekérdezi a felhasználó adatait. A demóért lásd ezt a 17 másodperces videót.
A mások megoldás a device code flow, ahol a usernek a link mellett egy kódot jelenítünk meg, amelyet a linkre kattintva meg kell adnia. Itt a kliensnek az utasítás-szöveg mellé nem mellékelünk kérdéseket, hanem a szerver a visszaigazoló üzenet után elkezdi kérdezgetni az OAuth2 szervert, hogy a folyamat véget ért-e már, majd amint vége, a felhasználói adatok lekérdezése után beengedi a felhasználót. A demót ebben a 25 másodperces videóban láthatod.
Az utóbbi felkínálná magát egy QR kód megjelenítésére is, ezt azonban az OpenSSH nem támogatja, mivel elvágja az utasítás szövegét 255 karakter után és az US-ASCII-n kívül más karaktereket nem is engedélyez.
Kliens támogatás
Jelen post írásakor a következőket tapasztaltuk:
- Az OpenSSH korlátozza az utasítás mező hosszát 255 karakterre és nem támogatja az UTF-8 karaktereket.
- A PuTTY megmutatja a linket, de azt 78 karakter után eltöri. Ezt jeleztük a fejlesztőknek, de visszajelzést még nem kaptunk.
- A WinSCP megjeleníti az utasítás-szöveget, de az nem kattintható vagy másolható. A szoftver fejlesztője épített egy demo buildet ahol ezt javította, de ez még nem ment ki élesbe. (Ha a link kellően rövid, akkor ez nem jelent problémát.)
- A Filezilla a PuTTY-hoz hasonlóan eltöri a link szöveget 78 karakter után, valamint duplázza az & karaktert. Ezt a nightly buildben javították. Ezen felül nem jeleníti meg a device flow-ban a kérdések nélkül küldött instrukciós szöveget.
- A Termius nem jeleníti meg az utasítás szövegét a mobil verzióban, valamint nem jelölhető vagy kattintható a szöveg a desktop verzióban. Ezt jeleztük nekik és továbbították a fejlesztőknek.
- A Bitvise nem teszi kijelölhetővé vagy kattinthatóvá a linket. Ezt jeleztük és bugként kezelik.
- A JuiceSSH egyáltalán nem jeleníti meg az instrukciós szöveget Androidon. Ezt jeleztük, de visszajelzést nem kaptunk.
Mikor?
Hamarosan. A ContainerSSH-ban már működik egy igen-igen házitákolt verzió, de ezt még csiszolni kell. Mivel felderítetlen vizeken evezünk a release dátum bizonytalan, és szeretnénk megvárni amíg legalább néhány közkedvelt SSH kliens teljeskörűen támogatja ezt a funkcionalitást.
Ezúton is köszönetet szeretnénk mondani mindazoknak, akik ötletekkel, javaslatokkal és teszteléssel támogatják a projektet. Ez a blog post az angol nyelvű ContainerSSH post magyar fordítása.
- janoszen blogja
- A hozzászóláshoz be kell jelentkezni
Hozzászólások
QR kodra alternativa: https://zxing.org/w/chart?cht=qr&chs=350x350&chld=L&choe=UTF-8&chl=http…
SSH kliens amit meg erdemes lenne tesztelnetek: MobaXterm. Ez alapvetoen egy X szerverkent hirdeti magat, de valojaban egy nagyon okos, profilokat is kezelni tudo OpenSSH/SFTP kliens Windowsra (ami egyebkent mellesleg X szerver is).
Illetve a linkhossz problemara nem lehetne megoldas egy goo.gl -szeru linkrovidito hasznalat?
- A hozzászóláshoz be kell jelentkezni
A linkelt QR kód link hogy oldja meg azt a problémát, hogy nem tudjuk a konzolba kirajzolni mert nincs elég karakter? QR kódot renderelni mi is tudunk, csak nincs mivel. :)
MobaXterm: a fedél alatt ránézésre OpenSSH-t használ.
Linkhossz: de, ez lesz a megoldás, csak nem publikus linkrövidítővel. Az picit security issue lenne. :)
- A hozzászóláshoz be kell jelentkezni
OK, szóval már nem 1995-öt írunk, hogyan vesszük rá az SSH-t, hogy böngészőn keresztül autentikáljon?
Könnyen lehet, hogy nem értem kellő mélységben a problémát, de a fenti kérdésedet tippre valakik már megoldották, amikor mindenféle webes terminal-t faragtak a GUI-kra (pl freenas).
"The only valid measurement of code quality: WTFs/min"
- A hozzászóláshoz be kell jelentkezni
Persze, egy webes terminál ezt mind megoldja, de nem tudod használni a már meglevő SSH-s eszközeidet. A cél az, hogy a klasszikus SSH klienseddel be tudj lépni és ennek ellenére OAuth2-n autholni.
- A hozzászóláshoz be kell jelentkezni
A webes terminál is valahogyan authentikál, mert nem a login promptot kapod meg, hanem már a bejelentkezett állapotot.
Erre gondoltam, hogy érdemes megnézni miként csinálja...
"The only valid measurement of code quality: WTFs/min"
- A hozzászóláshoz be kell jelentkezni
Ha megnézed pl. a Teleport nevű SSH szervert, ők egy saját SSH klienst építettek, ami HTTP-n autentikál, majd egy rövid lejáratú átmeneti tokennel jelentkezik be az SSH sessionbe. Ezt nem szeretnénk, a cél az, hogy egy normál SSH klienssel be tudj jelentkezni.
- A hozzászóláshoz be kell jelentkezni
Raadasul tobbfele webes terminal van, van amelyik szerver oldalon nyit egy pty-t, amibe behivja az aktualis paraszt login shelljet (egy getent-tel lekerdezi), es ennek a kimenetet kommunikalja a klienssel. Nem minden webes terminal epit SSH kapcsolatokat ki. Ugy konnyu authentikalni.
Itt tenyleg az a problema, hogy az SSH-t viszonylag nehez osszehozni kulso authentikacios forrasokkal, a legtobbszor a PAM-on keresztul huznak be dolgokat, de az az Oauth2 eseten nem jarhato ut.
- A hozzászóláshoz be kell jelentkezni
...de az az Oauth2 eseten nem jarhato ut.
Ez igy nem egeszen igaz, a PAM tud keyboard-interactive autentikaciot, igy az OAuth2 is jarhato ut valamennyire. Lasd pl ezt vagy ezt a projektet. Az mas kerdes, hogy ezek csak OIDC-t tamogatnak es ranezesre csak egyetlen use case-re keszultek, vagyis nem biztos, hogy egy prod kornyezetben hasznalnam,
- A hozzászóláshoz be kell jelentkezni
A mások megoldás a device code flow, ahol a usernek a link mellett egy kódot jelenítünk meg, amelyet a linkre kattintva meg kell adnia.
Biztos én nem értek valamit, de ha a linket és a kódot is te generálod, akkor miért nem adod át a kódot a linkben, pl. egy query paraméter formájában? Nem látom mitől jobb, ha a kódot külön kell megadni.
- A hozzászóláshoz be kell jelentkezni
A kódot a device flow esetén az OAuth2 szerver generálja amit az SSH szerver lekéri és kiadja a usernek. A usernek a kódot be kell adnia az OAuth2 szerver által adott oldalon. Azaz nem tudom átadni a kódot, hiszen pont az a lényege, hogy a usernek interakcióba kell lépnie a szerverrel.
- A hozzászóláshoz be kell jelentkezni
De önmagában a link megnyitása és az ezzel járó authentikáció miért nem elég interakció? Ha a link egyedi, akkor már úgyis tudod, hogy melyik ssh sessiont indította az authentikált user, mert csak úgy nyithatta meg a linket.
Másként megfogalmazva, a link és a kód ugyanazon a csatornán érkezik (ssh session) és ugyanazon a csatornán keresztül is jut vissza a szerverhez (authentikált https session), vagyis szerintem a user feleslegesen van dolgoztatva a kóddal.
- A hozzászóláshoz be kell jelentkezni
Ez nem egy olyan dolog, amit én tudok befolyásolni, ezt az OAuth2-ben szabványosították. Ha jól értettem az eredeti célt, itt az a vágy, hogy az autentikáció akkor is működjön, ha a bejelentkeztetni kívánt eszköz és a jóváhagyó eszköz között nincs közvetlen hálózati kapcsolat. Így például egy okos TV megjeleníthetné a relatíve rövid URL-t, amit a telefonodon begépelsz és ott beütöd a kódot, jóváhagyva a bejelentkezést.
- A hozzászóláshoz be kell jelentkezni
Azt hiszem megvan mit ertettem félre, úgy gondoltam a kódot te generálod amivel azonosítod az ssh sessiont, illetve az authentikáció után is egy saját szolgáltatás fut, ami bekéri a kódot és átadja az adatokat az ssh szervernek. De ha jól értem itt az ssh szerver közvetlenül kommunikál az OAuth2 szerverrel, nem fut saját szolgáltatás https-en.
- A hozzászóláshoz be kell jelentkezni
Igen, ez így van, az SSH szerver kommunikál az OAuth2 szerverrel, majd elküldi a usert azonosítani az OAuth2 szerverhez és a háttérben kérdezgeti a szervert, hogy készen van-e.
A normál Authorization Code Flow-hoz kell a visszatéréskor egy HTTP szerver, de kizárólag a visszatérő kód megjelenítéséhez.
- A hozzászóláshoz be kell jelentkezni
sub
- A hozzászóláshoz be kell jelentkezni
Kár, hogy az ilyen szakmai, magyar (ld. Hungarian Unix Portal), kifejezetten érdekes, új technológiát és innovációt tartalmazó hírek nem érnek címlapot. Pedig ez mindannyiunk érdeke lenne... Helyette a politikai hőzöngésre és kókemény odamondogatásra van idő a főszerk részéről, meg totálisan offtopik szavazások kipakolgatása...
Ami a projektet illeti: Továbbra is csak azt tudom mondani, hogy nagyon tetszik, teljesen életszerű a problémafelvetés. Remélem meggazdagszol belőle, de legalább részlegvezető leszel majd a Red Hatnél :D
- A hozzászóláshoz be kell jelentkezni
Pedig hát nem egy rocket science
- cikként beküldeni
- ha blog lett, egy levelet dobni, hogy emeljem ki
20 másiknak sikerült! ;)
(Mielőtt nekiállsz erőlködni... Ne tedd! Számtalan példa volt arra, hogy blogbejegyzést kiemeltem a főoldalra.)
trey @ gépház
- A hozzászóláshoz be kell jelentkezni
Köszi, de ezt szándékosan nem küldtem be a nyitólapra. A releasekről szóló híreket beküldöm, de ez még kezdeti stádiumban van. Ha megjelenik a 0.5 ezzel a feature-el belinkelem ezt a postot is.
Ami a meggazdagodást illeti, nem szeretnék, mert annak sajnos velejárója a mai ismert open source üzleti modellek mellett, hogy valahol el kell vennem a projektből. A Red Hat managereimnek viszont tetszik a projekt. :)
- A hozzászóláshoz be kell jelentkezni