Skript, který spustí VPN klienta dodavatele, visí, dokud nevyprší časový limit, a protokol ukazuje, že klient žádá ověřovací kód, který nikdo nezadal. Heslo bylo dodáno, takže zřejmý závěr je, že heslo je špatné. Není. Výzva kódu je samostatná konverzace na samostatném kanálu a váš skript ji nikdy neotevřel.

Projděte pět kontrol níže v pořadí. Zastavte se u první, která selže, protože každý další krok předpokládá, že předchozí platí.

Kontrola 1: čte klient vůbec standardní vstup?

Otestujte to dřív, než napíšete jakoukoli automatizaci: protlačte do klienta falešné tajemství rourou a sledujte, co se stane. Pokud vypíše svou výzvu a pak čeká, rouru nečte.

Mnoho klientů otevírá zařízení terminálu přímo, nebo odmítá přijmout tajemství z proudu, který není terminál, aby zbloudilá roura nemohla uniknout heslo. OpenVPN je dokumentovaná výjimka, protože --auth-user-pass přijímá cestu k souboru. Klienti dodavatelů, kteří žádají jednorázový kód, obvykle nemají ekvivalentní přepínač a jejich výzva čeká na terminál, který váš skript nikdy neposkytl.

Kontrola 2: má potomek terminál?

pty přidělí potomkovi terminál, což promění výzvy ve čitelný výstup, na který můžete odpovídat v pořadí.

import pexpect

child = pexpect.spawn("openconnect vpn.example.net", encoding="utf-8", timeout=30)
child.expect("GROUP:")
child.sendline("staff")
child.expect("USERNAME:")
child.sendline("alice")
child.expect("PASSWORD:")
child.sendline(PASSWORD)
child.expect("Connected as", timeout=60)

Řetězce výzev výše jsou ilustrativní; zkopírujte přesný text, který váš klient vypisuje, včetně velikosti písmen a interpunkce. Každé očekávání má časový limit a uzavřený potomek vyvolá výjimku místo vrácení stavu, takže sekvenci obalte a konec souboru berte jako selhání. Všimněte si, co tento blok nedělá: potomek umírá se skriptem, protože pty není mechanismus odpoutání a disown je vestavěný příkaz shellu, který nedosáhne na proces, jenž váš skript vytvořil.

Kontrola 3: existuje podporovaný neinteraktivní vstup?

Snímání obrazovky se láme při aktualizacích klienta, takže nejprve hledejte dokumentovaný přepínač.

Prohlédněte výstup nápovědy, zda nabízí volbu tokenu nebo jednorázového kódu, a ověřte, zda služba přijímá kód připojený k poli hesla. Kde klient čte soubor pověření, dejte mu soubor místo výzvy:

openvpn --config office.ovpn --auth-user-pass <(printf "%s\n%s\n" "$USER_NAME" "$PASSWORD")

Nahrazení procesů dá klientovi čitelnou cestu v systémech, které nabízejí /dev/fd. Tajemství zůstává z pohledu klienta tajemstvím, takže je držte mimo protokoly, historii shellu a výpisy procesů. Pokud klient /dev/fd odmítne nebo cestu k pověřením otevře více než jednou, napište skutečný soubor s omezujícími právy a ve stejném skriptu jej smažte.

Kontrola 4: přežije tunel skript?

Ve výchozím nastavení tunel umírá se svým rodičem, což je opak toho, co spouštěcí skript potřebuje.

disown -h pomůže jen tehdy, když jste klienta spustili jako úlohu shellu, protože upravuje tabulku úloh tohoto shellu a nedosáhne na proces, který váš skript vytvořil přes pty. Správce služeb je lepší domov pro vše, co se musí připojovat znovu bez dozoru, protože klienta restartuje a zaznamená, proč zemřel. V každém případě čekejte nový kód po každém opětovném připojení: jednorázový token se spotřebuje při prvním úspěšném ověření.

Sledujte, co sudo dělá se sekvencí. Výzva k heslu sudo není výzvou VPN a odpovídat na ni heslem VPN je nejčastější způsob, jak jinak správné pořadí očekávání stále selže.

Kontrola 5: má být něčí kód ve skriptu?

To je kontrola, kterou lidé přeskakují. Token patří člověku, zatímco tunel, který se musí zvedat podle plánu, patří stroji.

Pokud se úloha musí připojovat znovu bez dozoru, zeptejte se, zda strojový certifikát nebo servisní účet může nahradit interaktivní přihlášení. Automatizace něčího jednorázového kódu mění druhý faktor v uložené tajemství, což je změna politiky, nikoli pohodlí pro skripty. Kde služba podporuje obojí, zvolte pověření, které odpovídá tomu, jak úloha skutečně běží. Odpověď zapište, protože další člověk se zeptá, proč skript drží token.

Jak vypadá funkční skript

Skript vypisuje krok, ke kterému došel, nikdy tajemství, a při každém neúspěšném očekávání skončí s nenulovým kódem.

Otestujte ho tím, že ho schválně rozbijete: špatné heslo, špatná skupina, propadlý token. Každé selhání by se mělo zastavit na pojmenovaném kroku místo visení. Pak ho jednou spusťte proti skutečné službě a zkontrolujte tunel zvenčí skriptu, ne z jeho nitra.

Související články