Як аўтаматызаваць уваход у VPN, які чакае код токена
CLI-кліент VPN, які запытвае ўвод у тэрмінале, блакуе скрыпт, што перадае толькі пароль праз канал. Прайдзіце гэтыя пяць праверак, перш чым брацца за expect.
Скрыпт, які запускае кліент VPN ад пастаўшчыка, завісае да сканчэння часу чакання, а журнал паказвае, што кліент просіць код пацверджання, які ніхто не ўводзіў. Пароль быў перададзены, таму відавочная выснова — пароль няслушны. Гэта не так. Запыт кода — асобная размова ў асобным канале, і ваш скрыпт ніколі яе не адкрываў.
Прайдзіце пяць праверак ніжэй па парадку. Спыніцеся на першай няўдалай, бо кожны наступны крок мяркуе, што папярэднія выкананы.
Праверка 1: ці чытае кліент стандартны ўвод наогул?
Праверце перад напісаннем любой аўтаматызацыі: перадайце ў кліент фіктыўны сакрэт праз канал і паглядзіце, што адбудзецца. Калі ён друкуе свой запыт і потым чакае, ён не чытае канал.
Многія кліенты адкрываюць прыладу тэрмінала напрамую або адмаўляюцца браць сакрэт з патоку, які не з'яўляецца тэрміналам, каб выпадковы канал не выпусціў пароль. OpenVPN — дакументаванае выключэнне, бо --auth-user-pass прымае шлях да файла. Кліенты пастаўшчыкоў, якія просяць аднаразовы код, звычайна не маюць эквівалентнага сцяжка, і іх запыт чакае тэрмінал, які ваш скрыпт не прадаставіў.
Праверка 2: ці мае даччыны працэс тэрмінал?
pty выдзяляе тэрмінал для даччынага працэсу, што ператварае запыты ў чытэльны вывад, на які можна адказваць па парадку.
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)Радкі запытаў вышэй — ілюстратыўныя; капіюйце дакладны тэкст, які друкуе ваш кліент, уключаючы рэгістр і пунктуацыю. Кожнае чаканне мае тайм-аўт, а закрыты даччыны працэс уздымае выключэнне замест вяртання статусу, таму абгарніце паслядоўнасць і лічыце канец файла няўдачай. Звярніце ўвагу, чаго гэты блок не робіць: даччыны працэс памірае разам са скрыптам, бо pty не з'яўляецца механізмам аддзялення, а disown — убудаваная каманда абалонкі, якая не дасягае працэсу, створанага вашым скрыптам.
Праверка 3: ці ёсць падтрыманы неінтэрактыўны ўвод?
Счытванне экрана ламаецца пры абнаўленні кліента, таму спачатку шукайце дакументаваны сцяжок.
Праверце вывад даведкі на наяўнасць опцыі токена або аднаразовага кода, а таксама ці прымае служба код, далучаны да поля пароля. Там, дзе кліент чытае файл уліковых даных, дайце яму файл замест запыту:
openvpn --config office.ovpn --auth-user-pass <(printf "%s\n%s\n" "$USER_NAME" "$PASSWORD")Падстаноўка працэсаў дае кліенту чытэльны шлях у сістэмах, якія прадастаўляюць /dev/fd. Сакрэт застаецца сакрэтам з пункту гледжання кліента, таму трымайце яго па-за журналамі, гісторыяй абалонкі і спісамі працэсаў. Калі кліент адхіляе /dev/fd або адкрывае шлях уліковых даных больш за адзін раз, запішыце сапраўдны файл з абмежавальнымі правамі і выдаліце яго ў тым жа скрыпце.
Праверка 4: ці перажыве тунель скрыпт?
Па змаўчанні тунель памірае разам са сваім бацькам, што процілеглае таму, што патрэбна скрыпту запуску.
disown -h дапамагае толькі калі вы запускалі кліент як задачу абалонкі, бо ён змяняе табліцу задач гэтай абалонкі і не дасягае працэсу, створанага вашым скрыптам праз pty. Менеджэр службаў — лепшае месца для ўсяго, што мусіць перападключацца без нагляду, бо ён перазапускае кліент і запісвае, чаму той спыніўся. У любым выпадку чакайце новы код пасля кожнага перападлучэння: аднаразовы токен спажываецца пры першай паспяховай аўтэнтыфікацыі.
Паглядзіце, што sudo робіць з паслядоўнасцю. Запыт пароля sudo — гэта не запыт VPN, і адказ на яго паролем VPN — самы часты спосаб, якім правільны парадак чаканняў усё роўна правальваецца.
Праверка 5: ці павінен код чалавека быць у скрыпце?
Гэта праверка, якую людзі прапускаюць. Токен належыць чалавеку, а тунель, які мусіць узнімацца па раскладзе, належыць машыне.
Калі задача мусіць перападключацца без нагляду, спытайцеся, ці можа машынны сертыфікат або службовы ўліковы запіс замяніць інтэрактыўны ўваход. Аўтаматызацыя чыйгосьці аднаразовага кода ператварае другі фактар у захаваны сакрэт, а гэта змена палітыкі, а не зручнасць для скрыптоў. Там, дзе служба падтрымлівае абодва, абярыце тыя ўліковыя даныя, што адпавядаюць таму, як задача рэальна выконваецца. Запішыце адказ, бо наступны чалавек спытае, чаму скрыпт трымае токен.
Як выглядае працоўны скрыпт
Скрыпт друкуе крок, да якога дайшоў, ніколі не друкуе сакрэт і выходзіць з ненулявым кодам пры любым няўдалым чаканні.
Праверце яго, наўмысна зламаўшы: няслушны пароль, няслушная група, скончаны токен. Кожная няўдача мусіць спыніць на названым кроку, а не завіснуць. Затым запусціце яго адзін раз супраць рэальнай службы і праверце тунель звонку ад скрыпта, а не знутры яго.