Identitások, csoportok és zárolás

Kinek gondol az átjáró, és melyik csoport melyik ajtót nyitja — a hozzáférési modellnek az a része, amin az SSH és a Web Access osztozik. Hogy azután egy-egy képesség mit enged, a saját lapján áll: SSH-policy és jóváhagyás a célgépen futó parancsokra, és Web Access-policy a webes konzolok kéréseire.

Identitások

Egy operátor egy címtár-bejegyzés. Ha van ldap.yaml, az átjáró a saját csak-olvasó szolgáltatásfiókjával kötődik a címtárhoz (bind_dn, bind_password), és a base_dn alatt keres a (<user_attr>=<username>) szűrővel. A megtalált bejegyzésről pontosan négy attribútumot olvas le:

Ahogy az ISG hívja ldap.yaml kulcs Alapértelmezett attribútum Mire szolgál
Felhasználónév user_attr uid A bejelentkezési név, és az --as principal, ha az egy személyt nevez meg
Szerepkör role_attr employeeType Szerepkörre szűkített policy-szabályok (rules[].roles)
Megjelenítendő név display_name_attr cn Az admin felület; ha üres, a felhasználónévre esik vissza
E-mail — mail A többfaktoros kód kézbesítése

A csoporttagság a csoport-bejegyzésekből olvasódik, nem a felhasználóról. Egy második keresés fut a group_base_dn alatt a (member=<the user entry's DN>) szűrővel, és minden visszakapott csoport cn-je a felhasználó egyik csoportja. Az a címtár tehát, amelyik a tagságot csak a felhasználó oldalán fejezi ki (memberOf és semmi más), csoport nélküli felhasználót fog feloldani — és az alábbi csoportalapú kapuk mindegyike nem-tagként fogja kezelni.

A címtár felé a kapcsolat titkosított, vagy az átjáró nem indul el. Két titok megy át rajta — a szolgáltatásfiók saját bind_password-je, és az admin felület minden bejelentkezésénél az operátor jelszava —, ezért a transzport indulásnál meghozott, fail-closed döntés, nem preferencia:

ldap.yaml Transzport Eredmény
egy ldaps:// url (alap port 636) TLS a kapcsolat elejétől Rendben — ez a javasolt üzemmód
egy ldap:// url (389-es port) start_tls: true-val StartTLS, minden bind és keresés előtt Rendben
egy ldap:// url egyik kulcs nélkül — az isg serve nem indul el
egy ldap:// url allow_plaintext: true-val Nincs Elindul; az isg system check WARN-t ad

A javaslatnak van egy címtár-oldali fele, amit az átjáró nem tud kikényszeríteni: az a címtár, amelyik a titkosítatlan portján továbbra is válaszol, ezt a transzportot a hálózaton bárki másnak is elérhetővé hagyja — bármit is mond az átjáró saját ldap.yaml-ja. A referencia-telepítés ezért a 636-ot ajánlja ki a flottának, a 389-et pedig csak a címtár-hoszton belülről hagyja elérhetőnek, azoknak a komponenseknek, amelyek ott futnak, és még nincs saját TLS-útjuk.

A StartTLS, ha egyszer kérték, kötelező: ha a szerver nem tudja, vagy a kézfogás bukik, az kapcsolódási hiba — nincs visszaesés titkosítatlan kapcsolatra, és egy ilyen bukás a directory_error osztályba esik, sosem a rossz-jelszó számlálókba. A tls_ca_file azt a PEM-et nevezi meg, amelyik a címtár tanúsítványát kiadta; üresen hagyva a gép rendszer-trustja dönt. A várt név a url hostja, tehát egy IP-címet hordozó url-hez IP-SAN-os tanúsítvány kell — egy csak DNS-SAN-os megbukik a név-ellenőrzésen. A padló TLS 1.2, az ellenőrzés soha nem kerül kihagyásra, és nincs is olyan kulcs, amivel ki lehetne hagyni. Az ellentmondásokat elutasítja, nem csendben feloldja: ldaps:// és start_tls együtt, allow_plaintext bármelyikkel együtt, vagy tls_ca_file egy olyan kapcsolaton, ami nem hordoz TLS-t. Az isg system check az ldap.yaml sorában kimondja a transzportot, és a LDAP bind sorában a valódi kézfogást is megméri — a tanúsítvány lejáratával együtt.

A jelszót az adott felhasználóként végzett bind ellenőrzi, sosem egy hash elolvasása. A DN <user_attr>=<username>,<base_dn> alakban áll össze, tehát az a címtár, amelynek személy-bejegyzései nem közvetlenül a base_dn alatt ülnek, azt a konténert igényli base_dn-ként, amely alatt ténylegesen ülnek. Az üres felhasználónevet és az üres jelszót még minden hálózati hívás előtt elutasítja, mert egyes címtárak az üres jelszót anonim bindként fogadják el, és „igen"-t válaszolnának. Kétféle hibát szándékosan tart külön: a rossz jelszó rossz jelszó, az elérhetetlen címtár pedig directory_error — csak az előbbi számít bele az mfa.yaml kizárási számlálóiba.

Egy operátor az identity provideren át is érkezhet. Ha van sso.yaml, az admin felület belépő oldala a szervezet identity providerét is kínálja — alapból OIDC-vel, vagy protocol: saml mellett SAML 2.0-val, ami csak a webes belépést szolgálja (a parancssor ilyenkor jelszó és az ISG második faktora marad). Amit a provider visszaad, az egy felhasználónév: OIDC-nél a username_claim értéke (alapból a preferred_username), SAML-nál a saml_username_attribute attribútum értéke. Ez az érték keresőkulcs, nem identitás: a címtárnak pontosan úgy kell feloldania, ahogy egy begépelt felhasználónevet old fel, és az a név, amit a címtár nem ismer, not_in_directory okkal utasítódik el. A szerepkör, a csoportok és az alábbi kapuk mindegyike a címtárból jön, sosem egy claimből vagy egy assertion-attribútumból. A második faktor alapból mfa: local — ugyanaz a kihívás, mint egy jelszó után —, vagy mfa: idp, ahol az identity provider saját állítása elégíti ki: OIDC-nél az id_token amr vagy acr claimje, SAML-nál a saml_idp_mfa_authn_context allow-listán szereplő AuthnContextClassRef. Az az OIDC-token, amelyik egyiket sem állítja, a helyi kihívásra esik vissza (local_fallback). Nincs olyan beállítás, ami második faktor nélkül engedne munkamenethez. OIDC-n a kijelentkezés mindkét irányban működik: rp_logout: on mellett az admin felületről való kilépés az identity provider munkamenetét is zárja (a böngészőt a provider end_session_endpoint-jára adja át), a providernél történő kilépés — vagy ha a provider kilépteti a felhasználót — pedig az admin felület munkamenetét zárja, OpenID Connect Back-Channel Logouttal. Egyik sem nyúl futó SSH-munkamenethez; SAML-lal a kijelentkezés csak az átjárón történik.

Címtár nélkül a users.json az identitásforrás. Felhasználónként egy szerepkört, egy e-mail-címet és egy csoportlistát hordoz, és ennyi elég az átjáró üzemeltetéséhez. Amire nem képes, az az, hogy egy csoport-állítást ellenőrizhetővé tegyen: az a kérés, amelynek a csoportjai ebből a fájlból jöttek, nem-címtárból-származóként van megjelölve, és minden csoportot követelő hozzáférési szabály elutasít ahelyett, hogy közelítene — a rögzített ok group_unverifiable. Az az LDAP-kapu, amelyik a tartalék fájlon mindenkit átenged, nem kapu.

Honnan jön az identitás: négy belépési pont, mind ugyanazt a felhasználónevet oldja fel, a címtár-ág és a users.json-ág, és hogy a szerepkör, a csoportok és az e-mail-cím mit döntenek el

Balról jobbra olvasd. A bal oszlop az, amire egy front támaszkodhat, mielőtt a címtártól bármit is kérdezne — és mindegyik ugyanarra szűkül: egy felhasználónévre. A középen álló két ág az egyetlen két létező válasz, a jobb oszlop pedig az, amiért a különbség számít: egy csoportlista pontosan annyit ér, amennyit a forrása. Egy aszimmetria megéri a keresést, a jobb alsó sarokban: a hívó saját identitása visszaeshet a users.json-ra, a --as alanyáé soha.

A második faktor külön ágrendszer, amiről az mfa.yaml és az sso.yaml dönt, nem az identitásforrás. Mégis ebbe a szakaszba tartozik, mert amit elintéz, az továbbra is az identitás: azután fut, hogy a címtár válaszolt, és azelőtt, hogy a következő szakasz bármelyik kapuja kiértékelődne.

A második faktor ágai: az SSO-kérdés, az mfa_mode három értéke, hol él a hitelesítő titok, mi számít helyes válasznak, és a zárolás két dimenziója

A függőleges az a sorrend, amiben a daemon kérdez, és az egyetlen ág, amelyik kilép belőle, fölül van: egy szolgáltató kielégítheti ezt a faktort, megszüntetni soha nem tudja. Alatta az mfa.yaml dönti el azt is, hogy mit kérdez, és azt is, hogy egy hitelesítő titok hol él — ennek az átjárónak a saját lemezén, vagy az OpenBaóban. Az utolsó sor az, ami akkor történik, ha a válaszok rendre rosszak, és hogy a közös számláló-tár kiesése mit tesz ezzel a védelemmel.

Az átjáró saját fiókjai

Minden, ami itt következik, az, amit a csomagolt unit és az isg system provision ténylegesen létrehoz; semmi nincs konvencióból következtetve.

Fiók vagy csoport Honnan jön Mire való
isg felhasználó A csomagolt isg-ui.service (User=isg) A daemon saját OS-identitása. A CA privát kulcsai 0600 módban az ő tulajdonában vannak, tehát emberi shell nem olvashatja őket
isg-operators csoport Ugyanaz a unit (Group=isg-operators) A daemon elsődleges csoportja, és ezt öröklik a futásidejű könyvtár meg a benne lévő socketek. Az operátorok ennek a csoportnak a tagjaként érik el a session.sock-ot és az issue.sock-ot
isg-gateway csoport isg system provision (felülírás: ISG_GATEWAY_SOCK_GROUP) Kizárólag az átjárós bejelentkezési socketet birtokolja. Szándékosan külön, hogy az SSH-belépési fiók sose lépjen be az isg-operators-ba, és így sose érje el a kiadási vagy a munkamenet-socketet
isg-login fiók isg system provision (felülírás: ISG_GATEWAY_LOGIN_ACCOUNT) Az a közös fiók, amiként az sshd ForceCommand-ja beengedi az embert, még mielőtt az ISG saját hitelesítése lefutna

Az isg system provision idempotens, és pontosan ennyit csinál: létrehozza a csoportot és a fiókot, és hozzáadja az isg-t az átjáró-csoporthoz. Sosem ír /etc/pam.d/-be vagy /etc/ssh/sshd_config.d/-be, és sosem indít újra szolgáltatást — a referencia-fájlokat a packaging/ hordozza, és egy adminisztrátor alkalmazza őket kézzel.

A célgépen az átjárónak nincs szüksége saját fiókra. Annak az OS-felhasználónak a nevében hitelesít, akit az operátor kért, tanúsítvánnyal. Hogy a célgépnek mire van szüksége, azt a Célgép-előkészítés írja le.

Szerepkörök és csoportok

Két különböző attribútum két különböző dolgot vezérel, és a kettő összekeverése a szokásos forrása annak, hogy „miért nem sült el az a szabály".

A szerepkör felhasználónként egyetlen sztring — a címtár role_attr értéke, vagy a users.json role mezője. A policy-szabályokat kapuzza: egy roles: listával bíró szabály csak azokra a felhasználókra vonatkozik, akiknek a szerepköre rajta van a listán, egy roles: lista nélküli szabály pedig mindenkire.

A csoporttagság azt kapuzza, hogy ki végezhet el egy műveletet egyáltalán. Minden kapu egy csoportnév az ldap.yaml-ban, és mindegyiknek van egy _required ikerpárja, ami a hiányzó csoportot vagy a hiányzó identitásforrást megengedő átcsúszásból kemény konfigurációs hibává változtatja:

Kapu Csoport-kulcs Fail-closed kapcsoló
Ki dönthet jóváhagyási kérésekről approver_group approver_group_required
Ki állíthatja vissza más többfaktoros regisztrációját mfa_reset_group mfa_reset_group_required
Ki futtathat CA-adminisztrációs műveletet (a kiállító socketen és a webUI-n) ca_admin_group ca_admin_group_required
Ki zárhatja le más munkamenetét (a webUI-n és az isg sessions close-zal), és ki mérheti újra a rendszerállapotot a webUI-n session_admin_group session_admin_group_required
Ki hívhatja a break-glasst breakglass_group breakglass_group_required

A break-glass az, amelyik a kapcsoló nélkül is zárva van: beállított breakglass_group hiányában mindenkitől meg van tagadva. Nincs olyan olvasata a „nincs beállítva"-nak, amitől megengedő lenne.

Mit mutat a webUI

A webUI a szerveren dönti el, hogy egy belépett felhasználó mit láthat, nem csak a menü kínálatát. A szintjén kívüli oldal 403-at ad, üzenettel, és annak a műveletnek a gombja, amit nem végezhet el, meg sem jelenik. Mindenki a legmagasabb illeszkedő szintet kapja:

Szint Ki Mit lát
Admin A session_admin_group vagy a ca_admin_group tagja. Ha egyik csoport sincs beállítva, mindenki Mindent. Az egyes írás-gombok a saját kapujukat követik
Auditor Az auditor_group tagja. Beállítatlan kulcsnál senki Minden oldalt és minden munkamenetet, csak olvasva, írás-gomb nélkül
Jóváhagyó Az approver_group tagja. Beállítatlan kulcsnál mindenki A saját munkameneteit és kérelmeit, plusz minden függő kérelmet a döntés-gombokkal. Mások átiratát nem
Felhasználó Mindenki más Alkalmazásaim, Profil, és a saját munkamenetei átirattal és felvétellel

A saját munkamenetét bárki lezárhatja, a webUI-n és az isg sessions close-zal is; a SESSION_CLOSED bejegyzés megnevezi, ki zárta le (closed_by, via). Más munkamenetének lezárásához session_admin_group kell, és az elutasítás SESSION_ADMIN_DENIED bejegyzést kap (via: webui vagy via: cli). Ha a szint nem állapítható meg — a címtár nem válaszol, vagy egy _required kapunak nincs csoportja —, a felhasználó a Felhasználó szintet kapja.

Felhasználó vagy app zárolása

Ha egy fiókot vagy egy alkalmazást azonnal le kell állítani, egy adminisztrátor (session_admin_group) zárolja — a webUI Zárolások oldalán, vagy az isg lock add paranccsal (--user vagy --app, kötelező --reason, és --for egy magától lejáró zárra). A felhasználónevet az identitás-forrás ellenőrzi: ismeretlen névre a zárolás elutasít, mert egy elgépelt név senkit nem zárna ki, hacsak nem kényszerítik ki (--force, vagy a Zárolások oldal jelölője); ha az identitás-forrás nem érhető el, a zár létrejön, és az üzenet jelzi, hogy a név ellenőrizetlen. A felhasználó zárolása a felhasználó minden futó SSH- és Web Access-munkamenetét lezárja minden brókeren, és a webUI-belépéseit is törli; az app zárolása az alkalmazás minden munkamenetét lezárja. Amíg a zár él, a gateway, a webUI és a Web Access a felhasználót (vagy az appot) bármely munkamenet indulása előtt elutasítja. Az isg lock rm feloldja, az isg lock list listázza a zárakat, a lejártakat jelölve. Az auditnaplóban LOCK_CREATED és LOCK_REMOVED áll, a lezárt munkamenetek oka locked. A zár miatt kiléptetett böngésző a belépő oldalon egy általános „a hozzáférésed felfüggesztve" üzenetet lát, indok nélkül. Ha a notify.yaml lock_mail blokkja be van kapcsolva, a session_admin_group tagjai minden zároláskor és feloldáskor e-mailt kapnak (ki, mit, miért, meddig), a mail_locked_user mellett pedig a zárolt felhasználó is kap egy általános levelet.

Amit az átjáró nem nyújt

Ezek mért hiányok, felsorolva, hogy egy telepítést ne ezek egyikére tervezzenek. Ami egy képességé, az a saját lapján áll: SSH és Web Access.