Paano i-automate ang pag-log in sa VPN na naghihintay ng token code
Ang CLI VPN client na nagtatanong sa terminal ay humaharang sa script na nagpapadala lamang ng password sa pipe. Gawin ang limang pagsusuring ito bago ka gumamit ng expect.
Ang script na naglulunsad ng VPN client ng vendor ay nakabitin hanggang mag-timeout, at ipinapakita ng log na humihingi ang client ng verification code na walang nag-type. Naibigay na ang password, kaya ang halatang konklusyon ay mali ang password. Hindi. Ang hiling ng code ay hiwalay na usapan sa hiwalay na channel, at hindi kailanman binuksan iyon ng script mo.
Daanan ang limang pagsusuri sa ibaba ayon sa pagkakasunod-sunod. Huminto sa unang mabibigo, dahil ipinapalagay ng bawat susunod na hakbang na wasto ang mga nauna.
Pagsusuri 1: binabasa ba ng client ang standard input?
Subukan bago sumulat ng anumang automation: magpadala ng pekeng sikreto sa client sa pamamagitan ng pipe at tingnan ang mangyayari. Kung ipi-print nito ang hiling nito at pagkatapos ay maghintay, hindi nito binabasa ang pipe.
Maraming client ang direktang nagbubukas ng terminal device, o tumatangging kumuha ng sikreto mula sa stream na hindi terminal, upang ang ligaw na pipe ay hindi makapaglabas ng password. Ang OpenVPN ang dokumentadong eksepsiyon, dahil ang --auth-user-pass ay tumatanggap ng path ng file. Ang mga client ng vendor na humihingi ng one-time code ay karaniwang walang katumbas na opsiyon, at ang hiling nila ay naghihintay sa terminal na hindi kailanman ibinigay ng script mo.
Pagsusuri 2: may terminal ba ang child process?
Ang pty ay naglalaan ng terminal sa anak, na ginagawang madaling basahin na output ang mga hiling na masasagot mo ayon sa pagkakasunod-sunod.
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)Ang mga string ng hiling sa itaas ay halimbawa lamang; kopyahin ang eksaktong text na ipi-print ng client mo, kasama ang malaki at maliit na titik at bantas. Bawat pag-asa ay may timeout, at ang saradong anak ay nagtatapon ng exception sa halip na magbalik ng status, kaya balutin ang sekwensiya at ituring na kabiguan ang dulo ng file. Pansinin ang hindi ginagawa ng bloke na ito: namamatay ang anak kasama ng script, dahil ang pty ay hindi mekanismo ng paghihiwalay at ang disown ay builtin ng shell na hindi maabot ang prosesong inilunsad ng script mo.
Pagsusuri 3: may sinusuportahang non-interactive input ba?
Nasira ang screen-scraping sa mga upgrade ng client, kaya maghanap muna ng dokumentadong opsiyon.
Tingnan ang help output para sa token o one-time code na opsiyon, at tingnan kung tinatanggap ng serbisyo ang code na idinagdag sa password field. Kung saan binabasa ng client ang credentials file, ibigay sa kanya ang file sa halip na hiling:
openvpn --config office.ovpn --auth-user-pass <(printf "%s\n%s\n" "$USER_NAME" "$PASSWORD")Ang process substitution ay nagbibigay sa client ng mababasang path sa mga sistemang nag-aalok ng /dev/fd. Sikreto pa rin ang sikreto mula sa pananaw ng client, kaya ilayo ito sa mga log, shell history at listahan ng proseso. Kung tinatanggihan ng client ang /dev/fd o binubuksan ang credentials path nang higit sa isang beses, sumulat ng tunay na file na may mahigpit na pahintulot at tanggalin ito sa parehong script.
Pagsusuri 4: mabubuhay ba ang tunnel nang mas matagal kaysa sa script?
Bilang default, namamatay ang tunnel kasama ng magulang nito, na kabaligtaran ng kailangan ng bootstrap script.
Ang disown -h ay tumutulong lamang kapag inilunsad mo ang client bilang shell job, dahil inaayos nito ang job table ng shell na iyon at hindi maabot ang prosesong inilunsad ng script mo sa pamamagitan ng pty. Mas mabuting tahanan ang service manager para sa anumang kailangang muling kumonekta nang walang pagmamasid, dahil pinapasimulan nitong muli ang client at itinatala kung bakit ito namatay. Sa anumang kaso, asahan ang bagong code pagkatapos ng bawat muling pagkonekta: ang one-time token ay nauubos sa unang matagumpay na authentication.
Pansinin ang ginagawa ng sudo sa sekwensiya. Ang hiling ng password ng sudo ay hindi ang hiling ng VPN, at ang pagsagot dito ng password ng VPN ang pinakakaraniwang dahilan kung bakit nabibigo pa rin ang isang tamang pagkakasunod-sunod ng pag-asa.
Pagsusuri 5: dapat bang nasa script ang code ng isang tao?
Ito ang pagsusuring nilalaktawan ng mga tao. Ang token ay pag-aari ng tao, samantalang ang tunnel na dapat tumayo ayon sa iskedyul ay pag-aari ng makina.
Kung ang isang trabaho ay kailangang muling kumonekta nang walang pagmamasid, itanong kung ang certificate ng makina o service account ay maaaring pumalit sa interactive na pag-log in. Ang pag-automate ng one-time code ng isang tao ay ginagawang nakaimbak na sikreto ang pangalawang factor, na pagbabago ng patakaran at hindi kaginhawahan sa scripting. Kung saan sinusuportahan ng serbisyo ang pareho, piliin ang credential na tumutugma sa kung paano talaga tumatakbo ang trabaho. Isulat ang sagot, dahil itatanong ng susunod na tao kung bakit may hawak na token ang script.
Hitsura ng gumaganang script
Ipi-print ng script ang hakbang na naabot, hindi kailanman ang sikreto, at lumalabas na may di-zero na code sa anumang nabigong pag-asa.
Subukan ito sa sadyang pagsira: maling password, maling grupo, nag-expire na token. Bawat kabiguan ay dapat huminto sa pinangalanang hakbang sa halip na makabitin. Pagkatapos, patakbuhin ito nang isang beses laban sa tunay na serbisyo at suriin ang tunnel mula sa labas ng script, hindi mula sa loob.