AnyConnect в Linux: безопасно скриптиране на последователността за вход
Бинарният файл vpn от Cisco AnyConnect чете отговори от stdin и това е достатъчно за повтаряем вход. Изградете последователността, защитете файла, проверете и спрете.
vpn клиентът, който идва с Cisco AnyConnect, се държи като разговор: отпечатва подкана, чака ред, после отпечатва следващата. Подайте този разговор от файл или тръба и същият бинарен файл работи без надзор. Техниката е едно пренасочване плюс подреден списък от отговори и именно списъкът, а не пренасочването, решава дали скриптът е надежден.
На практика две неща го чупят. Редът на подканите се измества, когато шлюзът попита нещо допълнително, а съхранена парола превръща една печатна грешка в блокиран акаунт. Отнасяйте се към последователността като към версионирани данни, които можете да сравните след всяка промяна на шлюза. Проваляйте се шумно, вместо да опитвате отново, защото цикълът е точно начинът, по който сгрешена парола става заключен акаунт.
Една последователност, в реда, в който клиентът пита
Стартирайте клиента интерактивно веднъж и запишете всяка подкана в реда, в който се появява. Този транскрипт става файл с отговори. Когато пренасочите файла към бинарния файл, първият ред трябва да е самата команда за свързване, затова последователността започва с име на хост, а не с потребителско име.
connect vpn.example.com
0
<username>
<password>
y
exit
Голият 0 избира първия профил за свързване, когато шлюзът предлага списък; използвайте индекса, който вашият шлюз отпечатва. y приема банер за вход, така че изтрийте този ред, ако няма банер, и вмъкнете ред там, където шлюзът ви задава допълнителен въпрос. exit в края позволява на клиента да завърши чисто, след като последният отговор е изразходван.
/opt/cisco/anyconnect/bin/vpn -s < anyconnect.txt
Неинтерактивният режим тук не е по избор. Без -s клиентът може да поеме терминала и да игнорира пренасочения вход; с него отговорите се четат от потока и процесът връща. Където бинарният файл изисква повишени права, обвийте извикването в sudo -n, за да се провали скриптът веднага, вместо да блокира на подкана за парола.
Къде файлът с отговори изтича
Файл, който съдържа парола, е идентификационни данни, затова му дайте правата на такива: режим 600, собственост на акаунта, който изпълнява задачата, и никога в споделена или синхронизирана директория. Създайте го с вече приложен режим, вместо да го поправяте после, защото файлът е за кратко четим от всички между записа и chmod.
install -m 600 /dev/null ~/.config/anyconnect.txt
chmod 700 ~/.config
Другата половина е argv. Парола, подадена като аргумент, е видима за всеки локален потребител, който изброява процеси, и също попада в историята на шела. Четете я от файлов дескриптор или от променлива на средата вместо това и слагайте полезния товар в кавички, за да не може шелът да разгърне нищо вътре.
printf '%s\n' 'connect vpn.example.com' '0' "$VPN_USER" "$VPN_PASS" 'y' 'exit' \
| sudo -n /opt/cisco/anyconnect/bin/vpn -s
Внимавайте с кавичките. В двойни кавички парола, съдържаща !, може да бъде разгърната от интерактивен шел, преди клиентът изобщо да я види, а отказът идва като обща грешка event-not-found, която изглежда като проблем с протокола.
Докажете тунела, после го затворете
Състоянието свързано доказва само, че клиентът вярва, че има сесия. Изберете хост, който отговаря само от вътрешността на корпоративната мрежа, и го пробвайте веднъж, преди да правите каквото и да е друго. Отказ там е проблем с маршрутизацията или политиката и повторното пускане на входа няма да го промени.
/opt/cisco/anyconnect/bin/vpn state
curl -sS -o /dev/null -w '%{http_code}\n' --max-time 10 https://<internal-host>/
/opt/cisco/anyconnect/bin/vpn disconnect
Проверете изхода на състоянието преди и след прекъсването. Клиент, оставен със застояла сесия, може да откаже следващото свързване, докато скриптът все още отчита успех, и този режим на отказ е невидим, ако гледате само кодовете за изход. Сравнете двете четения, вместо да се доверявате на второто само по себе си. Псевдонимите в профила на шела са достатъчни за ежедневна употреба, докато всичко планирано заслужава същия преглед на идентификационните данни и самоличността като всяка друга задача без надзор.
Когато фиксиран списък престане да е безопасен
Файлът с отговори кодира днешния ред на подканите. Променен банер, принудителна смяна на парола или предизвикателство за втори фактор го превръща в цикъл, който може да заключи акаунта, затова скриптът трябва да излезе при първия неочакван отговор, вместо да рестартира.
Запишете какво е отпечатал клиентът, върнете ненулев статус и оставете викащия да реши. Там, където шлюзът изисква втори фактор, честният отговор е, че вход без надзор не е наличен за този профил, а не че последователността се нуждае от още един ред.
Ротацията принадлежи към същия преглед. Ако идентификационните данни се съхраняват, решете кой може да ги чете, кога се сменят и какво ги премахва при преизграждане на хоста. Скрипт, който работи година, защото никой не е пипал паролата, не е дизайн, а инцидент, който чака политика за ротация.
Профили, които не са AnyConnect
Два по-стари стила на Cisco идентификационни данни се бъркат с този. Профил vpnc иска IPSec ID, което всъщност е името на групата, после тайна на групата, после вашите собствени данни, и трите идват от този, който управлява шлюза. Старият Cisco IPsec е различен протокол от AnyConnect, затова vpnc не може да достигне услуга само за AnyConnect; openconnect --protocol=anyconnect е отвореният клиент за тази работа.
Файл .pcf описва профила на по-стария клиент. Хостът, името на групата и груповата парола в него могат да се въведат отново на ръка в клиент, който говори Cisco IPsec, макар файлът да не е универсален импорт и всеки нестандартен порт или режим на тунелиране обикновено изчезва при преноса.
Започнете от това, което шлюзът действително предлага, после изберете клиента, който говори този протокол. Копирането на профил от друг сайт е начинът, по който хората стигат до дебъгване на идентификационни данни, които никога не са били проблемът.