Com automatitzar un inici de sessió VPN que espera un codi de testimoni
Un client VPN de línia d'ordres que demana dades en un terminal bloqueja un script que només envia una contrasenya per canonada. Feu aquestes cinc comprovacions abans de recórrer a expect.
Un script que engega un client VPN de proveïdor es penja fins que s'esgota el temps, i el registre mostra que el client demana un codi de verificació que ningú no ha escrit. La contrasenya s'havia enviat, així que la conclusió òbvia és que la contrasenya és incorrecta. No ho és. La petició del codi és una conversa separada en un canal separat, i el vostre script no la va obrir mai.
Feu les cinc comprovacions següents per ordre. Atureu-vos a la primera que falli, perquè cada pas posterior pressuposa que els anteriors es compleixen.
Comprovació 1: el client llegeix l'entrada estàndard, com a mínim?
Proveu-ho abans d'escriure cap automatització: envieu un secret fals al client per canonada i mireu què passa. Si imprimeix la seva petició i després espera, no llegeix la canonada.
Molts clients obren el dispositiu de terminal directament, o refusen prendre un secret d'un flux que no és un terminal, perquè una canonada esgarriada no pugui filtrar una contrasenya. OpenVPN és l'excepció documentada, perquè --auth-user-pass accepta un camí de fitxer. Els clients de proveïdor que demanen un codi d'un sol ús normalment no tenen cap opció equivalent, i la seva petició espera un terminal que el vostre script no ha proporcionat mai.
Comprovació 2: el procés fill té un terminal?
Un pty assigna un terminal al fill, cosa que converteix les peticions en sortida llegible que podeu respondre per ordre.
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)Les cadenes de petició de dalt són il·lustratives; copieu el text exacte que imprimeix el vostre client, incloent-hi majúscules i puntuació. Cada expectativa porta un temps d'espera, i un fill tancat llança una excepció en lloc de retornar un estat, així que emboliqueu la seqüència i tracteu el final de fitxer com un error. Fixeu-vos en què no fa aquest bloc: el fill mor amb el script, perquè un pty no és un mecanisme de desacoblament i disown és una ordre interna de l'intèrpret que no pot arribar a un procés que el vostre script ha creat.
Comprovació 3: hi ha una entrada no interactiva suportada?
L'extracció de pantalla es trenca amb les actualitzacions del client, així que busqueu primer una opció documentada.
Reviseu la sortida d'ajuda per si hi ha una opció de testimoni o de codi d'un sol ús, i comproveu si el servei accepta el codi afegit al camp de contrasenya. On el client llegeix un fitxer de credencials, doneu-li el fitxer en lloc d'una petició:
openvpn --config office.ovpn --auth-user-pass <(printf "%s\n%s\n" "$USER_NAME" "$PASSWORD")La substitució de processos dona al client un camí llegible en sistemes que ofereixen /dev/fd. El secret continua sent un secret des del punt de vista del client, així que manteniu-lo fora dels registres, de l'historial de l'intèrpret i de les llistes de processos. Si el client rebutja /dev/fd o obre el camí de credencials més d'una vegada, escriviu un fitxer real amb permisos restrictius i esborreu-lo dins del mateix script.
Comprovació 4: el túnel sobreviurà al script?
Per defecte el túnel mor amb el seu pare, que és el contrari del que necessita un script d'arrencada.
disown -h només ajuda quan heu llançat el client com a feina de l'intèrpret, perquè edita la taula de feines d'aquell intèrpret i no pot arribar a un procés que el vostre script ha creat mitjançant un pty. Un gestor de serveis és la millor casa per a tot el que s'ha de reconnectar sense supervisió, perquè reinicia el client i registra per què ha mort. En qualsevol cas, espereu un codi nou després de cada reconnexió: un testimoni d'un sol ús es consumeix amb la primera autenticació correcta.
Fixeu-vos en què fa sudo a la seqüència. La petició de contrasenya de sudo no és la petició del VPN, i respondre-hi amb la contrasenya del VPN és la manera més comuna que un ordre d'expectatives altrament correcte falli igualment.
Comprovació 5: el codi d'una persona ha de ser en un script?
Aquesta és la comprovació que la gent se salta. Un testimoni pertany a una persona, mentre que un túnel que s'ha d'aixecar segons una programació pertany a la màquina.
Si una feina s'ha de reconnectar sense supervisió, pregunteu si un certificat de màquina o un compte de servei poden substituir l'inici de sessió interactiu. Automatitzar el codi d'un sol ús d'algú converteix un segon factor en un secret emmagatzemat, cosa que és un canvi de política i no una comoditat de scripting. On el servei admet les dues opcions, trieu la credencial que encaixa amb com s'executa realment la feina. Escriviu la resposta, perquè la propera persona preguntarà per què el script guarda un testimoni.
Com és un script que funciona
El script imprimeix el pas on ha arribat, mai el secret, i surt amb un codi diferent de zero davant de qualsevol expectativa fallida.
Proveu-lo trencant-lo a propòsit: contrasenya incorrecta, grup incorrecte, testimoni caducat. Cada fallada hauria d'aturar-se en un pas amb nom en lloc de penjar-se. Després executeu-lo una vegada contra el servei real i comproveu el túnel des de fora del script, no des de dins.