Установка¶
Alatyr состоит из двух частей, и ставятся они независимо:
- Сервер — принимает заявки, проверяет аттестацию устройства, выпускает сертификаты через PKI, ведёт журнал аудита и отдаёт веб-интерфейс (дальше — админка). Разворачивается один раз на вашей инфраструктуре.
- Агент — программа на машине сотрудника. Заводит ключ в чипе устройства, подаёт заявку и ставит выданный сертификат. Ставится на каждое устройство.
Эта страница проводит через обе части по шагам. Каждый шаг заканчивается проверкой, которую можно выполнить и увидеть результат.
Прежде чем разворачивать сервер в работу, прочитайте Отказоустойчивость (HA) и Расчёт ресурсов: ни один из составов ниже не разворачивает базу или Vault в отказоустойчивой конфигурации сам по себе.
Что нужно перед началом¶
Машина под сервер¶
| Параметр | Минимум | Рекомендуется | Откуда число |
|---|---|---|---|
| CPU | 2 ядра | 4 ядра | в покое весь состав потребляет менее 0,3 ядра; запас нужен на выпуск и на раскатку парка |
| Память | 2 ГБ | 4 ГБ | замер в покое — около 120 МиБ на все компоненты; остальное уходит буферам PostgreSQL и файловому кэшу |
| Диск | 20 ГБ | 50 ГБ | образы занимают 1,3–1,9 ГБ; данные растут десятками мегабайт в год даже на парке в 600 машин, см. Расчёт ресурсов |
| ОС | Linux с systemd | проверяется на Debian 12 и Ubuntu 22.04 | |
| Docker | 24.0+ | нужен docker compose как подкоманда, а не отдельный docker-compose |
Для развёртывания в Kubernetes вместо Docker потребуется кластер 1.27+ и
kubectl с правами на создание пространства имён.
Условия, без которых не заработает¶
| Условие | Зачем | Чем проверить |
|---|---|---|
| Синхронизированное время | Сертификаты и токены проверяются по времени; расхождение в минуты даёт отказы, которые выглядят как ошибки прав | timedatectl status |
| Разрешение имени сервера в DNS | Агенты обращаются к серверу по имени; адрес в конфигурации переживает переезд хуже | getent hosts <имя> с машины агента |
| Доступ агентов к API сервера | Без него агент зарегистрируется, но сертификат не получит | curl https://<имя>:8090/health |
| Исходящий доступ к реестру образов | Иначе образы придётся переносить вручную | docker pull s3m4rgl/alatyr-server:<тег> |
Что понадобится рядом¶
| Компонент | Обязательность | Назначение |
|---|---|---|
| PostgreSQL | обязательно | основная база сервера |
| Vault или внешний SCEP CA | обязательно | выпуск сертификатов. Если УЦ ещё нет — встроенный УЦ поднимает его внутри состава |
| Keycloak | опционально | вход в админку через SSO. Альтернатива — встроенный вход по email и паролю |
На стороне устройства требование задаёт способ хранения ключа: TPM 2.0 на Windows и Linux, Secure Enclave на macOS либо поддерживаемая смарт-карта. Устройство без такого хранилища получит отказ при выпуске, если включена политика «только аппаратное хранилище», — см. Известные ограничения.
Порты¶
| Порт | Что на нём |
|---|---|
8090 |
API сервера (docker-compose.yml, меняется через ALATYR_API_PORT) |
3000 |
админка (docker-compose.yml, меняется через ALATYR_UI_PORT) |
13000 / 18090 |
демо-состав (docker-compose.demo.yml): админка / API |
8200 |
Vault |
8080 |
Keycloak (состав для ознакомления docker-compose.dev.yml) |
Версия поставки: тег обязателен¶
Сервер и админка поставляются готовыми образами
s3m4rgl/alatyr-server и
s3m4rgl/alatyr-frontend.
Собирать ничего не нужно — в этом репозитории лежит только развёртывание.
У тега нет значения по умолчанию, и тега latest не существует намеренно:
плавающий тег однажды отдал сборку месячной давности, и обнаружилось это не
отказом, а тем, что в продукте не оказалось нужной возможности — худший вид
сбоя, потому что находится он уже у вас.
Тег выглядит как 1.4.2843 — мажор и минор продукта плюс номер сборки. Это
не номер вида v1.4.5: теги репозитория и теги образов — разные
нумерации. Действующий список — на странице образа, раздел Tags. Версия
сервера и версия админки выпускаются парой и совпадают; берите один и тот же
тег для обоих.
Манифесты из этого репозитория рассчитаны на образы той же поставки.
Разойтись они могут молча и в обе стороны, поэтому правило простое: берите
ALATYR_IMAGE_TAG из тех же релизных заметок, что и манифест.
Проверить, что поднялось именно то, что вы взяли:
curl -s http://localhost:8090/api/v1/version
Ответ содержит версию, коммит и время сборки.
Сервер¶
Пилот: набор развёртывания из выпуска
Начиная с v1.5.5 каждый выпуск
несёт архив alatyr-deploy-<версия>.tar.gz: Docker Compose со встроенным
корневым и промежуточными УЦ, сценарий first-up.sh, который придумывает
все секреты и печатает их одним блоком (адрес админки, логин и пароль
администратора, доступ к базе, токен и ключ распечатывания УЦ), и
.env.example с уже вписанным тегом образов — набор и образы приходят парой.
tar -xzf alatyr-deploy-<версия>.tar.gz
cd alatyr-deploy-<версия>
./first-up.sh
Это рекомендуемый путь для пилота. Подробности — README.md внутри набора.
Остальные пути, и выбирать между ними нужно один раз:
| Что вам нужно | Берите |
|---|---|
| Пилот: всё поднимается одной командой, УЦ с промежуточными внутри | набор развёртывания из выпуска (выше) |
| Рабочая установка, Vault и Keycloak у вас свои | Docker Compose |
| Посмотреть продукт за одну команду, ничего не настраивая | демо-состав |
| Рабочая установка в Kubernetes | Helm-чарт |
| УЦ ещё нет и заводить его отдельно не хочется | набор развёртывания из выпуска (выше); прежний встроенный УЦ устарел — без промежуточных УЦ и без печати учётных данных |
Вариант 1 — Docker Compose¶
Шаг 1. Возьмите репозиторий и заполните .env¶
git clone https://github.com/s3m4rgl/alatyr-docs.git
cd alatyr-docs
cp .env.example .env
$EDITOR .env
Минимум, который нужно заполнить:
| Переменная | Что это |
|---|---|
ALATYR_IMAGE_TAG |
версия поставки из релизных заметок |
DB_PASSWORD |
пароль пользователя PostgreSQL; годится любая строка из openssl rand -base64 24 |
VAULT_ADDR плюс VAULT_ROLE_ID и VAULT_SECRET_ID (либо VAULT_TOKEN) |
доступ к вашему Vault. AppRole предпочтительнее статического токена и имеет над ним приоритет |
ALATYR_LOCAL_AUTH_ENABLED, ALATYR_LOCAL_ADMIN_EMAIL, ALATYR_LOCAL_ADMIN_PASSWORD |
первый администратор, если вы не используете Keycloak |
KEYCLOAK_URL, KEYCLOAK_REALM, KEYCLOAK_CLIENT_ID, KEYCLOAK_CLIENT_SECRET |
если используете Keycloak SSO |
Полный список переменных с умолчаниями — Конфигурация.
ALATYR_DB_URL в этом составе не действует
Строку подключения docker-compose.yml собирает сам из DB_PASSWORD.
Значение, заполненное в .env, молча игнорируется. Задавайте
ALATYR_DB_URL только тогда, когда запускаете сервер не этим
составом.
Секреты лучше передавать файлом
Любое имя из .env.example принимает форму <ИМЯ>_FILE — значение будет
прочитано из указанного файла. Переменная окружения видна в
docker inspect и в /proc/<pid>/environ, файл — нет.
Результат. docker compose config печатает состав целиком и не
жалуется ни на одну незаданную переменную.
Шаг 2. Поднимите состав¶
docker compose up -d
Результат. Все три контейнера в состоянии running, а сервер отвечает
своей версией:
docker compose ps
curl -s http://localhost:8090/api/v1/version
Если версия не та, что в релизных заметках, дальше разбираться
бессмысленно — вернитесь к ALATYR_IMAGE_TAG.
Шаг 3. Войдите в админку¶
Откройте http://localhost:3000 (или ваш адрес — внешние порты задаются
через ALATYR_API_PORT и ALATYR_UI_PORT). Войдите учётной записью первого
администратора.
Первый вошедший получает полные права
Роль cert-admin автоматически достаётся первому, кто войдёт, — это
работает и для Keycloak, и для локального входа. В установке только с
Keycloak это буквально первый обладатель действующего токена настроенного
клиента, а не обязательно вы. Войдите первым до того, как откроете
API наружу. Подробности и другие способы закрыть это —
Управление и роли.
Результат. Вы в админке, в правом верхнем углу ваша учётная запись с ролью «Администратор», и в левом меню видны разделы Пользователи, Настройки, Сервисные аккаунты.
Шаг 4. Направьте цели в их издатели¶
Чарт и состав задают только запасной путь к PKI. Какая цель куда ходит —
запись в базе, и без неё заявки уедут в состояние vault_failed.
Откройте Настройки → Удостоверяющие центры и задайте каждой цели её точку монтирования и роль. Конкретные значения для встроенного УЦ — в соответствующем разделе; для вашего Vault — те, что вы завели у себя.
У wifi и user_mtls издатель обязан быть разным
Оба сертификата несут одинаковое имя, и приёмник mTLS различает их только по издателю. Пока их выписывает один издатель, машинный сертификат — который подписывается молча, без PIN и биометрии — годится как замена пользовательскому. Разбор и замеры — mTLS пользователя → Настройка.
Результат. На вкладке у каждой цели указана своя точка монтирования,
кнопка проверки связи отвечает успехом, а в журнале сервера нет строки
Vault auth is not configured:
docker compose logs alatyr-server | grep -i vault
Шаг 5. Смените пароль первого администратора¶
После смены уберите ALATYR_LOCAL_ADMIN_PASSWORD из .env: он нужен только
на первый запуск, пока таблица пользователей пуста.
Результат. Вход под прежним паролем не проходит, под новым — проходит.
Демо-состав¶
Одна команда, ничего настраивать не нужно. Поднимает PostgreSQL, Vault с уже настроенным PKI, сервер, админку и наполняет базу демонстрационными данными:
ALATYR_IMAGE_TAG=<версия из релизных заметок> \
docker compose -f docker-compose.demo.yml up -d
Результат. Открывается http://localhost:13000, вход —
admin@wifi.local / Admin1234!. API — http://localhost:18090.
Это демонстрация, а не установка
Пароль администратора, пароль базы, токен Vault и ключи шифрования заданы прямо в файле, чтобы состав поднимался одной командой. Значит, они известны каждому, кто этот файл открыл. Никогда не переносите их в рабочую установку и не выставляйте этот состав в сеть.
Состав для ознакомления с чужим Keycloak или Vault¶
docker-compose.dev.yml поднимает только инфраструктуру — PostgreSQL (порт
5433), Vault в режиме разработки (8200) и Keycloak (8080), — чтобы
подключить к ней ваш realm или ваши настройки Vault и посмотреть, как
продукт ведёт себя с ними. Сервер и админку он поднимает по запросу:
docker compose -f docker-compose.dev.yml --profile app up -d
Vault здесь тоже в режиме разработки: данные в памяти, перезапуск стирает выпущенный УЦ вместе со всеми подписанными сертификатами.
Вариант 2 — Kubernetes (Helm)¶
В репозитории лежит рабочий чарт
charts/alatyr.
Он разворачивает сервер, админку и (по желанию) PostgreSQL. Vault он внутри
себя не поднимает — это сознательное решение: Vault в кластере это
отдельная установка со своим хранилищем, распечатыванием и резервными
копиями, и делать её попутно значит спрятать её от того, кто за неё отвечает.
Если УЦ ещё нет — начните со встроенного УЦ.
Шаг 1. Заведите Secret¶
Значений секретов в values.yaml нет и не будет: values уезжают в git и в
helm get values любому, у кого есть доступ к релизу. Чарт ждёт ссылку на
существующий Secret со следующими ключами:
| Ключ | Когда нужен |
|---|---|
local-jwt-secret |
HS256, не короче 32 байт (openssl rand -hex 32) |
local-admin-email, local-admin-password |
первый администратор; убрать после первого входа |
database-url |
при postgres.mode: external |
postgres-password |
при postgres.mode: embedded |
vault-role-id, vault-secret-id |
при vault.auth: approle |
vault-token |
при vault.auth: token |
webhook-enc-key |
если включаете вебхуки |
keycloak-client-secret |
если используете Keycloak |
kubectl create namespace alatyr
kubectl -n alatyr create secret generic alatyr-secrets \
--from-literal=local-jwt-secret="$(openssl rand -hex 32)" \
--from-literal=local-admin-email=admin@corp.example \
--from-literal=local-admin-password='<сильный пароль>' \
--from-literal=vault-role-id='<role_id>' \
--from-literal=vault-secret-id='<secret_id>' \
--from-literal=database-url='postgres://…'
Результат. kubectl -n alatyr get secret alatyr-secrets показывает
нужное число ключей.
Шаг 2. Установите релиз¶
helm upgrade --install alatyr charts/alatyr \
--namespace alatyr --create-namespace \
--set image.tag=<версия поставки> \
--set secrets.existingSecret=alatyr-secrets \
--set vault.addr=https://vault.corp.example:8200 \
--set pki.publicAddr=https://vault.corp.example:8200 \
--set ingress.enabled=true \
--set ingress.host=alatyr.corp.example
Чарт роняет установку, а не предупреждает, если чего-то не хватает:
пустой image.tag, отсутствующий secrets.existingSecret, пустой
vault.addr, postgres.mode: embedded без включённой резервной копии,
больше одной реплики сервера без явного признания ограничений. Ошибка на
helm install дешевле, чем ImagePullBackOff или сервер, который стартует
и отказывает на первой заявке.
Что стоит задать осознанно:
| Значение | Зачем |
|---|---|
postgres.mode |
external (рекомендуется) — ваша база, строка подключения в Secret; embedded — один под в этом релизе, пригодно для пилота, не отказоустойчиво |
pki.publicAddr |
адрес Vault, по которому его видят клиенты, а не поды. Попадает внутрь выданного сертификата как точка распространения списка отзыва: имя службы кластера снаружи не разрешается, и проверить отозванность будет нечем. Смена значения не чинит уже выданные сертификаты |
server.trustedProxies |
CIDR ingress-прокси. Без него у всех вызывающих один и тот же адрес, и любое ограничение по адресу становится общим разрешением — см. Конфигурация |
server.replicas |
больше одной реплики требует server.acknowledgeMultiReplicaLimits: true: опрос SCEP рассчитан на одну реплику, ограничение частоты между репликами не общее |
namespace |
пространство имён, которое чарт проставляет самим объектам. По умолчанию alatyr. Если вы ставите релиз в другое, задайте и --namespace, и --set namespace=…: иначе объекты уедут не туда, куда смотрит helm |
helm install --wait может зависнуть не из-за ошибки
Если класс хранения работает в режиме WaitForFirstConsumer (так устроен
local-path в k3s), PVC под резервные копии остаётся в Pending до
первого запуска задачи, и --wait ждёт его до истечения времени, хотя
релиз развёрнут правильно. Либо не задавайте --wait, либо запустите
копию сразу:
kubectl -n alatyr create job первая-копия \
--from=cronjob/alatyr-postgres-backup
Результат. Поды в состоянии Running, а сервер отвечает своей версией:
kubectl -n alatyr get pods
kubectl -n alatyr port-forward svc/alatyr-server 8090:8090 &
curl -s http://localhost:8090/api/v1/version
Шаг 3. Те же три шага, что и в Docker¶
Дальше — вход в админку, направить цели в их издатели и смена пароля первого администратора. Проверить, что сервер дошёл до Vault:
kubectl -n alatyr logs deploy/alatyr-server | grep -i vault
Строка Vault auth is not configured означает, что ключи в Secret названы не
так, как ждёт чарт.
Свой сертификат для админки¶
Речь здесь про сертификат, которым сама админка отвечает по HTTPS, — не
про сертификаты сотрудников (user_mtls, mTLS пользователя).
Оба выпускает один и тот же корень Alatyr Root CA, отсюда и типичная
путаница: доверие этому корню на Mac сотрудника нужно для входа в браузере по
user_mtls, а не для самой админки — подробнее в Пилоте, шаг 5.
Раздел ниже относится к набору развёртывания
(alatyr-deploy-<версия>.tar.gz, врезка выше): только в нём есть служба,
которая сама выпускает и продлевает сертификат админки. В варианте Docker
Compose и в Helm-чарте
TLS перед админкой всегда ставит заказчик сам — этот раздел к ним не
относится.
Свой сертификат подложить в набор нельзя¶
Настройки «загрузить свой сертификат» в наборе нет. Сертификат выпускает
служба tls-cert сама, из встроенного удостоверяющего центра, на имена и
адреса из ALATYR_TLS_NAMES, и перевыпускает его при подходящем сроке, смене
этих имён или смене корня PKI. Что за сертификат лежит в томе tls_data,
служба не проверяет. Поэтому подложенный туда вручную сертификат может
какое-то время работать, а затем будет молча заменён её собственным: при
плановом продлении, при смене ALATYR_TLS_NAMES или корня, а если вместе с
ним затронуты служебные файлы тома — при ближайшей проверке (раз в 12 часов).
Предупреждения при этом не будет: однажды браузеры сотрудников просто
перестанут доверять адресу админки. Так делать нельзя.
Как правильно: свой обратный прокси¶
Единственный поддерживаемый способ — выключить встроенный TLS и поставить перед сервером свой обратный прокси с сертификатом от корпоративного УЦ:
- В
.envнабора задайтеALATYR_TLS=off— встроенный УЦ сертификат больше не выпускает, и админка отдаётся поhttpнаALATYR_UI_PORT. - Поставьте перед сервером свой обратный прокси (nginx, HAProxy и подобные)
с сертификатом от вашего УЦ, проксирующий запросы на
ALATYR_UI_PORT. - Впишите адрес, по которому сотрудники будут открывать админку через
прокси, в
ALATYR_EXTRA_ORIGINS(через запятую, если адресов несколько). Без этого вход не сработает: браузер шлёт заголовокOrigin, сервер отвечает403на адрес не из списка разрешённых, а админка показывает это как неверный пароль. - Повторите
./first-up.sh(илиdocker compose up -dдля ручной установки), чтобы переменные применились.
Агентов сотрудников через этот прокси пускать необязательно: по умолчанию
они обращаются к серверу напрямую, на ALATYR_API_PORT (8090), в обход
админки и её TLS. Решите пустить и их через свой прокси — укажите его
https-адрес как адрес сервера при установке агента (параметр
WIFI_CERT_SERVER, Установка → Агент) и настройте на прокси
проксирование на тот же ALATYR_API_PORT.
Проверить. Откройте админку по адресу прокси — браузер не предупреждает о
сертификате, а в его свойствах издатель — ваш корпоративный УЦ, не Alatyr
Root CA. Вход под верным паролем администратора проходит; отвечает
«неверный пароль» при заведомо верном — адрес прокси не попал в
ALATYR_EXTRA_ORIGINS (README.md набора, раздел «Частые проблемы и
их решение»).
Агент¶
Агент — один исполняемый файл, общий для macOS, Windows и Linux. Он заводит ключ в аппаратном хранилище устройства, подаёт заявку на сервер, ждёт одобрения администратором и ставит выданный сертификат и профиль сети.
Отдельной учётной записи на сервере агенту не требуется: он предъявляет
enrollment_token устройства, полученный при первой регистрации.
Что задаётся при установке — одно и то же на всех трёх системах:
| Параметр | Обязателен | Что это |
|---|---|---|
| адрес сервера | да | URL сервера Alatyr, тот же, что в адресной строке админки |
| почта владельца | да, либо вместо неё домен | На кого выпускается сертификат |
| корпоративный домен | да, если почта не задана | Почта тогда выводится как <имя машины>@<домен> |
Без владельца агент уходит в цикл перезапуска
Если не задать ни почту, ни домен, агент не может определить владельца
машины и выходит с ошибкой на каждом запуске. Снаружи это выглядит
как успешная установка: пакет встал, «Готово» напечатано, а счётчик
перезапусков службы растёт. На Linux install.sh поэтому отказывается
ставить агента без одного из двух параметров; у пакетов deb/rpm
задать их нужно самому — см. ниже.
Где взять пакеты. Готовые пакеты для Windows, macOS и Linux лежат в разделе Releases этого репозитория — возьмите файл своей платформы из последнего выпуска. Пакет macOS начиная с v1.5.5 подписан и нотаризован Apple; адрес сервера в него не вшит и задаётся при установке, см. раздел про macOS.
Linux¶
Пакет ставит исполняемый файл /usr/local/bin/alatyr-agent, конфигурацию
/etc/alatyr-agent/config.env, системные службы alatyr-agent.service и
alatyr-agent-secretd.service, пользовательскую службу
alatyr-agent-user.service и значок в системной панели.
Поддерживаются amd64 и arm64.
Шаг 1. Поставьте пакет вместе с параметрами¶
Пакеты deb и rpm принимают параметры установки переменными окружения:
имена те же, что в config.env.
# Debian, Ubuntu
sudo WIFI_CERT_SERVER="https://alatyr.your-domain.example" \
CORP_DOMAIN="your-domain.example" \
apt install ./alatyr-agent_<версия>_amd64.deb
# Fedora, RHEL, Alma, Rocky
sudo WIFI_CERT_SERVER="https://alatyr.your-domain.example" \
CORP_DOMAIN="your-domain.example" \
dnf install ./alatyr-agent-<версия>-1.x86_64.rpm
Если config.env уже настроен (есть хоть одно незакомментированное
присваивание), параметры установки не применяются и пакет говорит об этом
в выводе: обновление парка не должно молча переписывать то, что человек
правил руками.
Для дистрибутивов без apt и dnf есть архив tar.gz со своим
установщиком — он сам доставит зависимости TPM и PKCS#11:
tar xzf alatyr-agent-linux-<версия>.tar.gz -C alatyr-agent
cd alatyr-agent
sha256sum -c SHA256SUMS.txt
sudo ./install.sh \
--server "https://alatyr.your-domain.example" \
--corp-domain "your-domain.example"
--skip-tpm-deps пропускает установку зависимостей, если вы ставите их сами.
Результат. Служба работает, а не перезапускается по кругу:
systemctl status alatyr-agent.service
В строке состояния должно быть active (running), а не activating
(auto-restart). В журнале не должно быть строки CORP_EMAIL not set and
CORP_DOMAIN not set.
Шаг 2. Если параметры нужно задать или поправить позже¶
sudo $EDITOR /etc/alatyr-agent/config.env
sudo systemctl restart alatyr-agent.service
Не ставьте этому файлу права 0600
Пакет кладёт config.env с правами 0640, владелец root, группа
alatyr-tpm, и это сделано намеренно: тот же файл читает
непривилегированная пользовательская половина агента, входящая в эту
группу. Ужесточение до 0600 оставляет её без адреса сервера и почты
владельца — процесс тогда бесконечно висит в ожидании личности, не
объясняя причины.
Если права уже изменены, верните их:
sudo chown root:alatyr-tpm /etc/alatyr-agent/config.env
sudo chmod 0640 /etc/alatyr-agent/config.env
Результат. ls -l /etc/alatyr-agent/config.env показывает
-rw-r----- root alatyr-tpm, а alatyr-agent status печатает состояние, а
не ошибку.
Шаг 3. Проверьте зависимости TPM¶
Пакеты deb и rpm тянут обязательное сами: модуль tpm2-pkcs11 (в Debian
и Ubuntu это libtpm2-pkcs11-1) и p11-kit. Без модуля агент падает на
каждом цикле при выпуске user_mtls и ssh.
Ещё два пакета идут как рекомендуемые, и их легко потерять при установке с
--no-install-recommends:
| Пакет | Что сломается без него |
|---|---|
libengine-pkcs11-openssl |
реальное подключение по Wi-Fi: регистрация и выпуск пройдут нормально, а EAP-TLS упадёт позже |
tpm2-tools |
ручная диагностика TPM; на работу агента не влияет |
# Debian, Ubuntu
dpkg -l libtpm2-pkcs11-1 p11-kit libengine-pkcs11-openssl
Без TPM агент работает, но иначе
Если модуля tpm2-pkcs11 нет вовсе, агент использует программный ключ на
диске (/var/lib/alatyr-agent/, права 0600). Это годится для
знакомства и не годится для парка: ключ становится файлом, который можно
скопировать, — то есть ровно то, от чего продукт защищает.
Результат. Все три пакета установлены, и alatyr-agent status показывает
аппаратное хранилище, а не программный ключ.
Диагностика и удаление¶
systemctl status alatyr-agent.service alatyr-agent-secretd.service
journalctl -u alatyr-agent.service -f
sudo /usr/local/bin/alatyr-agent status
Удаление: sudo apt remove alatyr-agent (данные и сертификаты остаются для
аудита) либо sudo apt purge alatyr-agent — с полной очисткой. Для архивной
установки — sudo ./uninstall.sh и sudo ./uninstall.sh --purge.
macOS¶
Агент на macOS работает у каждого пользователя отдельно (LaunchAgent), а
не на уровне машины. Причина в Secure Enclave: ключ подписи создаётся в связке
ключей вошедшего пользователя, которой под системной учётной записью не
существует. Каждый пользователь одной машины регистрируется отдельно и
получает свой сертификат.
Машина без графической сессии сертификат не получит
Пакет ставится нормально и без активного входа, но сертификат не
выпустится, пока кто-то не войдёт в графическую сессию: ключ Secure
Enclave держит системный процесс secd, а он есть только в такой сессии.
Это свойство платформы, а не недоработка.
Шаг 1. Возьмите пакет из выпуска¶
alatyr-agent-<версия>.pkg из выпуска
подписан Developer ID и нотаризован Apple. Проверить это до установки:
spctl -a -vvv -t install alatyr-agent-<версия>.pkg
# alatyr-agent-<версия>.pkg: accepted
# source=Notarized Developer ID
Пакет требует macOS 12 или новее. Адрес сервера в пакет не вшит: без него агент встаёт ненастроенным и к серверу не обращается, о чём пишет в свой журнал.
Шаг 2. Поставьте пакет вместе с параметрами¶
Штатный installer в macOS не умеет передавать параметры пакету, поэтому
они кладутся заранее в файл предварительных значений
/Library/Application Support/AlatyrAgent/config.env.preseed. Сценарий
установки пакета читает его (только если владелец файла — root),
применяет и удаляет. Скопируйте блок целиком, подставив свои значения:
PKG=./alatyr-agent-1.5.6.pkg
SERVER=https://alatyr.your-domain.example
CORP_DOMAIN=your-domain.example
CORP_EMAIL=user@your-domain.example # можно оставить пустым — тогда <логин>@CORP_DOMAIN
sudo mkdir -p "/Library/Application Support/AlatyrAgent"
printf 'WIFI_CERT_SERVER="%s"\nCORP_DOMAIN="%s"\nCORP_EMAIL="%s"\n' \
"$SERVER" "$CORP_DOMAIN" "$CORP_EMAIL" |
sudo tee "/Library/Application Support/AlatyrAgent/config.env.preseed" >/dev/null
sudo chmod 600 "/Library/Application Support/AlatyrAgent/config.env.preseed"
sudo installer -pkg "$PKG" -target /
Имя ключа WIFI_CERT_SERVER — историческое, это адрес сервера Alatyr.
Через MDM (например, FleetDM: Software → Add Software) делается то же самое:
сценарий до установки кладёт этот файл, затем ставится пакет.
Почту нельзя передать переменной окружения установщика
installer в macOS не пробрасывает переменные окружения в
postinstall-скрипт: sudo CORP_EMAIL=x installer -pkg … не работает
и молча откатывается на автоопределение
(<короткое имя>@<корпоративный домен> либо атрибут из каталога, если Mac
включён в домен). Задавайте почту только файлом предварительных значений.
Результат. launchctl list | grep semargl показывает загруженный
LaunchAgent, а команда
/Applications/alatyr-agent.app/Contents/MacOS/alatyr-agent status
печатает состояние. Журнал агента — ~/Library/Logs/AlatyrAgent/agent.log.
Для разработчиков: сборка пакета своей подписью¶
Нужна, только если организация хочет подписать агента своим Developer ID вместо поставляемого пакета.
- Разово создайте в учётной записи Apple Developer вашей организации
сертификаты Developer ID Application (подпись приложения) и
Developer ID Installer (подпись пакета) и пароль приложения для
notarytool. - Соберите выпуск скриптом
sign-agent-release.sh, задав адрес сервера и корпоративный домен. Скрипт компилирует приложение, подписывает, нотаризует и упаковывает в.pkg. Для локальной проверки без отправки на серверы Apple естьSKIP_NOTARIZE=1.
Результат. В каталоге dist/ лежит .pkg, и spctl -a -vvv -t install
на нём отвечает accepted. Ставится он так же, как в шаге 2.
Windows¶
Агент ставится пакетом MSI: alatyr-agent-<версия>-x64.msi. Он кладёт
службу, окно агента, минидрайвер смарт-карты и драйвер считывателя. Пакет
рассчитан на раскатку через групповую политику, FleetDM, Intune и подобные
средства.
Ключ подписи создаётся в TPM 2.0 и хранится на уровне машины, в отличие от macOS.
Только x64
Пакета для ARM64 нет: драйвер считывателя собирается под x64, и пакет для ARM64 приехал бы без поддержки карты.
Шаг 1. Установите доверие к издателю пакета¶
Пакет подписан нашим сертификатом, а не сертификатом общедоступного УЦ, и
корня Semargl в списке доверенных у Windows по умолчанию нет. Пока корень
не установлен, Windows считает издателя неизвестным: установка проходит, но с
предупреждением, а политики, требующие подписанного кода (AppLocker, WDAC,
Smart App Control), пакет отвергнут. Неподписанный MSI, кроме того, не
раскатывается через групповую политику.
На одной машине:
certutil -addstore -f Root "C:\Program Files\AlatyrAgent\driver\alatyr-driver-ca.cer"
certutil -addstore -f TrustedPublisher "C:\Program Files\AlatyrAgent\driver\alatyr-driver-signer.cer"
В домене то же делается один раз на парк: Computer Configuration → Policies → Windows Settings → Security Settings → Public Key Policies → Trusted Root Certification Authorities.
Результат. certutil -store Root содержит корень Semargl, а установка
пакета не показывает диалог «неизвестный издатель».
Шаг 2. Поставьте пакет¶
msiexec /i alatyr-agent-<версия>-x64.msi /qn `
SERVER=https://alatyr.your-domain.example `
CORP_DOMAIN=your-domain.example `
CORP_EMAIL=user@your-domain.example
Полезные ключи установки:
| Ключ | Умолчание | Что делает |
|---|---|---|
SERVER |
— | Адрес сервера Alatyr |
CORP_DOMAIN |
— | Корпоративный домен |
CORP_EMAIL |
— | Почта владельца устройства |
INSTALL_CARD |
1 |
Заводить ли смарт-карту и считыватель |
ENROLL_PURPOSE |
— | Что создаёт машинная регистрация: пусто или wifi — устройство и машинный сертификат; none — только устройство и enrollment_token, без заявки. Нужно там, где хосту требуется только ssh или только карта |
PURGE |
0 |
При удалении снести данные агента |
REMOVE_READER |
1 |
При удалении убрать устройство считывателя |
REMOVE_ANCHOR |
1 |
При удалении убрать корневой сертификат УЦ |
Журнал установки: добавьте /l*v C:\Windows\Temp\alatyr-msi.log.
Обновление — та же команда с более новым пакетом: он сам снимает предыдущую версию. Ключи очистки при обновлении не срабатывают, иначе перекат сносил бы считыватель и корень доверия между шагами.
Результат. Служба работает и задача пользовательской половины заведена:
sc.exe query AlatyrAgent
schtasks /Query /TN AlatyrAgentUser
Шаг 3. Проверьте карту и готовность ко входу¶
certutil -silent -scinfo
& "C:\Program Files\AlatyrAgent\alatyr-agent.exe" rdp --target <fqdn>
Последняя команда печатает список препятствий ко входу по карте через RDP: адрес, политика, карта, клиент, PIN, служба считывателей, защита LSA.
Результат. Карта видна, контейнер на месте, и все проверки готовности отвечают «да».
Раскатка на парк¶
FleetDM и Intune передают свойства штатно:
msiexec /i alatyr-agent-<версия>-x64.msi /qn SERVER=https://alatyr.corp `
CORP_EMAIL=$FLEET_VAR_HOST_END_USER_EMAIL_IDP
Групповая политика свойств msiexec передавать не умеет — администратор
назначает пакет компьютерам, и всё. Поэтому настройки задаются самой
политикой, через реестр:
HKLM\SOFTWARE\Policies\Semargl\Alatyr
WIFI_CERT_SERVER = https://alatyr.corp
CORP_EMAIL = user@corp
CORP_DOMAIN = corp
Имена значений те же, что у переменных окружения и ключей config.env. Ветка
Policies выбрана намеренно: её содержимое перезаписывается при каждом
применении политики, поэтому значение, убранное из политики, исчезает с
машины само.
Разовая ручная установка перебивает доменную политику
Порядок источников, от старшего к младшему: флаг командной строки →
config.env → свойства установки (HKLM\SOFTWARE\Semargl\Alatyr) →
групповая политика. Значит, свойство, переданное разовой ручной
установкой, переживёт последующие раскатки по политике и будет её
перебивать. Агент пишет в журнал, откуда взял каждое значение — по
этой строке такой случай виден сразу.
Что делает пакет, а что служба¶
Пакет умеет ровно то, что умеет Windows Installer: кладёт файлы, заводит
службу AlatyrAgent, пишет свойства в реестр и убирает всё это при удалении.
Считыватель, задачу пользовательской половины и подключение считывателя к каналу карты заводит служба при своём запуске. Так сделано не в обход установщика, а потому, что это чинится само: служба стартует и при обновлении, и при ремонте, и при перезагрузке, а её команды идемпотентны. Значит, считыватель, убранный руками, и задача, удалённая руками, восстановятся сами — без переустановки пакета.
Переход с прежней установки (.zip и install.ps1)¶
Ставьте пакет поверх — снимать старое руками не нужно. Машинную задачу
планировщика AlatyrAgent, которую заводил прежний установщик, служба
снимает сама при первом запуске. Это не косметика: пока задача жива, она
гоняет цикл каждые десять минут, и служба делает ровно то же с тем же файлом
состояния — две регистрации одного устройства идут параллельно и перетирают
друг друга, а по журналу это выглядит как повторные заявки без причины.
Пользовательскую задачу снимать не нужно — пакет перезаписывает её своей.
Удаление¶
msiexec /x alatyr-agent-<версия>-x64.msi /qn # данные сохраняются
msiexec /x alatyr-agent-<версия>-x64.msi /qn PURGE=1 # вместе с данными
Что дальше¶
- Агенты — как агент ведёт себя после установки, сроки сертификатов и команды для разбора.
- Управление и роли — роли, одобрение заявок, сервисные аккаунты.
- Настройка целей: Wi-Fi и проводной 802.1X, mTLS пользователя, SSH-доступ, Вход в домен по смарт-карте, Доступ к Kubernetes.
- Диагностика — когда устройство не получает сертификат.