Перейти к содержанию

Настройка доступа по 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 на вашем сервере — «Приёмники сертификатов».

Что дальше