Агенты¶
Эта страница — про то, как ведёт себя агент на каждой ОС уже после установки: структура CLI-подкоманд, где именно живёт ключевой материал, какие процессы постоянные, а какие — по таймеру, и переключатели, которыми администратор может отключить установку сетевых профилей самим агентом. Про сборку/подпись пакетов и сами шаги установки — см. Установка → Агент.
Отдельная, параллельная подсистема — SSH Key Registry (регистрация сырых hardware-backed SSH-ключей, реестр principal → ключ, Keyholder API) — на этой странице не дублируется, только упоминается там, где пересекается с общим CLI/процессной моделью. Полный разбор — SSH Key Registry. Поведение самого hardware ssh-agent'а по ОС, включая интерактивное подтверждение доступа на macOS, описано ниже — в разделе «Поведение по ОС».
Структура CLI-подкоманд¶
Один бинарь alatyr-agent (alatyr-agent.exe на Windows), общий для всех
трёх ОС; часть подкоманд платформозависима — на платформе, где подкоманда
не поддержана, она всё равно зарегистрирована (не «unknown command»), но
сразу возвращает понятную ошибку вместо попытки что-то сделать.
| Подкоманда | Кто запускает | Платформы | Назначение |
|---|---|---|---|
run |
Планировщик (systemd timer / Scheduled Task / LaunchAgent), периодически | Все | Основной цикл: enroll → ожидание одобрения → установка сертификата и сетевого профиля. Короткоживущий процесс — стартует, делает один цикл, выходит. |
status |
Оператор вручную | Все | Печатает текущее состояние FSM из state.json (стадия, DeviceID, RequestID, серийный номер и срок действия сертификата, если есть). |
reset |
Оператор вручную | Все | Сбрасывает состояние в INIT (следующий run начнёт enroll заново) и на Linux дополнительно освобождает TPM-резидентный объект и pkcs11-store — чтобы не оставлять «осиротевшие» TPM-слоты. |
version |
Оператор / скрипты | Все | Версия сборки агента. |
ssh-agent |
Собственный always-on процесс (LaunchAgent с KeepAlive) |
Только macOS. На Windows и Linux подкоманда зарегистрирована, но возвращает ошибку: там ssh-agent работает внутри процесса user-agent, отдельного юнита для него нет. |
Держит Unix-сокет hardware ssh-agent'а весь свой жизненный цикл. |
user-agent |
Собственный постоянный процесс (systemd --user юнит на Linux, отдельная задача на Windows) |
Windows, Linux | Выпуск пользовательского ключа (user_mtls) в контексте залогиненного пользователя, когда сам run работает от системной учётной записи и до пользовательского контекста доступа не имеет. На macOS не нужен — используется уже существующий per-user LaunchAgent. |
secretd |
Собственный постоянный systemd-сервис | Только Linux | D-Bus secret-agent для NetworkManager — отдаёт PIN TPM PKCS#11-токена при активации 802.1X-соединения. Работает независимо от таймера run, потому что NetworkManager может запросить PIN в любой момент, не только на очередном цикле run. |
print-active-session-user |
Postinstall-скрипт пакета, не оператор | Только Linux | Внутренняя утилита: определяет логин активной interactive-сессии для автозаполнения CORP_EMAIL при установке. |
Поведение по ОС¶
macOS — Secure Enclave, per-user¶
Ключ подписи создаётся в Secure Enclave и живёт в data-protection
keychain залогиненного пользователя — поэтому агент на macOS
устанавливается и работает как per-user LaunchAgent, не как
per-machine LaunchDaemon. Каждый пользователь на одной машине проходит
enroll отдельно и получает свой сертификат; на headless-машине без
активной GUI-сессии сертификат не выпустится вообще, потому что SE-ключ
держит secd, а secd работает только внутри GUI-сессии.
После выпуска сертификата агент сам молча привязывает его к каждому сконфигурированному SSID в user-keychain залогиненного пользователя; в system-keychain — дополнительно, best-effort, только если агент выполняется с правами root — без этого macOS показывал бы пользователю диалог «Выберите сертификат для сети» при каждом подключении.
ssh-agent — единственная подкоманда, у которой на macOS есть отдельный
всегда-работающий процесс с собственным LaunchAgent (KeepAlive, без
StartInterval), не завязанный на периодический тик run.
По умолчанию окно доверия выключено (ssh_unlock_window_minutes = 0 по
умолчанию) — каждая подпись проходит обычную проверку присутствия
пользователя (Touch ID или пароль), которую обеспечивает сам Secure
Enclave. Администратор может включить окно, задав значение от 1 до 5 минут
в настройках (верхнюю границу задаёт сама macOS). Когда окно включено,
перед подписью, не покрытой ещё действующим разрешением, агент показывает
уведомление с выбором «1 минута» / «5 минут» / «Отказать»; выбор
дополнительно подтверждается биометрией или паролем — не одним лишь
фактом тапа по уведомлению. Отказ, закрытие уведомления без ответа или
истечение времени ожидания трактуются как «нет разрешения» — текущая
подпись всё равно проходит обычную проверку присутствия.
Windows — TPM 2.0, per-machine¶
Ключ создаётся в TPM 2.0 — на Windows это аппаратное хранилище
выполняет ту же роль, что Secure Enclave на macOS, и дополнительно даёт
аттестацию через AK (attestation key). Хранится per-machine, не per-user:
основной run работает от SYSTEM через
Scheduled Task (HighestAvailable, обязателен для доступа к TPM).
Пользовательский контекст (выпуск user_mtls/AD-логона) выполняет
отдельный процесс — подкоманда user-agent — потому что процесс SYSTEM
структурно не имеет доступа к пользовательской сессии; передача
enrollment-токена между ними идёт через DPAPI-защищённый handoff-файл с
retry/backoff.
В том же процессе user-agent работает и Windows-реализация hardware
ssh-agent'а (именованный pipe) — в отличие от macOS, здесь для этого нет
отдельной подкоманды ssh-agent, она на Windows намеренно не
поддерживается и возвращает ошибку, объясняющую, что SSH-agent живёт
внутри user-agent. Подробности о регистрации SSH-ключей — на странице
SSH Key Registry.
Доменный вход по смарт-карте (ad_logon) использует отдельный
TPM Virtual Smart Card, создаваемый только когда ad_logon включён
для устройства — user_mtls-only машины остаются на обычном CNG-ключе с
PIN.
Linux — TPM 2.0 через tpm2-pkcs11¶
Ключ создаётся в TPM 2.0 через tpm2-pkcs11 (soft dependency — без
модуля агент использует программный fallback-ключ на диске). Как и на
Windows, пользовательский контекст обслуживает отдельный постоянный
процесс — здесь это user-agent, зарегистрированный как systemd --user
юнит (Restart=always), а не таймер. Он же поднимает Unix-сокет
hardware ssh-agent'а на Linux (не отдельная подкоманда ssh-agent, как
на macOS).
Дополнительно на Linux всегда работает системный сервис secretd
(см. таблицу подкоманд выше) — без него NetworkManager не сможет получить
PIN TPM-токена при активации 802.1X-соединения, независимо от того,
выполнил ли уже run очередной цикл.
На Linux нет интерактивного «окна доверия» для SSH-подписи — доступ к
authValue TPM-токена уже неинтерактивен (в отличие от Secure Enclave:
здесь просто нечего подавлять): каждая подпись и так проходит без
повторного запроса пользователя.
Продление сертификата¶
Продление не выделено в отдельный режим — это тот же самый цикл enroll, что и при первичной выдаче, и он одинаков на всех трёх ОС.
- По умолчанию срок действия машинного сертификата (
wifi) — 3 года; это единственная цель, у которой значение настраивается на сервере (см. Конфигурация). У остальных целей срок фиксированный:user_mtlsиad_logon— 1 год,ssh— 24 часа. - Скрипт-обёртка агента проверяет срок действия установленного
сертификата перед тем, как запустить
run. - Перевыпуск запускается, если сертификат отсутствует, уже истёк, либо до истечения остаётся меньше 30 дней — это окно одинаковое на macOS, Windows и Linux.
- Перевыпуск — не обновление существующей заявки: обёртка удаляет файл
локального состояния — агент стартует с нуля, как после подкоманды
reset(см. таблицу подкоманд выше), — и заново проходит enroll, создавая новую заявку. Терминальные статусы прежней заявки — отклонена или сертификат отозван — тоже сбрасывают состояние агента, чтобы он не опрашивал бесконечно уже мёртвую заявку. - Следствие для планирования: новая заявка проходит ту же проверку одобрения, что и первичная. При ручном одобрении это означает периодическую волну заявок на одобрение по мере того, как у устройств флота подходит срок действия сертификата — см. Эксплуатация. При настроенном автоодобрении (см. Администрирование → Approve / reject / revoke заявок) дополнительных ручных действий не требуется.
- Автоматическое продление сейчас работает только для машинного
сертификата (
wifi) — именно его срок проверяется на каждом запуске. Сертификатыuser_mtls,ad_logonиsshпо истечении срока автоматически не перевыпускаются; их обновление требует повторной регистрации.
Отключение установки сетевых профилей агентом¶
Всего есть четыре переключателя, не устанавливающих сетевой профиль самим агентом, — один fleet-wide и три per-network; все они рассчитаны на флоты, где Wi-Fi/802.1X-профили раскатываются внешним MDM/GPO/config management, а не агентом:
Fleet-wide, только macOS — ALATYR_MACOS_AGENT_PROFILE_DISABLED
(переменная окружения сервера, см. Конфигурация):
когда включена, сервер вообще не отдаёт macOS .mobileconfig в ответе
агенту (GET /requests/:id/certificate) ни для одной сети — агент ставит
только SE-ключ и bind сертификата, без собственного open .mobileconfig.
На admin bundle ZIP (GET /certificates/:serial/bundle) не влияет — это
артефакт для ручной настройки MDM, там профиль всегда полный.
Per-network, все три ОС — три отдельных переключателя на каждой записи сети в Admin UI (столбец «Распространять профиль через агента»):
| ОС | Что отключает | Эндпоинт |
|---|---|---|
| macOS | Эту сеть — из объединённого .mobileconfig (wifi — исключается из списка SSID; wired — профиль целиком обнуляется, активна только одна wired-сеть) |
PUT /admin/networks/:id/macos-agent-profile-disabled |
| Windows | Эту сеть — из windows_profiles (закрывает конфликт: netsh wlan add profile иначе перезатирает GPO-профиль с тем же именем/SSID при каждом reconcile) |
PUT /admin/networks/:id/agent-profile-disabled, {"os":"windows","disabled":bool} |
| Linux | Эту сеть — через отдельный список linux_disabled_ssids в ответе сервера; агент вычитает эти SSID из enabled_ssids локально перед передачей в NetworkManager (сам enabled_ssids при этом не меняется) |
PUT /admin/networks/:id/agent-profile-disabled, {"os":"linux","disabled":bool} |
Переключатель меняет только то, кто устанавливает профиль. Сеть
по-прежнему числится в enabled_ssids и остаётся видна агенту — просто
профиль для неё агент больше не ставит.
Все три per-network-переключателя входят в расчёт bundle_version:
изменение флага меняет bundle_version только у затронутого устройства, и
переустанавливает профиль тоже только оно. Fleet-wide-переключатель в
bundle_version не входит — он применяется при формировании ответа
сервера, чтобы Windows- и Linux-агенты не видели ложных изменений версии
из-за macOS-only флага. Admin bundle ZIP не фильтруется ни одним из
четырёх переключателей.
«Забыть сеть» — известное платформенное ограничение
Когда у сети включён хотя бы один из переключателей, Alatyr не может программно удалить/забыть профиль, распространяемый извне (MDM/GPO/config management) — Admin UI показывает предупреждение при попытке отключить/удалить такую сеть; убрать профиль нужно вручную через соответствующую консоль.
Управление самими сетями (cert-admin) — Администрирование →
Сети.