Клиент 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, хотя файл не является универсальным импортом и любой нестандартный порт или режим туннелирования обычно теряется при переносе.

Начните с того, что шлюз действительно предлагает, затем выберите клиент, который говорит на этом протоколе. Копирование профиля с другого сайта — это путь, которым люди приходят к отладке учётных данных, которые никогда не были проблемой.

Похожие статьи