Конфигурация¶
Справочник переменных окружения сервера 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 или в своём манифесте.