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 |
| — | 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.
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 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.
- Nincs megengedő átcsúszás egy olyan kapun, amit kötelezőnek nyilvánítottál.
Bekapcsolt
_requiredkapcsolóval a hiányzó címtár vagy a hiányzó csoportnév olyan elutasítás, ami megnevezi, mi hiányzik — nem nyitott ajtó. - Nincs olyan kitolt másolat, ami rekordnak számítana. Az auditnapló egy
lokális, csak hozzáfűzhető fájl, amit egy SIEM vagy naplószállító olvas. Egy
opt-in syslog-másolat (
audit.yaml:syslog) minden bejegyzést továbbíthat, de a sikeres küldés sosem teljesíti az audit-garanciát — a lemezen lévő fájl a rekord, és az auditnapló-séma az a szerződés, ami ellen fel kell dolgozni.