Architektúra
Az Inshipia Security Gateway (ISG) egy daemon, az isg serve. Az operátorok
lokális socketen vagy böngészőn át érik el; ő a célgépeket SSH-n éri el, a Web
Access-szel pedig a webes admin-konzolokat HTTP(S)-en. Minden
más — az identitásforrás, a levéltovábbító, az opcionális háttértárak — erről a
daemonról lóg le, és elhagyható.
Egy gépen egy daemon a szállított alapértelmezés, és minden, ami itt következik, ezt írja le. Egyszerre több daemon is kiszolgálhatja ugyanazt az állományt, úgy, hogy az állapotukon osztoznak, nem a munkát osztják fel; hogy ez min változtat, azt a Több átjáró üzemeltetése fejti ki, és ezen az oldalon semmi más nem feltételezi sem az egyiket, sem a másikat.
Komponensek
Az átjáró az egyetlen dolog, ami hitelesítő adatot tart egy célgéphez, és
mindegyiket percekig tartja. Egy operátor isg connect-je nem nyit maga
SSH-kapcsolatot: átadja a kérést a daemonnak egy lokális UNIX socketen, a daemon
pedig a kernelből állapítja meg, ki kérdez — nem abból, amit a kliens állít
magáról. A böngésző ugyanazt a daemont éri el a saját TCP-portján az admin
felületért és a jóváhagyási képernyőkért.
A Web Access ugyanez az átjáró a webes admin-konzolokhoz — BMC-felületekhez,
monitoring- és tároló-konzolokhoz. A böngésző az átjáró alkalmazás-listenerét
(apps.yaml: listen) éri el, az alkalmazás saját hosztnevén; az átjáró a
felhasználót az alkalmazás csoportjaihoz, jóváhagyásához és az incidens-zárakhoz
méri, minden kérést kiértékel a policy.yaml http_rules szabályai szerint,
rögzíti a munkamenet átiratában, és csak utána továbbítja a konzolnak
(upstream). A konzol egy aláírt assertionből tudja meg, ki a felhasználó
(identity: jwt), semmiből (identity: none), vagy sehogy, mert az átjáró egy
közös fiókkal lép be az OpenBao-ból (identity: credential — fejléc, basic
belépés, vagy a konzol saját belépő űrlapja kind: form-mal). Űrlapos
belépésnél a konzol munkamenet-sütijei az átjáró memóriájában maradnak: a
böngészőnél csak az átjáró saját alkalmazás-sütije van.
Egy mode: isolated alkalmazás egyáltalán nem a felhasználó böngészőjében
nyílik meg. Az átjáró egy izolációs (RBI) hoszton indít a munkamenetnek egy
eldobható böngészőt, a felhasználónak csak a képét küldi Guacamole-protokollon
(guacd, rbi.yaml: agents), és visszaveszi a bemenetét. Az izolált böngésző
csak az átjárón át éri el a konzolt. Az RBI-agent kölcsönös TLS-sel a brókerek
megújító listeneréhez kapcsolódik (rbi-agent.yaml: brokers): a parancsai, a
böngésző forgalma és a felvétel feltöltése mind ezen megy, és az RBI-hoszton
nincs hitelesítő adat és tároló-kulcs.
Három rendszer közönséges függőség, nem opció: a célgépek (SSH), az
identitásforrás, ami egy operátort egy címtár-identitássá és a csoporttagságaivá
old fel, és — ha a többfaktoros kódok e-mailben mennek, nem TOTP-vel — egy
levéltovábbító. Az auditnapló lokális fájl, amit egy SIEM vagy naplószállító
olvas; egy opt-in syslog-másolat (audit.yaml: syslog) minden bejegyzést ki is
tolhat egy SIEM-be, de a fájl marad az audit-of-record mindkét esetben.
Egy negyedik külső rendszer opcionális, és csak a belépést adja: egy OIDC
identity provider, az sso.yaml-ban megnevezve, az admin felület böngészős
belépése és az átjárós bejelentkezés device flow-ja mögött. Az identitást és a
jogosultságot sosem ő adja — a név, amit visszaad, keresőkulcs, és a címtár-kapu
pontosan úgy áll, mint egy jelszavas belépésnél.
A szaggatottal rajzolt három háttértár ki van kapcsolva, hacsak egy konfigurációs fájl meg nem nevezi őket: egy OpenBao-példány a tanúsítvány-aláíróként a beépített helyett, PostgreSQL a munkamenet- és jóváhagyás-rekordok tárolójaként a lokális könyvtár helyett, és egy S3-kompatibilis objektumtár a munkamenet-felvételek archívumaként.
A szaggatott vonal egyetlen átjáró esetén jelent opcionálist. Többnél nem az: a PostgreSQL az, amin az átjárók osztoznak, az OpenBao pedig kötelezővé válik, nem csak elérhetővé. Az az átjáró, aminek neve van és PostgreSQL-t használ, de OpenBao-t nem, nem hajlandó elindulni — lásd Több átjáró üzemeltetése.
Kapcsolódás
Egy connect-et a daemon rögzített sorrendben dönt el, és pont a sorrend a lényeg.
Elsőként a hívó identitása áll össze, a socket-kapcsolat kernel által tanúsított
hitelesítő adataiból, és a címtár ellen oldódik fel. Ezután fut a két
nem-interaktív hozzáférési kapu — a ca.yaml human_access-e, majd a
hostgroup.yaml hosztonkénti megkövetelt csoportja —, hogy egy olyan kérés,
amit soha nem engedtek volna át, ne kerüljön az operátornak egy többfaktoros
kihívásába. Csak ezután megy ki a kihívás, és csak azután létezik egyáltalán
hitelesítő adat, hogy sikerült.
Egy parancs jóváhagyása
Egy munkamenet minden parancsa önmagában értékelődik ki, a policy-fájl ellen,
ahogy az abban a pillanatban szól — a policy.yaml parancsonként töltődik be,
tehát egy szerkesztett policy a következő parancsnál lép életbe, az átjáró és a
munkamenet újraindítása nélkül. Egy szabály vagy kereken megtagadja a parancsot,
vagy egy második személyhez küldi. Az a parancs, ami semmire nem illeszkedik,
lefut.
A beépített tiltó szabályok minden policy részei, beleértve egy olyan átjáró
policyját is, amelynek egyáltalán nincs policy.yaml-ja, és egy felhasználói
szabály nem írhatja felül őket: a fájl saját szabályai a beépített tiltások és a
beépített jóváhagyási szabályok között értékelődnek ki, és az első találat nyer.
Egy webes konzol megnyitása
A felhasználó az admin felületen az Alkalmazásaim lapot nyitja meg — ez csak
azokat az alkalmazásokat mutatja, amelyeket a csoportjai engednek —, és az
alkalmazás linkjét követi. Az alkalmazás-hoszton még nincs munkamenete, ezért az
a böngészőt egy egyszeri átadásra küldi az admin felülethez: ott a felhasználó
már be van lépve, és az átadás újra megnézi a csoportokat, az incidens-zárakat
és a licencet. Egy require_approval-os alkalmazás előbb időtartamot kér, és
egy második személy döntésére vár (approval_mode: four_eyes), vagy indoklásra
azonnal megnyílik (approval_mode: self); az ablaknak mindkét esetben vége van,
és vele zárul az alkalmazás-munkamenet is. Onnantól minden kérésről külön
születik döntés: egy incidens-zár, egy elveszett csoport vagy egy http_rules
tiltás a konzol előtt elutasítja, egy step_up szabály friss második faktort
kér, és minden kérés — engedett vagy sem — egy sor a munkamenet átiratában.
Állapot
Több átjáró üzemeltetése
Több átjáró is kiszolgálhatja egyszerre ugyanazt az állományt. Egyenrangúak: mindegyik minden szerepet visz — admin felület, munkamenet-brókerezés, CA-műveletek, jóváhagyások —, és egyik sem tartalék. Attól egyetlen rendszer és nem több, hogy az állapotukon osztoznak.
Amit ez ad, az az, hogy egy átjáró elvesztése nem zárja be az ajtót: az operátorok tovább nyitnak munkameneteket az állva maradtakon keresztül. Amit nem ad, az az elveszett átjárón már futó munkamenetek túlélése. Egy élő munkamenet egy SSH-folyam és egy PTY azon a bizonyos gépen; ha a gép elmegy, a folyam vele megy, és az operátor új munkamenetet nyit egy társon keresztül. A rekord viszont túléli — egy állva maradt átjáró lezártnak jelöli a munkamenetet, nem hagyja nyitva —, tehát az audit-nyomvonalon nincs rés.
Három dolog hordozza ezt a közös állapotot, és két dolog lokális marad, akárhány átjáró van:
| Mi | Egy átjáró — lokálisan, a $ISG_HOME alatt |
Közös elrendezés | Kapcsoló |
|---|---|---|---|
| Munkamenet- és jóváhagyás-rekordok | sessions/, approvals/ |
PostgreSQL | storage.yaml: records.backend |
| Bróker-bérletek, kizárások, visszavonások, bejelentkezési állapot, átjáró-feladatok | rekord-családonként egy könyvtár | PostgreSQL — ugyanaz a tár, ugyanaz a kapcsoló | storage.yaml: records.backend |
| Lezárt munkamenetek felvételei és átiratai | recording-<SESSION-ID>.cast, transcript-<SESSION-ID>.jsonl |
S3-kompatibilis objektumtár | storage.yaml: recordings.backend |
| Az SSH tanúsítvány-aláíró | ca_key a ca/ alatt |
OpenBao — a privát kulcsot az átjáró soha nem nyitja meg és nem is kéri: egy seedelt másodlagoson egyáltalán nincs ca_key, csak a pinned ca_key.pub; az elsődleges őrzi a Bao-ba importált példányt |
ca.yaml: signer |
| Többfaktoros titkok | totp/ |
OpenBao (KV) | mfa.yaml: store |
| Az auditnapló | audit.log |
minden átjárón lokális, mindig | — |
| Az X.509 CA, a publikus tükör, az állapotgyökér bérlete, az esemény-kimenősor | ca/, pub/, serve.lease, ticket_outbox/ |
lokális, mindig | — |
A közös sorok bármelyikének helyében egy lokális könyvtár egy-átjárós
elrendezés, nem közös — és attól, hogy azt a könyvtárat hálózati fájlrendszerre
teszed, még nem lesz közös: a serve.lease rögzíti, melyik gép birtokolja az
állapotgyökeret, és egy másik gépen futó átjáró nem hajlandó elindulni rajta.
Minden átjáró saját nevet visel — a broker.yaml id-ja, egy-nyolc alfanumerikus
karakter —, és rábélyegzi minden munkamenet-rekordra és minden auditsorra, tehát
egy a közös tárból olvasott rekord megmondja, melyik átjáró állította elő. A
flottát az isg system brokers listázza.
A Fail-closed posztúra indulási elutasításai közül kettő ezért az elrendezésért van. Az első az, hogy egy névtelen átjáró nem csatlakozik olyan tárhoz, amit egy másik átjáró már használ. A második az, hogy annak az átjárónak, ami egyszerre nevezett és PostgreSQL-re mutat, az aláíráshoz és a többfaktoros titkokhoz is OpenBaót kell használnia. Az ok az, hogy az alternatívák külön-külön helyesek, és együtt csendesen hibásak: a beépített aláíró folyamatonként számolja a tanúsítvány-sorszámokat, tehát két átjáró ugyanazt a sorszámot adhatja ki két különböző tanúsítványra, és egy visszavonási lista onnantól nem egyetlen tanúsítványt nevez meg; egy pedig az egyik átjáró lemezére írt többfaktoros titok nem létezik a társain, tehát az az operátor, aki az egyiken regisztrált, a másikon nem tud bejelentkezni. Mindkét hiba messze jelentkezne az okától — egy visszavonásnál, ami nem harap, egy bejelentkezésnél, ami nem működik —, és ezért történik az ellenőrzés inkább induláskor.
Néhány dolog szándékosan lokális marad. Minden átjáró a saját auditnaplóját írja: a fájl szerződés szerint csak hozzáfűzhető, és egy közös író ezt a szerződést cserélné kényelemre. A flottaszintű nézet a sorok exportálásából áll össze, nem a fájl összeöntéséből. Az esemény-ticketek kimenő sora ugyanezért lokális: egy közös sornak közös rekord kellene, amire a munkát akaszthatja, egy visszavonásnak pedig nincs ilyenje. Az az átjáró tehát, ami leáll, a saját esemény-ticketjeit ott hagyja, amíg vissza nem tér — késés, nem veszteség, és az auditnapló fedezi a rést. A munkamenet-ticketek a fordított eset: azok a közös munkamenet-rekordról lógnak, tehát egy megszakadtat tizenöt perc múlva felvesz egy társ.
Az operátor szempontjából két következményt érdemes betervezni. Az admin felület a bejelentkezési állapotát a közös tárban tartja, tehát az átjárók ülhetnek egy név vagy egy terheléselosztó mögött, ragadós munkamenet nélkül. És egy célgép felé a szondázási ráta az átjárók számával szorzódik: az az időköz, ami megakadályozza, hogy a szondák kiváltsák a célgép kizárását, szándékosan átjárónként van kikényszerítve, mert terhelési tulajdonság, nem helyességi.
Flotta-topológia
A fentiek egyetlen átjárót írnak le. Egy éles környezet kis flotta, amit az Ansible playbookok telepítenek: az átjárók, és a gépek, amelyek a közös állapotukat, az identitásforrásukat és a monitorozásukat hordozzák. Ez a szakasz megnevezi ezeket a gépszerepeket, és hogy melyik melyik portot nyitja, kinek. Az átjáró saját portjai és socketjei lent maradnak, a Hálózat és portok alatt.
Egy tipikus környezet: két bróker, egy közös tár, egy címtár-hoszt, egy monitoring-hoszt és tetszőleges számú célgép.
Gépszerepek
| Szerep | Inventory-csoport | Mi fut rajta | Hány darab |
|---|---|---|---|
| Bróker | isg_brokers |
Maga az átjáró (isg_gateway, isg_broker_e1) és a break-glass napló-fogadó (isg_breakglass_receiver). Ha VIP van beállítva, azt az isg_keepalived tartja — a fő futás után települ, amikor minden bróker egészséges |
Kettő vagy több; az állapotot osztják meg, nem a munkát |
| Közös tár | isg_store |
PostgreSQL a munkamenet-rekordoknak, RustFS (S3) a felvételeknek, és OpenBao (isg_shared_store, isg_bao_init) |
Egy |
| Címtár-hoszt | isg_infra |
OpenLDAP, Keycloak és Mailpit (isg_directory). A Mailpit csak teszt-levélgyűjtő: SMTP-n fogadja a többfaktoros kódokat |
Egy |
| Monitoring-hoszt | isg_monitoring |
Prometheus és Grafana (isg_monitoring) |
Egy |
| Izolációs (RBI) hoszt | isg_rbi |
Az RBI-agent, a guacd és az eldobható böngésző-konténerek (isg_rbi) — csak ha egy alkalmazás mode: isolated |
Opcionális; egy vagy több |
| Célgép | isg_targets |
Az ügyfél szerverei. A playbookok tanúsítványos belépésre és break-glass hozzáférésre állítják be őket (isg_target_host, isg_breakglass_target); a host-tűzfaluk az ügyfél saját baseline-jánál marad |
Tetszőleges |
| Jump host | isg_jumphost |
Opcionális gép, ahonnan a tesztelők belépnek. A playbookja külön áll, és nem része az átjáró telepítésének | Opcionális |
| Vezérlő | — | Az Ansible-t futtató gép. Nem inventory-gép | Egy |
Minden bróker, tár-, címtár- és monitoring-hoszt megkapja a tűzfal-baseline-t
(isg_firewall) és a node exportert (isg_node_exporter) is. A célgépek
egyiket sem: azok az ügyfélé.
Szolgáltatás, port és forrás
Minden sor forrásonkénti tűzfal-szabály, amit a portot birtokló role nyit. Az üres forráslista semmit sem nyit — sosem azt jelenti, hogy „mindenkinek".
| Port | Hol | Ki nyitja | Forrás |
|---|---|---|---|
| 22 (SSH) | brókerek | isg_firewall |
isg_net_admin_sources és isg_net_user_sources — a brókeren a 22-es port az átjáró-belépés útja is |
| 22 (SSH) | tár, címtár, monitoring | isg_firewall |
isg_net_admin_sources |
| VRRP (112-es IP-protokoll) | brókerek | isg_firewall |
a másik bróker, csak ha az isg_vip_address be van állítva |
| 8765 (admin-nézet) | brókerek | isg_gateway |
isg_net_user_sources és a többi bróker (a flotta-szintű öndiagnosztikához) |
8444 (a Web Access alkalmazás-listenere, isg_apps_port) |
brókerek (és a VIP) | isg_gateway |
isg_net_user_sources — csak bekapcsolt Web Access mellett (isg_cfg_apps vagy egy dinamikus-app tartomány van megadva) |
| 8766 (tanúsítvány-megújítás, kölcsönös TLS) | brókerek | isg_gateway |
isg_net_target_sources, az RBI-hosztok (isg_rbi) és a többi bróker |
| 8767 (diagnosztika és metrikák) | brókerek | isg_broker_e1 (a diag.yaml listen kulcsából) |
isg_monitoring_host és a többi bróker |
| 9100 (node exporter) | minden flotta-gép | isg_node_exporter |
isg_monitoring_host |
| 5432 (PostgreSQL, munkamenet-rekordok) | tár | isg_shared_store |
a brókerek |
| 9000 (RustFS S3, felvételek) | tár | isg_shared_store |
a brókerek |
| 8200 (OpenBao) | tár | isg_shared_store |
a brókerek |
| 4822 (guacd, TLS) | RBI-hosztok | isg_rbi |
csak a brókerek; üres listánál a role nem nyitja meg a portot, és ezt kimondja |
| 636 (LDAP TLS-en) | címtár-hoszt | isg_directory |
a brókerek |
| 389 (LDAP, titkosítatlan) | címtár-hoszt | isg_directory |
a brókerek — csak az átmeneti fázisban; amint a címtár csak TLS-t beszél, a port nincs is publikálva |
| 1025 (SMTP, többfaktoros kódok) | címtár-hoszt | isg_directory |
a brókerek |
| 8443 (Keycloak HTTPS) | címtár-hoszt | isg_directory |
isg_net_user_sources és a brókerek (a böngésző, és a démon discovery- és kulcslekérése) |
| 8025 (Mailpit webes nézet) | címtár-hoszt | isg_directory |
isg_directory_firewall_admin_sources (alapból isg_net_admin_sources), és ha a Mailpit Web Access-alkalmazás, a brókerek (isg_directory_firewall_mail_ui_app_sources) |
| 3000 (Grafana) | monitoring-hoszt | isg_monitoring |
isg_monitoring_firewall_admin_sources (alapból isg_net_admin_sources), és ha a Grafana Web Access-alkalmazás, a brókerek (isg_monitoring_firewall_app_sources) — a referencia-környezet csak a brókereknek nyitja |
| 9091 (Prometheus) | monitoring-hoszt | isg_monitoring |
ugyanaz a két lista, mint a Grafanánál |
| 20514 (break-glass napló-fogadó, TCP syslog) | brókerek | isg_breakglass_receiver |
isg_net_target_sources — a break-glass sorokat a célgépek küldik. Itt az üres lista megállítja a futást: egy fogadó, amihez egyetlen sor sem érhet el, csak egy soha el nem múló figyelmeztetésként látszana |
A brókerről a célgépre menő SSH a célgép tűzfalán múlik, az pedig az ügyfélé. A
Grafana a saját gépén, localhost-on éri el a Prometheust, ahhoz nem kell
szabály.
Háló
A telepítésnek egyetlen hálózati bemenete van: négy érték és egy kapcsoló a környezet group-változói közt.
| Változó | Mit jelent |
|---|---|
isg_firewall_enabled |
Fut-e a tűzfal-baseline ebben a környezetben |
isg_net_admin_sources |
Az SSH és az admin-konzolok forrásai |
isg_net_user_sources |
A böngésző (admin-nézet, Keycloak) és a brókerek 22-es portján az átjáró-belépés forrásai |
isg_net_target_sources |
A célgépek, a tanúsítvány-megújításhoz és a break-glass naplóhoz |
isg_vip_address |
Ha meg van adva: a brókerek közt a VRRP engedélyezett, és ez az a cím, amit az isg_keepalived felállít |
Minden más cím az inventoryból jön: a brókerek címei és a monitoring-hoszt. A gépnevek bármilyen névfeloldón át feloldódhatnak, a role-ok által használt címek azonban nem függnek tőle: kimondva állnak az inventoryban. A host-cert IP-principálját a futás nem tudja a gépen felderíteni, és egy több hálózati lábú gépen az alapértelmezett cím nem feltétlenül az, amelyiken a bróker tárcsáz.
Hálózat és portok
A portok a szállított alapértelmezések; mindegyik vagy egy flag az isg serve-ön,
vagy egy kulcs egy konfigurációs fájlban. Az átjáró saját lokális socketjei velük
együtt vannak felsorolva, mert egy operátor szemszögéből ugyanolyan dolgok: ajtó
a daemonba. Ahol több átjáró fut, ott mindegyik a saját példányát köti be az
alábbi minden sorának.
| Irány | Port vagy útvonal | Protokoll | Mikor kell |
|---|---|---|---|
| Böngésző → átjáró | TCP 8765 (--bind 127.0.0.1, --port 8765) |
HTTPS, ha a CA inicializált; előtte sima HTTP | Mindig — az admin felület és a jóváhagyási képernyők |
| Böngésző → átjáró (Web Access) | TCP 8443 (apps.yaml: listen; a playbookok 8444-et állítanak) |
HTTPS, az apps.yaml tls_cert_file tanúsítványával (a webUI-ról kezelt alkalmazásokhoz *.<dynamic_apps_domain> SAN-nal) |
Csak ha az apps.yaml alkalmazást vagy dinamikus-app tartományt nevez meg |
| Megújító ügynök → átjáró | TCP 8766 (--ca-renew-bind 0.0.0.0, --ca-renew-port 8766; az ügynök az agent.yaml: ca_renew_url címet tárcsázza) |
HTTPS kölcsönös TLS-sel | Csak szolgáltatásfiók-tanúsítvány megújításához, és csak akkor indul el, ha a CA inicializált |
| Monitorozás → átjáró | TCP 127.0.0.1:8767 (diag.yaml: listen) |
HTTP — /healthz, /readyz, /metrics |
Csak ha a diag.yaml-ban enabled: true áll; egyébként semmilyen socket nem kötődik be |
| Operátori CLI → átjáró | /run/isg/session.sock (mód 0660) |
lokális UNIX socket | Mindig — ez a munkamenet-út |
| Operátori CLI → átjáró | /run/isg/issue.sock (mód 0600) |
lokális UNIX socket | Tanúsítvány-kiadás, MFA-regisztráció és -visszaállítás, jóváhagyási döntések, munkamenet lezárása |
| SSH-bejelentkezési fiók → átjáró | /run/isg/gateway.sock (mód 0660, isg-gateway csoport) |
lokális UNIX socket | Csak ha van konfigurált identitásforrás |
| Átjáró → célgép | TCP 22 | SSH | Mindig |
| Célgép → break-glass naplófogadó | breakglass.yaml: breakglass_log_target (a brókerek fogadója: TCP 20514, vagy egy SIEM) |
syslog, TCP-n, hacsak a breakglass_log_protocol nem udp |
Ha a break-glass továbbítás be van állítva: a célgépek break-glass belépési és parancs-nyoma |
| Átjáró → identitásforrás | az ldap.yaml url-jében álló port |
A javasolt üzemmód az LDAPS (ldaps://, 636); a StartTLS-es LDAP (start_tls: true, 389) ugyanilyen erős. Titkosítatlan kapcsolathoz az allow_plaintext: true kimondása kell, és enélkül a daemon nem is indul el — a címtár tehát a titkosítatlan portját ne is ajánlja ki a hálózat felé |
Ha van ldap.yaml |
| Átjáró → levéltovábbító | smtp.yaml: host, port |
SMTP, STARTTLS-sel ha tls: true |
Ha a többfaktoros kódok e-mailben mennek |
| Átjáró → OpenBao | vault.yaml: address |
HTTPS | Ha a ca.yaml-ban signer: vault áll, vagy az mfa.yaml-ban store: vault |
| Átjáró → PostgreSQL | a storage.yaml records.postgres.dsn_file kulcsa által megnevezett kapcsolati sztring |
PostgreSQL | Ha a records.backend értéke postgres |
| Átjáró → objektumtár | storage.yaml: recordings.s3.endpoint |
HTTPS (S3 API) | Ha a recordings.backend értéke s3 |
| Átjáró → SIEM | audit.yaml: syslog.address |
RFC 5424 syslog TCP-n, TLS-sel | Ha a syslog.enabled igaz — az auditnapló opt-in másolata, sosem maga a rekord |
| Átjáró → identity provider | sso.yaml: issuer (OIDC) vagy saml_idp_metadata_url (SAML) |
HTTPS (OIDC discovery, token- és device-végpont; a SAML IdP metaadata) | Ha az sso.yaml-ban enabled: true áll |
| Átjáró → webes konzol | apps.yaml: az alkalmazások upstream-je (apps[].upstream) |
HTTP vagy HTTPS (saját CA-hoz upstream_ca_file) |
Minden proxizott Web Access-kérésnél, és egy kind: form fiók átjáró általi belépésénél |
| Átjáró → OpenBao (Web Access-fiókok) | vault.yaml: address, út: <kv_mount>/data/<prefix>/<app>/<name> (a <prefix> az apps.yaml: credential_kv_prefix) |
HTTPS | Ha egy alkalmazás identity: credential-t használ; a bróker csak olvas |
| Átjáró → RBI-hoszt | rbi.yaml: agents[].guacd (TCP 4822) |
Guacamole-protokoll TLS-en, a szervert a guacd_ca_file ellenőrzi |
Csak ha egy alkalmazás mode: isolated: az izolált böngésző képe és a felhasználó bemenete |
| RBI-agent → átjáró | rbi-agent.yaml: brokers (TCP 8766, a megújító listener) |
HTTPS kölcsönös TLS-sel | Csak RBI-hoszton: az agent parancsai, az izolált böngésző forgalma a konzol felé (az átjárón át) és a felvétel feltöltése |
| Átjáró → Jira | jira.yaml: endpoint |
HTTPS (Jira REST API) | Ha a jira.yaml be van állítva, és nincs disabled: a munkamenet-ticketek |
| Átjáró → webhook | notify.yaml: webhook.url |
HTTPS, JSON POST | Ha a notify.yaml webhook-ot állít be: minden új jóváhagyási kérelem |
A fenti socket-útvonalak a rendszerszolgáltatás-elrendezéshez tartoznak. Ha az
XDG_RUNTIME_DIR be van állítva — felhasználónkénti daemon, jellemzően
kiértékelés közben —, a daemon helyette az
$XDG_RUNTIME_DIR/isg/<name>.sock-ot köti be, a CLI pedig előbb a
/run/isg/<name>.sock-ot keresi, és arra esik vissza.
E portok közül kettő alapból a hálózat felé néz, kettő pedig nem, és a különbség szándékos. Az admin felület a loopbackre köt, amíg ki nem szélesíted, a kiszélesítés pedig elutasításra kerül, ha nincs a helyén a hitelesítés és a TLS is (lásd lentebb: Fail-closed posztúra). A megújítási végpont minden interfészre köt, mert egy megújító ügynök definíció szerint máshol fut; a védelme a kölcsönös TLS, nem a bind-cím. A diagnosztikai figyelő loopbacken van és ki van kapcsolva, abból kiindulva, hogy a monitorozó ügynök ugyanazon a gépen fut.
A tanúsítványok életciklusa
Az átjáró saját hitelesítésszolgáltatót üzemeltet, amit egyszer kell inicializálni
az isg ca init-tel. Négy különböző dolgot ír alá, négy különböző élettartammal,
és a különbségek abból következnek, hogy melyik hitelesítő adat mire való.
Az emberi hozzáférési tanúsítvány az, amire egy munkamenet ténylegesen épül.
Amikor egy connect minden kapun átjut, a daemon friss ed25519 kulcspárt generál
a saját memóriájában, aláír fölé egy SSH-felhasználói tanúsítványt, és azzal
tárcsázza a célgépet. Pontosan tíz percig érvényes — a kiadás mindkét oldalán öt
percig, egy olyan ablak, ami a kézfogás alatti órajel-eltérésre van méretezve, és
semmi másra —, a permit-pty kiterjesztést hordozza és semmi többet, és sosem
íródik lemezre. Sem a kulcs, sem a tanúsítvány nem kerül soha az operátor kezébe.
Egy szolgáltatásfiók-hozzáférési tanúsítvány (isg ca issue --account <account> --host <host>) ennek a gépi megfelelője: alapból egy óra, vagy amennyit
a ca.yaml service_accounts[].ttl_seconds mond arra a fiókra.
Egy megújítható identitás az az X.509 kliens-tanúsítvány, amit egy
szolgáltatás-gép tart, hogy az ügynöke megújíthassa a hozzáférési tanúsítványokat
a kölcsönös TLS-végponton. Egy egyszer használatos csatlakozási token beváltásával
adódik ki (isg ca join-token redeem --token <token>; maga a token alapból
tizenöt perc), és harminc napig él, hacsak a ca.yaml renewable_ttl_days-e mást
nem mond. A privát kulcs a szolgáltatás-gépen generálódik, és sosem kerül át az
átjáróra.
Egy hoszttanúsítvány (isg ca host-cert issue --host <host> --key <file>) az,
amitől az átjáró fel tudja ismerni a célgépet. A célgép meglévő publikus
hosztkulcsa fölé íródik alá — a CA a gép privát kulcsát sosem látja —, és alapból
egy évig él (ca.yaml: host_cert_ttl). A célgép oldalán nincs megújító ügynök,
tehát itt a modell a hosszú élettartam plusz a visszavonás, nem a rövid életű
rotáció.
Az egész mögött álló aláírót a ca.yaml signer kulcsa választja ki: builtin,
ami az átjárón nyitja meg a CA privát kulcsát, vagy vault, ami az aláírást az
OpenBaóra delegálja, és lokális kulcsot egyáltalán nem nyit meg. Az átjáró saját
TLS-kiszolgáló-tanúsítványai — az admin felülethez és a megújítási végponthoz —
ugyanabból a CA-ból származnak, és kilencven napig élnek.
Hogy mi történik lejáratkor, az hitelesítő adatonként más, és az egyik eset
meglepetést szokott okozni. Az SSH kizárólag a kézfogás alatt nézi meg egy
tanúsítvány érvényességét. Az a munkamenet tehát, amelyik a tíz perces ablakán
belül kapcsolódott, utána korlátlanul tovább működik; nincs megújítás és nincs
munkamenet-közbeni újrakiadás, tervezetten. Egy ember elvágásának a kara a
következő kiadás megtagadása — ezt teszik a hozzáférési kapuk —, nem egy már
használatban lévő tanúsítvány érvénytelenítése. A hosszú életű hitelesítő
adatoknál ez fordítva van: az isg ca revoke --account <account> és az
isg ca host-cert revoke egy sorszámot tesz az átjáró visszavonási listájára,
amit minden megújítási kérésnél és minden tárcsázásnál megnéz, elavulni képes
gyorsítótár nélkül.
Az ábra szétválasztja azt, amit a fenti bekezdések szükségszerűen összefolyatnak. A bal oszlop egyetlen kapcsoló és mindaz, ami alatta van. A jobb oszlop egy olyan hitelesítésszolgáltató, amit ez a kapcsoló soha nem mozdít — ezért van az, hogy egy OpenBaón keresztül aláíró átjáró is tart saját privát kulcsot a lemezén. A szaggatott sáv egy harmadik CA, és azért van mindkét oszlopon kívül rajzolva, mert ott is él: egy olyan gépen, amit ez az átjáró nem ér el, és amelynek az aláírásait soha nem állítja elő.
Adatok nyugalomban
Minden, amit az átjáró perzisztál, egyetlen könyvtár alatt él: az $ISG_HOME
alatt, ami a rendszerszolgáltatás-elrendezésben a /var/lib/isg. A konfiguráció
és az állapot ezen osztozik. Minden konfigurációs fájl opcionális — a fájl nélküli
állapotgyökér érvényes első-futás állapot —, és minden betöltő maga definiálja,
mit jelent a saját fájlja hiánya. A
konfigurációs referencia minden fájlt és bennük minden
kulcsot felsorol.
Az állapot, szemben a konfigurációval:
| Útvonal | Mit tart |
|---|---|
sessions/ |
Munkamenet-rekordonként egy JSON-fájl, mód 0640 |
approvals/ |
Jóváhagyás-rekordonként egy JSON-fájl, mód 0640 |
audit.log |
Az auditnapló: csak hozzáfűzhető JSONL, eseményenként egy sor, mód 0640 |
recording-<SESSION-ID>.cast |
Egy munkamenet terminál-felvétele, 5 MiB-ban maximálva |
transcript-<SESSION-ID>.jsonl |
Egy munkamenet parancsai — Web Access-munkamenetnél kérésenként egy sor (metódus, út, státusz, a közvetített fiók; record_body mellett egy módosító kérés maszkolt törzse) |
apps-dynamic/ |
A webUI Appok kezelése oldalán kezelt alkalmazások (rekord-család, flottában PostgreSQL) |
ca/ |
A CA saját kulcsanyaga — a privát kulcsok módja 0600 |
pub/ |
A CA publikus artifactjainak operátor által olvasható tükre, mód 0644 |
serve.lease |
Melyik folyamat birtokolja jelenleg ezt az állapotgyökeret |
totp_outbox.txt |
Többfaktoros kódok, ha nincs konfigurált levéltovábbító |
ticket_outbox/ |
Újrapróbálásra váró ticket-szándékok |
Egy kind: form fiók upstream munkamenet-sütijei szándékosan nincsenek ezen a
listán: csak az átjáró memóriájában élnek, alkalmazás-munkamenetenként, és egy
újraindulás vagy egy másik átjáróra kerülés után az átjáró újra belép.
Hogy ezek közül melyik hagyja el a könyvtárat egy közös tár felé, és melyik
soha, azt a Több átjáró üzemeltetése alatti tábla mondja ki. A retention.yaml
bekapcsol egy időszakos söprést, ami törli a lejárt artifactokat — 24 óránként,
hacsak a sweep.interval mást nem mond, és teljesen kikapcsolva, hacsak a
sweep.enabled nincs beállítva. Hogy a flottában mely átjárók élnek, az egy
rekord a közös tárban, és az isg system brokers az, ami olvassa.
Az auditnapló mindennek a kivétele. Sosem söpri semmi, sosem íródik újra és sosem kerül máshová: szerződés szerint csak hozzáfűzhető, a szerződést pedig — egy sor JSON-alakját, a fájl módját, azt a rotálási viselkedést, amit egy begyűjtő ügynöknek el kell viselnie — az auditnapló-séma írja le.
Fail-closed posztúra
Az átjáró inkább nem indul el, mint hogy olyan állapotban induljon el, ami helyesnek látszik, de nem az. Ez tudatos csere: az elutasítást látja az az operátor, aki az újraindítást végzi, míg egy csendben kikapcsolt kontrollt addig senki nem lát, amíg nem számít.
Az isg serve nem jön fel, ha:
- egy konfigurációs fájlban olyan felső szintű kulcs van, amit nem ismer. Bármelyik regisztrált fájlban, minden más megnyitása előtt ellenőrizve, kimenekülő kapcsoló nélkül. Egy elgépelt kulcs, amit csendben figyelmen kívül hagyna, olyan átjárót eredményezne, ami tisztán elindul, és mást kényszerít ki, mint amit a fájl mond.
- a
retention.yamlnem értelmezhető. Az a megőrzési szabály, amit senki nem tud elolvasni, rosszabb, mintha nem lenne szabály, mert úgy néz ki, mintha lenne. - egy másik daemon már birtokolja az állapotgyökeret. Két daemon egy könyvtár
fölött nem rontja el egymás rekordjait; a második csendben eldobja az első
munkameneteit. A bérlet az, ami ezt megelőzi, és az
isg system lease statusaz, ami megmagyarázza az elutasítást. - egy névtelen átjáró olyan tárhoz próbál csatlakozni, amit egy másik átjáró
használ. Egy
broker.yamlidnélküli átjáró rekordjai utólag nem különböztethetők meg a társaiétól, és a közös tár pontosan az a hely, ahol ez számít. - egy átjáró nevezett és PostgreSQL-t használ, de OpenBaót nem. A
ca.yamlsigner-je és azmfa.yamlstore-ja isvaultkell legyen ebben az elrendezésben. Az üzenet egyszerre nevezi meg az összes sértést — a fájlt, a jelenlegi értéket, a megköveteltet és az okot —, nem újraindításonként egyet. Hogy egyébként mi romlik el, azt a Több átjáró üzemeltetése mondja el. - az auditnapló nem nyitható meg, vagy az
audit.yamlnem értelmezhető. - egy megnevezett háttértár nem építhető fel. Az a
records.backendvagyrecordings.backend, amit az ISG nem tud megkonstruálni, elutasítás, nem csendes visszaesés lokális tárolásra — az az elkülönítés, amit az operátor kért, vagy létezik, vagy az átjáró kimondja. - az
mfa.yamlnem létező módot nevez meg, vagy a többfaktoros titok-tár nem építhető fel. - a
connect.yamlismeretlenhost_key_checkértéket nevez meg. Megengedő beállításra való visszaesés nincs. - nem-loopback
--bind-ot kérnek hitelesítés nélkül vagy TLS nélkül. A kettő együtt kötelező; bármelyik hiánya olyan elutasítás, ami megnevezi, mi hiányzik.
További két eset kérésidejű elutasítás, nem indulási. Ha egy kért --as principal
címtár-lekérdezése infrastrukturális okból hiúsul meg — nem „nincs ilyen
felhasználó", ami túlélhető —, a daemon megtagadja a munkamenetet, ahelyett hogy
üres csoporttagságokkal folytatná, és abban reménykedne, hogy valamelyik szabály
átengedi. A break-glass pedig, az a mechanizmus, ami megkerüli a négy szem elvének
kapuját, mindenkitől meg van tagadva, ha nincs breakglass_group konfigurálva;
nincs olyan olvasata a „nincs beállítva"-nak, amitől megengedő lenne.
Két dolog nem végzetes. Az első az inicializálatlan CA: a daemon elindul,
kimondja, és nem nyitja meg a megújítási végpontot; a CA-adminisztrációs műveletek
addig maradnak elérhetetlenek, amíg az isg ca init le nem futott. A második az
induláskor elérhetetlen identity provider: a daemon SSO nélkül indul — a
jelszó-űrlap web: required mellett is megmarad —, és az isg system check
SSO (OIDC) sora ezt mondja, amíg a provider vissza nem tér. Hogy bárki
beléphet-e egy futó átjáróba, az nem múlhat azon, hogy egy JSON-dokumentum
letölthető-e.