Korleis automatisere ein VPN-innlogging som ventar på ein tokenkode
Ein CLI-VPN-klient som spør i ein terminal, blokkerer eit skript som berre sender eit passord gjennom eit røyr. Gå gjennom desse fem kontrollane før du grip til expect.
Eit skript som startar ein VPN-klient frå ein leverandør, heng til det går ut på tid, og loggen viser at klienten ber om ein stadfestingskode som ingen skreiv inn. Passordet vart sendt, så den openberre konklusjonen er at passordet er feil. Det er det ikkje. Kodeforespurnaden er ein separat samtale på ein separat kanal, og skriptet ditt opna han aldri.
Gå gjennom dei fem kontrollane nedanfor i rekkjefølgje. Stopp ved den første som feilar, fordi kvart seinare steg føreset at dei tidlegare held.
Kontroll 1: les klienten standard inndata i det heile?
Test før du skriv nokon automatisering: send ein dummy-hemmelegheit gjennom eit røyr til klienten og sjå kva som skjer. Viss han skriv ut forespurnaden og deretter ventar, les han ikkje røyret.
Mange klientar opnar terminaleininga direkte, eller nektar å ta ei hemmelegheit frå ein straum som ikkje er ein terminal, slik at eit villfaren røyr ikkje kan leke eit passord. OpenVPN er det dokumenterte unntaket, fordi --auth-user-pass tek ein filsti. Leverandørklientar som ber om ein eingongskode har vanlegvis ingen tilsvarande brytar, og forespurnaden deira ventar på ein terminal som skriptet ditt aldri stilte til rådvelde.
Kontroll 2: har borneprosessen ein terminal?
Ein pty tildeler ein terminal til barnet, noko som gjer forespurnader om til lesbar utdata du kan svare på i rekkjefølgje.
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)Forespurnadsstrengane over er illustrative; kopier den nøyaktige teksten klienten din skriv ut, inkludert store og små bokstavar og teiknsetjing. Kvar forventing har ei tidsgrense, og eit lukka barn kastar eit unntak i staden for å returnere ein status, så pakk inn sekvensen og handsam slutten av fila som ein feil. Legg merke til kva denne blokka ikkje gjer: barnet døyr med skriptet, fordi ein pty ikkje er ein fråkopingsmekanisme, og disown er ein innebygd skalkommando som ikkje kan nå ein prosess skriptet ditt starta.
Kontroll 3: finst det støtta ikkje-interaktiv inndata?
Skjermskraping bryt saman ved klientoppdateringar, så sjå etter ein dokumentert brytar først.
Sjekk hjelpeutdataa for eit token- eller eingongskodeval, og sjekk om tenesta godtek koden som er lagt til passordfeltet. Der klienten les ei påloggingsfil, gje han fila i staden for ein forespurnad:
openvpn --config office.ovpn --auth-user-pass <(printf "%s\n%s\n" "$USER_NAME" "$PASSWORD")Prosessubstitusjon gjev klienten ein lesbar bane på system som tilbyr /dev/fd. Hemmelegheita er framleis ei hemmelegheit frå klienten si side, så hald henne unna loggar, skallhistorikk og prosesslister. Viss klienten avviser /dev/fd eller opnar påloggingsbanen meir enn éin gong, skriv ei ekte fil med strenge løyve og slett henne i same skript.
Kontroll 4: overlever tunnelen skriptet?
Som standard døyr tunnelen med forelderen sin, noko som er det motsette av kva eit oppstartsskript treng.
disown -h hjelper berre når du starta klienten som ein skalljobb, fordi han redigerer jobbtabellen til den skallen og ikkje kan nå ein prosess skriptet ditt starta gjennom ein pty. Ein tenestebehandlar er eit betre heim for alt som må kople til på nytt utan tilsyn, fordi han startar klienten på nytt og registrerer kvifor han døydde. Uansett, vent ein ny kode etter kvar gjenoppkopling: eit eingongstoken vert brukt opp av den første vellukka autentiseringa.
Legg merke til kva sudo gjer med sekvensen. Ein sudo-passordforespurnad er ikkje VPN-en sin forespurnad, og å svare på han med VPN-passordet er den vanlegaste måten ein elles korrekt forventingsrekkjefølgje likevel feilar.
Kontroll 5: bør koden til ein person vere i eit skript?
Dette er kontrollen folk hoppar over. Eit token høyrer til ein person, medan ein tunnel som må opp etter ein plan høyrer til maskinen.
Viss ein jobb må kople til på nytt utan tilsyn, spør om eit maskinsertifikat eller ein tenestekonto kan erstatte den interaktive innlogginga. Å automatisere eingongskoden til nokon gjer ein annan faktor til ei lagra hemmelegheit, noko som er ei policyendring og ikkje ein komfort for skript. Der tenesta støttar begge, vel den pålogginga som passar med korleis jobben faktisk køyrer. Skriv ned svaret, fordi neste person vil spørje kvifor skriptet held eit token.
Korleis eit fungerande skript ser ut
Skriptet skriv ut steget det nådde, aldri hemmelegheita, og avsluttar med ein ikkje-null kode ved kvar mislukka forventing.
Test det ved å øydeleggje det med vilje: feil passord, feil gruppe, utløpt token. Kvar feil bør stoppe ved eit namngjeve steg i staden for å henge. Køyr det deretter éin gong mot den ekte tenesta, og kontroller tunnelen utanfrå skriptet, ikkje innanfrå.