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

Конфигурация

Справочник переменных окружения сервера Alatyr: что задать, что можно не трогать и что сервер проверяет при старте.

Флаги и переменные агента (WIFI_CERT_SERVER, CORP_DOMAIN, CORP_EMAIL) — на странице Установка → Агент. Настройки, которые живут не в окружении, а в базе и правятся в админке (издатели, политика выдачи, ступени подтверждения, разрешённые сети Keyholder), — в разделах по целям и в «Управление и роли».

Два правила, действующие на все переменные ниже

1. У любой переменной есть форма <ИМЯ>_FILE. Значение тогда читается из указанного файла, а не из окружения. Для секретов это предпочтительный способ: переменная окружения видна в docker inspect и в /proc/<pid>/environ, файл — нет.

VAULT_SECRET_ID_FILE=/run/secrets/vault_secret_id

Правила строгие, потому что это путь для секретов:

  • заданы оба источника сразу (и VAULT_SECRET_ID, и VAULT_SECRET_ID_FILE) — ошибка запуска, а не «победит один из них»;
  • файла нет, он не читается или пуст — тоже ошибка запуска;
  • хвостовой перевод строки срезается (echo secret > file добавляет его всегда, а невидимый \n в secret_id даёт отказ Vault без объяснения).

2. У части переменных есть старые имена. Имена вида WIFI_CERT_* и совсем короткие (DB_URL, SERVER_PORT) продолжают работать. Если задано старое имя, а нового нет, сервер пишет в журнал <СТАРОЕ> is deprecated, use <НОВОЕ>. Заданы оба — выигрывает каноническое ALATYR_*.

Минимальная конфигурация

Чтобы сервер стартовал, безусловно обязательна одна переменная:

Переменная Зачем
ALATYR_DB_URL Строка подключения к PostgreSQL. Без неё сервер не стартует.

Ещё несколько становятся обязательными условно — только если включена соответствующая функция:

Переменная Обязательна, когда
ALATYR_WEBHOOK_ENC_KEY включены вебхуки (ALATYR_WEBHOOKS_ENABLED=true)
ALATYR_SCEP_URL, ALATYR_SCEP_CHALLENGE, ALATYR_SCEP_CA_FINGERPRINT, ALATYR_SCEP_ENC_KEY выбран SCEP-издатель (ALATYR_ISSUER=scep)
ALATYR_K8S_BROKER_TLS_CERT, ALATYR_K8S_BROKER_TLS_KEY включён брокер Kubernetes (ALATYR_K8S_BROKER_LISTEN задан)

Сервер стартует и без настроенного Vault, но тогда подписание сертификатов будет падать, пока Vault не сконфигурирован. Это предупреждение в журнал, не фатальная ошибка — см. «Проверки при старте».

Всё остальное на этой странице имеет значение по умолчанию и нужно для тонкой настройки.

Сервер: базовые параметры

Переменная Старые имена По умолчанию Описание
ALATYR_SERVER_PORT WIFI_CERT_SERVER_PORT, SERVER_PORT 8090 Порт HTTP.
ALATYR_DB_URL WIFI_CERT_DB_URL, DB_URL — (обязательна) Строка подключения к PostgreSQL, например postgres://user:pass@host:5432/alatyr.
ALATYR_CORS_ORIGINS WIFI_CERT_CORS_ORIGINS, CORS_ORIGINS — Разрешённые CORS-origin через запятую. Пусто — только localhost-порты для разработки.
ALATYR_TRUSTED_PROXIES — — CIDR обратных прокси, чьему X-Forwarded-For сервер верит. См. пояснение ниже.
ALATYR_LOG_LEVEL WIFI_CERT_LOG_LEVEL, LOG_LEVEL info debug | info | warn | error.
ALATYR_DEFAULT_SSID WIFI_CERT_DEFAULT_SSID, WIFI_SSID CorpWiFi SSID, заводимый при первом старте, если список сетей пуст.
ALATYR_DEV_MODE WIFI_CERT_DEV_MODE, AUTH_DEV_MODE false Принимать Bearer dev-token как cert-admin без Keycloak. Никогда не включайте в рабочей установке.

ALATYR_TRUSTED_PROXIES пуст по умолчанию — и это важно за ingress

Пока список пуст, адресом вызывающего считается адрес TCP-пира, а заголовки не читаются вовсе. Под ingress Kubernetes трафик приходит в Service напрямую, поэтому у всех вызывающих оказывается один и тот же адрес — и любое ограничение по адресу (например, разрешённые сети Keyholder) превращается в общее разрешение на весь мир.

Перечисляйте CIDR только тех прокси, которые действительно стоят перед сервером: доверие лишнему возвращает подмену адреса. Неразобранная запись и сеть, покрывающая всё (/0), — отказ при старте, а не предупреждение: молчаливо несработавшая настройка безопасности хуже отсутствующей.

Вход в админку: локальная аутентификация

Сосуществует с Keycloak SSO — оба способа могут быть включены одновременно.

Переменная Старые имена По умолчанию Описание
ALATYR_LOCAL_AUTH_ENABLED WIFI_CERT_LOCAL_AUTH_ENABLED, AUTH_LOCAL_ENABLED false Включить вход по email и паролю наряду с Keycloak.
ALATYR_LOCAL_JWT_SECRET 🔒 WIFI_CERT_LOCAL_JWT_SECRET, LOCAL_JWT_SECRET — Секрет HS256 для подписи локальных сессий. Можно не задавать: сервер сгенерирует его при первом старте и сохранит, так что у каждой установки он свой. Заданный вручную обязан быть не короче 32 байт, иначе сервер не стартует.
ALATYR_LOCAL_ADMIN_EMAIL WIFI_CERT_LOCAL_ADMIN_EMAIL, LOCAL_ADMIN_EMAIL — Email первого администратора, создаваемого при пустой таблице пользователей.
ALATYR_LOCAL_ADMIN_PASSWORD 🔒 WIFI_CERT_LOCAL_ADMIN_PASSWORD, LOCAL_ADMIN_PASSWORD — Его пароль. Уберите из манифеста развёртывания после первого входа.
ALATYR_LOCAL_ACCESS_TTL_MIN WIFI_CERT_LOCAL_ACCESS_TTL_MIN, LOCAL_ACCESS_TTL_MIN 15 Срок жизни access-токена, минуты.
ALATYR_LOCAL_REFRESH_TTL_DAYS WIFI_CERT_LOCAL_REFRESH_TTL_DAYS, LOCAL_REFRESH_TTL_DAYS 30 Срок жизни refresh-токена, дни.

🔒 — значение помечено как секрет: в сгенерированных примерах и в журнале оно маскируется (<secret>) и никогда не печатается открытым текстом.

Keycloak

Переменная По умолчанию Описание
KEYCLOAK_URL — Базовый URL Keycloak.
KEYCLOAK_REALM — Realm.
KEYCLOAK_CLIENT_ID — OIDC client id.
KEYCLOAK_CLIENT_SECRET 🔒 — OIDC client secret (confidential client).

Издатель сертификатов: Vault или внешний SCEP CA

Переменная Старые имена По умолчанию Описание
ALATYR_ISSUER WIFI_CERT_ISSUER vault Чем выпускать: vault | scep.
ALATYR_SCEP_URL WIFI_CERT_SCEP_URL — URL внешнего SCEP CA. Обязателен при ALATYR_ISSUER=scep. Обязан быть https — см. ниже.
ALATYR_SCEP_CHALLENGE 🔒 WIFI_CERT_SCEP_CHALLENGE — SCEP challenge password. Обязателен при scep.
ALATYR_SCEP_CA_FINGERPRINT WIFI_CERT_SCEP_CA_FINGERPRINT — Ожидаемый отпечаток SHA-256 сертификата SCEP CA. Обязателен при scep.
ALATYR_SCEP_CA_IDENTIFIER WIFI_CERT_SCEP_CA_IDENTIFIER — Идентификатор CA для установок с несколькими CA (NDES).
ALATYR_SCEP_ENC_KEY 🔒 WIFI_CERT_SCEP_ENC_KEY — Ключ AES-256 (64 hex-символа) для шифрования состояния опроса SCEP. Обязателен при scep.
ALATYR_SCEP_POLL_SECONDS WIFI_CERT_SCEP_POLL_SECONDS 30 Интервал опроса ожидающих заявок SCEP, секунды.
ALATYR_SCEP_ALLOW_PLAINTEXT_URL — false Разрешить http:// в ALATYR_SCEP_URL.
ALATYR_SCEP_INTERNAL_CIDRS — — Сети, куда издателю SCEP разрешено ходить вопреки защите от SSRF: локальный ADCS/NDES всегда имеет частный адрес. Пусто — поведение не меняется. Link-local не разрешается никогда, даже если указан.

http:// до SCEP CA — отказ при старте, и снять его можно только явно

На открытом канале положение «в разрыве» подменяет ответ GetCACert целиком, а он определяет и получателей конверта, и корневой сертификат, который уезжает на каждую машину парка. Поэтому сервер с http://-адресом не стартует вовсе.

ALATYR_SCEP_ALLOW_PLAINTEXT_URL=true снимает этот отказ. Включайте только там, где путь до NDES защищён иначе; каждый запуск с этим послаблением пишет предупреждение в журнал.

При ALATYR_ISSUER=scep смотрите также Архитектура и PKI и Известные ограничения: у SCEP нет операции отзыва, а опрос заявок рассчитан на одну реплику сервера.

Vault

Переменная По умолчанию Описание
VAULT_ADDR — Адрес Vault.
VAULT_TOKEN 🔒 — Статический токен. Используется, когда VAULT_ROLE_ID пуст.
VAULT_ROLE_ID — AppRole role_id. Рекомендуемый способ для рабочей установки.
VAULT_SECRET_ID 🔒 — AppRole secret_id.
VAULT_PKI_MOUNT pki Точка монтирования PKI-движка.
VAULT_PKI_ROLE alatyr Имя роли PKI.
VAULT_CA_CERT_PATH — PEM-бандл для доверия TLS самого Vault.
VAULT_CERT_TTL_HOURS 26280 Срок выпускаемого сертификата в часах (3 года). Действует только на цель wifi и только пока срок не задан в профиле издателя; у остальных целей срок берётся из профиля.

Эти значения — запасные. У каждой цели (wifi, user_mtls, ad_logon, ssh, k8s, vpn) есть свой профиль издателя с собственными адресом, точкой монтирования, ролью и сроком; он правится в админке на вкладке Настройки → Удостоверяющие центры и имеет приоритет над переменными выше. Как развернуть встроенный УЦ и направить в него цели — «Встроенный УЦ».

Каталог (LDAP/AD): SID для входа в домен по карте

Нужны там, где агенты стоят на недоменных хостах и на macOS: у них локальный SID домену неизвестен, а без SID сертификат для входа в домен непригоден.

Переменная По умолчанию Описание
ALATYR_DIRECTORY_URL — Адрес каталога, ldaps://dc.example.local:636. Пусто — каталог не настроен: маршрут /enroll/identity-sid не регистрируется, а перепроверка SID при выдаче ad_logon не производится.
ALATYR_DIRECTORY_BIND_DN — DN учётной записи привязки. Ей нужно право читать objectSid и больше ничего: сервер в каталог не пишет никогда.
ALATYR_DIRECTORY_BIND_PASSWORD 🔒 — Пароль этой учётной записи.
ALATYR_DIRECTORY_BASE_DN — Поддерево поиска, DC=example,DC=local. Из компонентов DC= выводится раздел конфигурации леса, где ищется точка распространения списков отзыва, — значение без DC= ломает доставку CRL.
ALATYR_DIRECTORY_INSECURE_SKIP_VERIFY false Не проверять сертификат контроллера домена. Только для тестовых установок с самоподписанным сертификатом: в это соединение уходит пароль привязки.
ALATYR_DIRECTORY_SID_DAILY_LIMIT 3 Сколько различных личностей одно устройство может разрешить в SID за сутки без участия человека. Границей служит число личностей, а не запросов: агент приходит каждый тик и счётчик запросов выел бы квоту за час. Личности с одобренным сертификатом и названные в задании администратора квоту не тратят. 0 запрещает самообслуживание целиком.
ALATYR_DIRECTORY_TIMEOUT_SECONDS 5 Потолок времени на подключение и поиск. Неотвечающий контроллер домена не должен подвешивать выдачу.

Что ещё настраивается в домене и в админке — Вход в домен по смарт-карте → Настройка.

Брокер доступа к Kubernetes

Переменная По умолчанию Описание
ALATYR_K8S_BROKER_LISTEN — Адрес отдельного TLS-слушателя брокера эфемерных credential для kubectl, например :8443. Пусто — брокер выключен целиком, и это штатное состояние. Слушатель отдельный, потому что он запрашивает клиентский сертификат, а выставлять на такой порт всю админскую поверхность незачем.
ALATYR_K8S_BROKER_URL — Адрес брокера, каким его видит устройство, например https://alatyr.corp:8443. Отдаётся агенту при опросе целей: слушатель живёт на своём порту, и угадать его устройство не может. Пусто — плагин kubectl скажет, что это развёртывание credential не выдаёт.
ALATYR_K8S_BROKER_TLS_CERT — PEM-файл серверного сертификата брокера. Обязателен, если задан ALATYR_K8S_BROKER_LISTEN.
ALATYR_K8S_BROKER_TLS_KEY 🔒 — PEM-файл закрытого ключа брокера. Обязателен вместе с предыдущим.

Пошагово — Доступ к Kubernetes → Настройка.

Аппаратное хранилище и аттестация

Переменная По умолчанию Описание
TPM_CA_DIR ./tpm-ca Каталог с доверенными сертификатами УЦ производителей TPM.
TPM_INTEL_EK_RECOVERY true Восстанавливать отсутствующие EK-сертификаты Intel PTT из сети (best-effort). Отключайте на серверах без выхода наружу.
TPM_INTEL_EK_SERVER_URL — Переопределить адрес сервиса Intel EK (зеркала, тесты).
TPM_REJECT_UNATTESTED false Отклонять ключи в TPM, для которых EK-сертификат недостижим.
TPM_REJECT_SOFTWARE false Отклонять заявки с platform=software — там, где нет ни TPM, ни Secure Enclave. Выключено, чтобы не ломать существующую выдачу на машинах без железа; включайте для парка, где аппаратный ключ обязателен.
TPM_REQUIRE_AK_CERTIFY false Требовать доказательство TPM2_Certify (привязка AK к EK) и отклонять заявки platform=tpm2, его не прошедшие. Пока выключено, результат проверки лишь отражается в поле ak_verified и ничего не блокирует.

Включение TPM_REJECT_UNATTESTED и TPM_REQUIRE_AK_CERTIFY — то, что закрывает обход блокировки устройства подменой серийного номера: заявленный серийник тогда обязан совпасть с аттестованным железом (см. «Управление и роли»).

App Attest (только macOS)

Переменная По умолчанию Описание
ALATYR_APP_ATTEST_APP_ID — Идентификатор приложения Apple App Attest, <TeamID>.<BundleID>. Пусто — App Attest выключен целиком: эндпоинты /enroll/app-attest отвечают 503.
ALATYR_APP_ATTEST_ENVIRONMENT appattest Какую среду принимать: appattest (рабочая) либо appattestdevelop / appattestsandbox (одна и та же нерабочая среда под двумя именами из документации Apple). Это средство защиты, а не флаг сборки: нерабочая аттестация приходит из сборки, которую любой разработчик запускает на любом устройстве, и рабочая среда её не принимает. Непонятное значение — отказ при старте.

Функциональные переключатели

Переменная Старые имена По умолчанию Описание
ALATYR_REMOTE_LOGS_ENABLED WIFI_CERT_REMOTE_LOGS_ENABLED false Разрешить сбор логов с устройств по запросу администратора.
ALATYR_MACOS_AGENT_PROFILE_DISABLED WIFI_CERT_MACOS_AGENT_PROFILE_DISABLED false Не отдавать агенту macOS профиль .mobileconfig для Wi-Fi и проводной сети — агент тогда пропускает собственную установку профиля. Включайте, когда профили раскатывает MDM. На ZIP-бандл для администратора не влияет. Переключатели на отдельные сети — Кто ставит профиль.
ALATYR_PLACEHOLDER_CONTINUITY_MERGE_ENABLED WIFI_CERT_PLACEHOLDER_CONTINUITY_MERGE_ENABLED false Разрешить устройству с подставным серийным номером повторно привязаться к своей прежней строке в списке устройств по continuity_key и не расходовать новое место лицензии при переустановке. См. пояснение ниже.
ALATYR_AGENT_UPDATE_ALERT_MINUTES WIFI_CERT_AGENT_UPDATE_ALERT_MINUTES 30 Сколько минут устройство может не отчитываться о принудительном обновлении, прежде чем фоновая сверка пометит его в алертах.
ALATYR_AGENT_UPDATE_MANIFEST_DIR — — Каталог с подписанными вендором манифестами обновления агента (<платформа>.json). Пусто — управляемая раскатка выключена целиком: манифест не прикладывается при отметке устройства, а админка честно показывает канал как ненастроенный вместо кнопки, которая молча ничего не делает. Зарезервированное имя server.json несёт версию платформы, а не сборку агента: оно никогда не предлагается устройству и питает уведомление об обновлении для администратора.

ALATYR_PLACEHOLDER_CONTINUITY_MERGE_ENABLED выключен намеренно: доказать криптографически «это та же машина» для неаттестованного железа через неаутентифицированный канал невозможно, поэтому каждая регистрация с подставным серийником по умолчанию получает новую строку. Включение — решение администратора: удобство переустановки без траты места лицензии в обмен на эту гарантию.

Вебхуки

Переменная Старые имена По умолчанию Описание
ALATYR_WEBHOOKS_ENABLED WIFI_CERT_WEBHOOKS_ENABLED false Включить исходящие вебхуки. Пока выключено, раздел Вебхуки в админке не показывается.
ALATYR_WEBHOOK_ENC_KEY 🔒 WIFI_CERT_WEBHOOK_ENC_KEY — Ключ AES-256 (64 hex-символа) для шифрования секретов вебхуков на диске. Обязателен, когда вебхуки включены: сервер не стартует, если ключ отсутствует или не декодируется ровно в 32 байта. Взять значение: openssl rand -hex 32.
ALATYR_WEBHOOK_POLL_SECONDS WIFI_CERT_WEBHOOK_POLL_SECONDS 10 Интервал опроса очереди доставки, секунды.
ALATYR_WEBHOOK_RETENTION_DAYS WIFI_CERT_WEBHOOK_RETENTION_DAYS 30 Сколько дней хранить записи о доставке.
ALATYR_WEBHOOK_MAX_ATTEMPTS WIFI_CERT_WEBHOOK_MAX_ATTEMPTS 6 Максимум попыток доставки, после которых она считается неудавшейся.

Трассировка (OpenTelemetry)

Переменная По умолчанию Описание
ALATYR_OTEL_ENABLED false Экспортировать трассы. Выключено: установка без коллектора не должна платить за спаны, которые некуда отправить.
ALATYR_OTEL_ENDPOINT — Адрес коллектора OTLP/HTTP, host:port (например otel-collector:4318). Обязателен при ALATYR_OTEL_ENABLED=true.
ALATYR_OTEL_SERVICE_NAME alatyr-server Значение service.name в экспортируемых спанах.
ALATYR_OTEL_INSECURE true Отправлять OTLP открытым HTTP. По умолчанию так, потому что коллектор обычно стоит соседним контейнером в том же кластере; false требует TLS.
ALATYR_OTEL_SAMPLE_RATIO 1 Доля трасс, начинаемых этим сервисом, 0.0–1.0. Решения о выборке, пришедшие в traceparent/b3, соблюдаются всегда.

Проверки при старте

Проверки делятся на две категории, и разница видна сразу: одна останавливает сервер, другая пишет в журнал.

Фатальные — сервер не стартует:

  • ALATYR_DB_URL не задан;
  • локальная аутентификация включена, а заданный вручную ALATYR_LOCAL_JWT_SECRET короче 32 байт (незаданный — законен, сервер сгенерирует свой);
  • вебхуки включены, а ALATYR_WEBHOOK_ENC_KEY отсутствует или не декодируется ровно в 32 байта;
  • ALATYR_ISSUER=scep, но не хватает одной из четырёх обязательных SCEP-переменных, либо адрес не https без явного ALATYR_SCEP_ALLOW_PLAINTEXT_URL;
  • ALATYR_ISSUER — не vault и не scep;
  • в ALATYR_TRUSTED_PROXIES запись, которая не разбирается как CIDR, либо сеть, покрывающая все адреса;
  • ALATYR_APP_ATTEST_APP_ID задан, а ALATYR_APP_ATTEST_ENVIRONMENT — не одно из трёх допустимых значений;
  • ALATYR_K8S_BROKER_LISTEN задан, а сертификат или ключ брокера — нет.

Все найденные проблемы объединяются в одно сообщение:

configuration error:
  - <проблема 1>
  - <проблема 2>

То есть сервер показывает весь список сразу, а не только первую ошибку.

Предупреждения — сервер стартует, но пишет в журнал:

  • не настроен ни VAULT_TOKEN, ни пара VAULT_ROLE_ID + VAULT_SECRET_ID: подписание сертификатов будет падать, пока Vault не сконфигурирован;
  • задан ALATYR_SCEP_ALLOW_PLAINTEXT_URL=true: путь до SCEP CA не защищён TLS. Это напоминание на каждом запуске — послабление обычно включают «на время» в лаборатории и забывают.

Результат. После правки окружения перезапустите сервер и проверьте, что он поднялся именно с вашими значениями:

docker compose logs alatyr-server | head -40
curl -s http://localhost:8090/api/v1/version

В журнале не должно быть ни строки configuration error, ни is deprecated, use — вторая означает, что значение подхвачено под старым именем и однажды перестанет подхватываться.

DB_PASSWORD — переменная только для docker compose

docker-compose.yml подставляет DB_PASSWORD в строку подключения и в пароль контейнера PostgreSQL до старта сервера. Сам сервер её не читает и о её существовании не знает. Не путайте с переменными выше.

В этом составе ALATYR_DB_URL не действует

Строку подключения docker-compose.yml собирает сам из DB_PASSWORD, и значение ALATYR_DB_URL, заполненное в .env, молча игнорируется. Задавайте ALATYR_DB_URL напрямую только тогда, когда запускаете сервер не этим составом — например, в Kubernetes или в своём манифесте.