Настройка доступа по VPN¶
Пошагово: что нажать в админке и что сделать на машине сотрудника. Что это за
цель и чем она отличается от user_mtls — в обзоре раздела.
Серверная сторона OpenVPN (ca, crl-verify, проверка имени) описана
отдельно — «Приёмники сертификатов».
Шаг 1. Направьте цель в её удостоверяющий центр¶
Откройте Настройки → Удостоверяющие центры и задайте цели vpn её точку
монтирования и роль. Во встроенном УЦ это pki_vpn и роль vpn — таблица
соответствий целиком в разделе «Встроенный
УЦ».
У цели vpn, как и у user_mtls и k8s, нет запасного пути: без явно
настроенного и включённого профиля издателя заявки отклоняются. Запасной
издатель из переменных окружения есть только у wifi.
В установке, поднятой набором развёртывания из выпуска (first-up.sh), этот шаг уже сделан:
строка «VPN (OpenVPN)» приходит настроенной на свой промежуточный УЦ
Alatyr VPN Issuing CA. Проверьте его и переходите к шагу 2.
Результат. В списке профилей у строки vpn заданы своя точка монтирования
и своя роль, кнопка проверки связи отвечает успехом.
Шаг 2. Разрешите выдачу¶
Откройте Настройки → Политика выдачи и включите строку «VPN (OpenVPN)» в колонке «Выдаём».
У каждой цели здесь свой переключатель, и включение одной не требует включения
другой: чтобы выдавать vpn, включать «mTLS пользователя» не нужно.
«Выдаём» на двух вкладках — это разные переключатели
На вкладке «Политика выдачи» колонка «Выдаём» означает «просить ли у агентов эту цель»: выключено — агенты её не запрашивают, заявок не появляется. На вкладке «Удостоверяющие центры» та же колонка означает «кто подписывает эту цель»: выключено — заявки копятся в очереди и не подписываются.
Результат. В колонке «Готовность» у строки vpn стоит «Готов —
политика разрешает, ЦА настроен».
Шаг 3. Назначьте цель устройству¶
Откройте Устройства, раскройте строку машины и назначьте ей цель vpn.
Назначение цели и разрешение её выдавать — разные действия, нужны оба.
Результат. Через несколько минут агент на машине сотрудника заведёт ключ в чипе и подаст заявку.
Шаг 4. Одобрите заявку¶
Откройте раздел Запросы. Заявка на vpn появится в статусе pending —
проверьте, чьё это устройство и чей адрес в заявке, и одобрите её.
Автоодобрению цель vpn по умолчанию не открыта
Сертификат vpn утверждает личность человека. Сервисный аккаунт с
ролью cert-auto-approver может одобрять только те цели, которые
администратор перечислил ему явно; умолчание списка — ровно wifi.
Результат. Сертификат выдан, и агент положил его туда, откуда его заберёт
клиент OpenVPN: на Windows — в хранилище пользователя CurrentUser\My, на
Linux — в токен PKCS#11, на macOS — рядом с ключом в Secure Enclave.
Шаг 5. Спросите машину, чего ей не хватает¶
На машине сотрудника есть команда, которая печатает построчно, что уже есть, чего нет и какие строки добавить в профиль клиента:
alatyr-agent vpn
Команда ничего не устанавливает, не подключается и не трогает PIN. Если цель не готова, команда завершается ненулевым кодом — чтобы её можно было поставить в проверку, а не только прочитать глазами.
Linux¶
Отчёт проверяет четыре вещи и на каждую отвечает отдельно:
| Что проверяется | Чем лечится отказ |
|---|---|
Клиент openvpn найден |
поставить пакет openvpn; учтите, что он лежит в /usr/sbin, которого нет в PATH неинтерактивного сеанса |
Клиент собран с enable_pkcs11=yes |
нужен другой клиент: без PKCS#11 аппаратный ключ ему недоступен |
Найден модуль PKCS#11 libtpm2_pkcs11.so |
в Debian/Ubuntu — пакет libtpm2-pkcs11-1 |
| В токене есть сертификат цели | цель назначена и заявка одобрена (шаги 3 и 4) |
Дополнительно отчёт предупреждает о двух вещах, которые он не может исправить сам:
TPM2_PKCS11_STOREне наследуется юнитом systemd. Самому отчёту это не мешает — он подставляет путь сам, — а клиенту помешает. В юнит добавляется строкаEnvironment=TPM2_PKCS11_STORE=/var/lib/alatyr-agent/pkcs11-store.- Отзыв живёт на сервере. Без
crl-verifyсо свежим списком отозванный сертификат продолжает подключаться, и агент на это не влияет.
Когда всё сошлось, команда печатает готовый фрагмент профиля — две строки:
pkcs11-providers /usr/lib/x86_64-linux-gnu/pkcs11/libtpm2_pkcs11.so
pkcs11-id '<сериализованный идентификатор объекта>'
Идентификатор клиент сравнивает дословно, поэтому копировать его надо из вывода команды целиком, а не собирать руками.
PIN токена клиент спросит в консоли.
Linux: необслуживаемый запуск¶
Там, где клиент поднимает служба, консоли нет и спросить PIN не у кого.
Добавьте к команде --unattended:
alatyr-agent vpn --unattended
К фрагменту профиля добавятся три строки, и они обязательны вместе:
management 127.0.0.1 7505
management-query-passwords
management-hold
PIN приходит клиенту через этот служебный канал, а не через диалог. Две подробности, каждая из которых стоила прогона:
management-holdобязателен. Без него клиент начинает рукопожатие раньше, чем отвечающая сторона подключилась, и первый запрос PIN уходит в консоль, которой у службы нет.- Запрос приходит по метке токена, а не по слову «PIN», и тег в ответе
обязан совпасть дословно — например,
wifi-cert-agent token. Ошибка в теге выглядит как зависание, а не как отказ.
Интерфейс управления слушает петлю 127.0.0.1 намеренно: он принимает PIN без
пароля, и внешний адрес отдал бы ключ любому, кто дотянется до порта.
Метку токена, путь к модулю и каталог хранилища можно задать флагами
--token-label, --provider и --store — это нужно только на хосте с
нестандартной установкой.
Windows¶
Клиент — community OpenVPN GUI (openvpn.exe 2.6 из дистрибутива
openvpn.net). Официальный OpenVPN Connect не годится — почему, разобрано в
«Нюансах и пределах».
Считыватель и смарт-карта для VPN не нужны: ключ цели vpn лежит в TPM, в
контейнере CNG, и в хранилище Windows его находит сам клиент.
Профиль сотруднику готовить не нужно — агент кладёт его сам.
Что делает администратор (один раз)¶
В админке, в разделе «Профиль VPN», вставьте базовый профиль вашего
сервера доступа целиком — без строки cryptoapicert и без данных
конкретного сотрудника, это допишет агент. Сервер проверяет основу списком
разрешённых директив и при отказе отвечает номером неподходящей строки:
исполняемые директивы (up, plugin, script-security и подобные) и
собственный клиентский ключ в основе профиля запрещены — агент подставляет
ссылку на ключ в TPM сам.
Пример базового профиля:
client
dev tun
proto udp
remote vpn.example.com 1194
nobind
remote-cert-tls server
verify-x509-name vpn.example.com name
<ca>
... корень, которым подписан сертификат ВАШЕГО сервера доступа ...
</ca>
Что делает агент (на машине сотрудника)¶
Агент — машинной половиной, от имени SYSTEM, — раз в такт проверяет цель
vpn: если она назначена и одобрена, дописывает к основе строку с отпечатком
сертификата из хранилища вошедшего пользователя
cryptoapicert "THUMB:<отпечаток сертификата>"
и кладёт готовый профиль в C:\Program Files\OpenVPN\config\ — писать туда
может только SYSTEM, поэтому и делает это машинная половина, а не сам
сотрудник. Если цель снята или отозвана, агент профиль убирает. PIN на этом
пути не спрашивается вовсе: ключ CNG под платформенным провайдером
открывается без ввода. Это разница механизмов, а не настройки, — на Linux PIN
токена спрашивается.
Диагностика:
| Что проверяется | Чем лечится отказ |
|---|---|
Найден openvpn.exe |
поставить community OpenVPN GUI — официальный OpenVPN Connect директиву cryptoapicert не поддерживает |
Каталог C:\Program Files\OpenVPN\config\ есть и профиль в нём появился |
цель назначена и заявка одобрена (шаги 3 и 4); в «Профиль VPN» задана основа; журнал агента — раздел про профиль VPN |
| В хранилище пользователя есть сертификат цели | то же самое: без сертификата агенту нечем дополнить основу |
Ключ лежит в контейнере CNG alatyr-agent-vpn |
это состояние здоровья: ключ не покидает TPM |
Результат. В трее OpenVPN GUI «Подключить» → значок зелёный, в журнале
клиента Initialization Sequence Completed, на сервере — CN сотрудника.
macOS¶
Путь PKCS#11 на macOS закрыт подписью клиентов (разбор — в «Нюансах и
пределах»),
поэтому ключ отдаётся иначе: openvpn присылает агенту по локальному сокету
хэш рукопожатия, агент подписывает его ключом Secure Enclave. Ключ анклав не
покидает, а сам openvpn не загружает ничего стороннего.
Клиент — openvpn 2.5 или новее из командной строки: brew install
openvpn либо бинарь, который уже лежит внутри Tunnelblick
(/Applications/Tunnelblick.app/Contents/Resources/openvpn/openvpn-2.6.*/openvpn).
Графический Tunnelblick и OpenVPN Connect этим путём не пойдут.
Отчёт:
alatyr-agent vpn
| Что проверяется | Чем лечится отказ |
|---|---|
Найден openvpn 2.5+ |
brew install openvpn либо бинарь из Tunnelblick; 2.4 этого не умеет |
| Есть сертификат цели | цель назначена и заявка одобрена (шаги 3 и 4) |
| Ключ в Secure Enclave соответствует сертификату | если нет — сертификат выписан на другой ключ (обычно после переустановки агента) |
Когда всё сошлось, команда печатает строки для профиля — они заменяют key:
cert "/Users/<кто>/Library/Application Support/AlatyrAgent/vpn/<почта>.user.crt.pem"
management "/var/run/alatyr-openvpn-<uid>.sock" unix
management-client-user <кто>
management-hold
management-external-key nopadding
Что делает каждая строка:
management … unix—openvpn(он работает от root) слушает локальный сокет в системном каталоге, куда обычный пользователь писать не может;management-client-user— подключиться к сокету разрешено только этому сотруднику;management-hold—openvpnждёт, пока агент подключится, и только потом начинает соединение;management-external-key nopadding— закрытого ключа уopenvpnнет, подпись он просит по сокету.nopaddingобязателен: без него сборкиopenvpnна OpenSSL 1.1.1 отказываются стартовать с ключом ECDSA и TLS 1.3.
Подключение — два шага. Поднять туннель от root (туннельный интерфейс требует прав):
sudo openvpn --config ~/vpn/work.ovpn
и в сеансе сотрудника запустить подписывающую сторону:
alatyr-agent vpn serve-key
Порядок не важен: serve-key ждёт, пока openvpn откроет сокет, и после
остановки туннеля ждёт следующего запуска.
serve-key отдаёт подпись только процессу root на том конце сокета —
учётку проверяет ядро, а подменить сокет в системном каталоге пользователь не
может. Другой процесс сотрудника подписать этим ключом не сможет — ровно как и
без сокета.
Если туннель не поднимается¶
Отчёт зелёный, а туннеля нет — на Windows. Две причины, и обе выглядят
одинаково — openvpn.exe не запускается, журнала нет:
- профиль лежит в пользовательском каталоге, а сотрудник не в группе
OpenVPN Administrators— GUI показывает диалог «requires membership in "OpenVPN Administrators" group»: подробнее; - профиль с одним и тем же именем лежит сразу в машинном и пользовательском каталогах: «Дубль имени профиля».
OpenVPN Connect пишет «No hardware tokens found». Так и должно быть: вкладка
Hardware Tokens ищет токены PKCS#11, а ключ Alatyr на Windows лежит в TPM.
Нужен другой клиент — разбор.
Сервер пускает сертификат другой цели. Проверьте проверку издателя на сервере — «Приёмники сертификатов».
Клиент не находит ключ на Linux. Строку pkcs11-id клиент сравнивает
дословно — сверьте её с выводом alatyr-agent vpn, а не с собственной записью.
Вторая частая причина — TPM2_PKCS11_STORE, не доехавший до юнита.
Клиент запрашивает «внешний сертификат» и не видит ключа. Это OpenVPN Connect: платформенные хранилища он не читает. См. «Нюансы и пределы».
Сотрудник подключается отозванным сертификатом. Отзыв у OpenVPN действует
только через crl-verify на вашем сервере — «Приёмники
сертификатов».
Что дальше¶
- Нюансы и пределы — где путь упирается в клиента, а не в Alatyr.
- Приёмники сертификатов — серверная сторона.