Теги развёртывания — обычная причина, по которой люди берутся за эту функцию: каждое соединение должно нести что-то вроде площадки или роли, а сервер должен читать это, не изобретая второй формат учётных данных. В общественном OpenVPN механизм уже есть, и он небольшой. Болезненная часть — ожидания. Установка обычной переменной в профиле клиента ничего не делает на сервере, а значение, которое всё же доходит, доказывает только то, что клиент его отправил.

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

Задайте переменную и включите путь

Две строки выполняют работу в профиле клиента, и обе нужны. Без первой нечего отправлять; без второй клиент вообще не предлагает информацию о пирах. Порядок не важен, и это стоит знать, потому что обе строки часто оказываются в разных частях сгенерированного профиля. Важно, чтобы обе пережили любую перезапись профиля до того, как клиент его прочитает.

setenv UV_DEPLOY field-support
push-peer-info

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

Одна практическая проверка уместна здесь, а не в конце: убедитесь, что директива доходит до бинарного файла клиента и не проглатывается обёрткой. Графический клиент, который сам формирует командную строку, или интерфейс управления, который перезагружает сохранённый профиль, может отбросить строки, которых не узнаёт. Если сервер ничего не видит, это первое место, куда стоит посмотреть.

Прочитайте поле из хука сервера

На стороне сервера полученная информация о пире проверяется и вставляется в окружение рабочего процесса соединения, и именно это делает её читаемой из хука без какой-либо вашей работы с протоколом. Серверу не нужно разбирать канал управления или что-то хранить для вас; значение просто присутствует, пока устанавливается соединение. Минимальный скрипт client-connect, который записывает метку рядом с аутентифицированным именем, выглядит так.

#!/bin/sh
# /etc/openvpn/server/hooks/label.sh
printf '%s %s\n' "$common_name" "${UV_DEPLOY:-unset}" \
  >> /var/log/openvpn/deploy-labels.log

Читайте переменную через окружение, а не разбирая журнал, и всегда давайте ей значение по умолчанию. ${UV_DEPLOY:-unset} сохраняет работоспособность скрипта для клиентов, которые никогда не отправляют поле, что является нормальным состоянием при поэтапном развёртывании. Не выливайте всё окружение в журнал, чтобы найти имя; там гораздо больше, чем метка, включая значения, которые вы не собирались сохранять.

Запустите скрипт вручную, и он сообщит unset для всего, потому что ручная оболочка не несёт окружение соединения. Это не ошибка скрипта и не доказательство того, что поле отсутствует. Проверьте его через реальное соединение — единственный контекст, в котором переменная существует.

Проверьте, что действительно пришло

Подключите одного клиента с меткой и одного без неё, затем прочитайте файл. Пара и есть тест: одна строка должна нести значение, а другая — значение по умолчанию, и обе должны называть одну и ту же аутентифицированную личность, которую вы ожидаете.

tail -n 5 /var/log/openvpn/deploy-labels.log
# field-support deployed-client-07
# unset         legacy-laptop-02

Эти строки комментариев — форма вывода, а не расшифровка с вашего сервера; читайте свой собственный файл. Если второй клиент тоже показывает значение, переменная задана где-то ещё в окружении, и вы читаете устаревшую настройку, а не поле пира.

Проверьте также журнал сервера для этого соединения. Информация о пире может появиться там, что удобно для отладки и является причиной держать значения скучными: без имён людей, без номеров заявок, ничего такого, что вы не хотели бы показать читателю журнала.

Относитесь к метке как к утверждению, а не как к личности

Любой, кто может редактировать профиль клиента, может изменить метку, и то, что туннель аутентифицирован, не делает метку полномочной. Транспорт защищает значение в пути; он не удостоверяет утверждение. Авторизация по-прежнему принадлежит аутентифицированной личности и записи о регистрации, которой владеет сервер, а метка сравнивается с этой записью, когда это важно.

Это различие решает, где метку можно использовать. Хорошие применения — направлять сеанс в нужный файл журнала, выбирать группу отображения на панели или помечать сеанс поддержки, чтобы человек мог найти его позже. Плохие применения — пускать устройство в подсеть, выбирать политику межсетевого экрана или решать, какие данные клиента сеанс может читать.

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

case "${UV_DEPLOY:-}" in
  field-support|field-qa|lab) : ;;
  *) UV_DEPLOY=unknown ;;
esac

Откатите аккуратно

Удаление функции — это два удаления и одна проверка. Удалите строки setenv и push-peer-info из профиля клиента, затем удалите или отключите хук и его цель журнала на сервере.

grep -rn 'UV_DEPLOY\|push-peer-info' /etc/openvpn/
tail -n 3 /var/log/openvpn/deploy-labels.log

После этого подключите одного клиента заново и убедитесь, что строка журнала перестала появляться. Хук, который продолжает срабатывать после изменения профиля, обычно оказывается вторым профилем, всё ещё развёрнутым на тестовом устройстве, и найти его сейчас дешевле, чем во время аудита.

В конце остаётся небольшой, ограниченный фрагмент метаданных сеанса с задокументированным происхождением: клиент заявляет его, сервер записывает, и ничего в доступе от него не зависит. Это полезная версия функции, и для неё не нужны новые учётные данные.

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