← Назад к «Клиент»

Клиент LSUS Config Agent (Linux)

lsus-config-agent — отдельный systemd-сервис для Linux-клиентов, исполняющий Ansible-плейбуки, поступающие с сервера через вкладку Конфигурации. Это «руки» модуля compliance/remediation: проверка и приведение в соответствие хостов (EDR/AV/DLP, харднинг ОС, конфиги, службы, установка ПО).

Поставляется со встроенным self-contained Ansible (vendored venv, ~15 МБ) — не требует интернета, установки ansible из репозиториев ОС или системных devel-пакетов. Зависит от lsus-client (читает из его конфигов server_url и Bearer-токен; при пустом адресе находит сервер через DNS TXT/SRV, как клиент). Версия агента синхронна версии LSUS — собирается из того же релиза.

Архитектура и принцип работы#

  Master (вкладка Конфигурации)
      │  POST /api/v1/clients/ansible/runs/pending  (Bearer хоста)
      ▼
  lsus-config-agent (systemd, root)
      │  GET /clients/ansible/runs/<id> → spec {playbook, подпись Ed25519, assets, vault}
      │  проверка подписи + sha256
      │  запуск: venv/bin/ansible-playbook -c local (--check|--become)
      │  POST /runs/<id>/result {status, recap, per-task, stdout_log, report}
      ▼
  встроенный venv: ansible-core 2.19 + ansible.posix + community.general

infoPull-модель

Агент сам опрашивает сервер (GET /api/v1/clients/ansible/runs/pending) — никаких входящих SSH/портов на клиенте открывать не нужно. Тот же Bearer-токен хоста, что у lsus-client. Запуск локальный: ansible-playbook -c local на самом клиенте, без SSH-push с сервера.

Ритм опроса: раз в poll_interval_seconds (по умолчанию 60 с) со случайным джиттером до poll_jitter_seconds (30 с); сервер может подсказать паузу next_poll_seconds, при ошибках — экспоненциальный backoff до max_backoff_seconds (600 с).

Ключевые свойства#

  • Ed25519-подпись обязательна — каждый playbook подписывается приватным ключом сервера; агент проверяет подпись перед выполнением. Защищает от подмены контента (RCE от root — главный риск). Без подписи или при неверной подписи раннер отказывается выполнять.
  • Версионирование — контент playbook'а хранится на сервере в immutable-версиях; идущие прогоны ссылаются на конкретную версию. Редактирование плейбука не ломает идущие прогоны.
  • Антишторм — раскатка батчами с throttle/jitter, lease на выполнение, экспоненциальный backoff при ошибках.
  • Запуск не от root — через run_as_user + runuser (сброс привилегий), временные файлы с правами 700 — подробнее ниже.

Установка#

lsus-config-agent — отдельный пакет, ставится на Linux-клиенты после lsus-client (жёсткая зависимость).

Команды установки#

# Astra / Debian / Ubuntu (.deb)
sudo apt install ./lsus-config-agent_<версия>_amd64.deb

# РЕД ОС / ALT / CentOS (.rpm)
sudo dnf install ./lsus-config-agent-<версия>-1.x86_64.rpm

Зависимости#

Зависимость Назначение
lsus-client >= <версия> Источник server_url и Bearer-токена

Интерпретатор Python 3.12 и Ansible лежат внутри пакета. Системный Python, пакет python3-venv и отдельный python3.11 из репозитория не нужны: хватает той же системы, где уже стоит клиент. Установка не обращается в интернет.

priority_highПорядок установки

Сначала lsus-client, затем lsus-config-agent. Пакет lsus-config-agent не сможет работать без конфигов и токена lsus-client.

При установке пакет автоматически:
1. создаёт venv из bundled wheels (/var/lib/lsus-config-agent/venv);
2. устанавливает коллекции Ansible (community-general, ansible.posix);
3. настраивает SELinux (при enforcing — chcon/semanage для venv);
4. включает и запускает службу lsus-config-agent.service (если на Master не выключен тумблер «Агент конфигураций на хостах»).

Пути установки#

Путь Содержимое
/var/lib/lsus-config-agent/ демон lsus_config_agent.py, раннер lsus_ansible_runner.py, venv/, work/
/etc/lsus-config-agent/lsus-config-agent.conf конфиг (%config(noreplace))
/usr/share/lsus-config-agent/wheels/ wheels для пересоздания venv
/usr/share/lsus-config-agent/collections/ коллекции Ansible
/var/log/lsus-config-agent/agent.log журналы

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

Основной конфиг — /etc/lsus-config-agent/lsus-config-agent.conf. По умолчанию server_url и api_token в нём закомментированы — наследуются из конфигов lsus-client, а при их отсутствии сервер находится через DNS (TXT _lsus.<домен>, запас — SRV) — так же, как это делает основной клиент (см. Подготовка DNS).

Приоритет чтения настроек#

  1. [server] server_url из собственного конфига (если задан);
  2. assigned_server_url из конфигов lsus-client — адрес, назначенный сервером. На филиале Site хост остаётся на своём Site: агент не «уводит» его обратно на Master через DNS. Адрес перечитывается при каждом опросе, поэтому назначение, появившееся уже после старта службы, подхватывается без переустановки;
  3. /etc/lsus-client/lsus-client.conf или /etc/lsus-client/lsus-client-common.conf — секция [server], ключи server_url или master_server_url;
  4. DNS-обнаружение: TXT _lsus.<домен> (отбор по своим IPv4 и cidr, затем SRV _lsus._tcp); домен берётся из server_discovery_domain — сначала из собственного конфига, затем из конфига lsus-client, иначе — из FQDN хоста;
  5. Bearer-токен — всегда из /etc/lsus-client/.api_token (тот же, что у lsus-client).

infoПока адрес не найден

Если ни один источник не дал URL (или токен ещё не выдан), агент не падает: ждёт с нарастающим backoff (до max_backoff_seconds, по умолчанию 600) и перечитывает настройки. Текущее состояние видно в systemctl status lsus-config-agent (строка STATUS=) и в журнале /var/log/lsus-config-agent/agent.log.

Параметры конфигурации#

Ключи /etc/lsus-config-agent/lsus-config-agent.conf (все имеют значения по умолчанию — файл можно не трогать):

Секция Ключ По умолчанию Назначение
[server] server_url — (наследуется) Адрес сервера; если пуст — конфиги lsus-client, затем DNS
[server] server_discovery_domain — (FQDN хоста) Домен для TXT _lsus.<домен> / SRV-обнаружения
[agent] poll_interval_seconds 60 Период опроса очереди прогонов
[agent] poll_jitter_seconds 30 Случайный разброс опроса (антишторм)
[agent] max_backoff_seconds 600 Потолок паузы при ошибках/ожидании настроек
[agent] http_timeout_seconds 15 Таймаут HTTP-запросов к серверу
[runner] venv_dir /var/lib/lsus-config-agent/venv Каталог встроенного Ansible
[runner] work_dir /var/lib/lsus-config-agent/work Рабочий каталог прогонов (playbook, vars, vault)
[runner] stdout_max_bytes 1048576 Потолок вывода ansible в отчёте (1 МБ)
[runner] stderr_max_bytes 262144 Потолок stderr (256 КБ)
[runner] max_tasks 2000 Максимум задач в одном плейбуке
[logging] log_dir /var/log/lsus-config-agent Каталог файлового лога
[logging] log_level INFO Уровень логирования

systemd-служба#

# /etc/systemd/system/lsus-config-agent.service
Type=notify
NotifyAccess=main
TimeoutStartSec=180
User=root
After=network.target lsus-client.service
Requires=lsus-client.service
ConditionPathExists=/var/lib/lsus-config-agent/venv/bin/ansible-playbook
Restart=always
RestartSec=10
ExecStart=/var/lib/lsus-config-agent/venv/bin/python3 /var/lib/lsus-config-agent/lsus_config_agent.py

infoType=notify: ожидание адреса — не рестарты

Агент сам сообщает systemd READY=1 сразу после старта. Если server_url/DNS ещё не дали адрес, ожидание идёт внутри процесса (backoff, см. выше) — служба не падает по таймауту старта и не уходит в restart-loop. Реальные падения по-прежнему обрабатывает Restart=always.

infoConditionPathExists

Сервис не стартует, пока venv не развёрнут (нет ansible-playbook). Это защита от запуска при незавершённой установке.

Встроенный Ansible (vendored venv)#

Компонент Версия
ansible-core 2.19.11
community.general 13.2.0 (в пакете дополнительно лежит 13.1.0)
ansible.posix 2.2.2 (в пакете дополнительно 2.2.0/2.2.1)
cryptography 49.0.0 (проверка Ed25519)
PyYAML 6.0.3

Интерпретатор CPython 3.12, колёса и tarball-коллекции поставляются внутри пакета. venv создаётся при установке из /usr/lib/lsus-config-agent/python и локального каталога /usr/share/lsus-config-agent/wheels/, без обращения к PyPI. Коллекции разворачиваются ansible-galaxy collection install --offline из локальных архивов в /var/lib/lsus-config-agent/ansible/collections (вне дерева pip-пакета ansible), без обращения к galaxy.ansible.com. Зависимость community.library_inventory_filtering ставится раньше community.general. Колёса собраны под этот интерпретатор: cp312 и stable ABI cp311-abi3 для cryptography.

Поддерживаемые ОС#

ОС Версия Системный Python Особенность
РЕД ОС 8.0.2 как у клиента интерпретатор службы внутри пакета
Astra Linux 1.7.9 3.7 отдельный python3.11 не нужен
Astra Linux 1.8.5 3.11 —
Ubuntu 22.04 3.10 отдельный python3.11 не нужен
Ubuntu 24.04 3.12 —
Debian 12 / 13 3.11 / 3.13 системный Python службой не используется
Oracle Linux 8 3.6 та же планка, что у клиента
ALT Linux 11.1 3.12 (glibc 2.38) —
CentOS Stream 10 3.12 SELinux enforcing

Архитектура: x86_64. Для Windows используется отдельный .NET-агент (PowerShell вместо Ansible).

Что делает агент с run'ом#

  1. GET pending — GET /api/v1/clients/ansible/runs/pending (получает список ожидающих прогонов, до 10 за раз, с учётом next_poll_seconds от сервера).
  2. GET spec — GET /clients/ansible/runs/<id> (контент playbook, Ed25519-подпись, content_type, assets[], расшифрованный vault-секрет — только по TLS).
  3. Доставка ассетов — скачивание файлов-нагрузок (сертификаты, конфиги, дистрибутивы ПО), проверка sha256 + Ed25519, установка mode/owner.
  4. Проверка подписи — обязательная проверка Ed25519-подписи контента playbook перед выполнением.
  5. Запуск — ansible-playbook -i localhost, -c local --check|--become через venv, с таймаутом из spec (по умолчанию 1800 с).
  6. Прогресс — live-обновления POST /runs/<id>/progress (фаза, задача).
  7. Артефакты — загрузка собранных файлов (логи, отчёты) обратно на сервер.
  8. Результат — POST /runs/<id>/result (status, recap ok/ch/fail/unr, per-task, stdout_log, report, stderr, rc):
    - stdout_log — человекочитаемый вывод ansible (PLAY/TASK/MSG/PLAY RECAP, классический default-формат). Агент формирует его из распарсенного вывода JSON-callback (берёт события прогона и собирает строки PLAY/TASK/MSG/PLAY RECAP), без повторного запуска ansible — отдельного прогона ради человекочитаемого лога нет.
    - report — сырой JSON-callback (структурированные события прогона), отправляется отдельным полем. На сервере попадает в детали прогона как вкладка «сырой вывод ansible (JSON-callback)» и используется для глубокой отладки/интеграций.

Статусы прогона (AWX-выровненные)#

Статус Значение
pending Создан, ждёт агента
claimed Агент забрал (lease активен)
running Выполняется
successful Завершён без failed/changed
changed Завершён, что-то изменено (apply)
failed Проверка/применение упали
error Ошибка агента (нет venv, нет подписи)
timed_out Превышён timeout_seconds
canceled Отменён оператором

Запуск не от root#

В шаблоне/запуске можно указать run_as_user. Тогда демон (работающий под root) сбрасывает привилегии через runuser -u <user> -- и запускает плейбук от имени этого пользователя. Временные файлы (playbook, vars, vault) создаются с владельцем и правами 600. become=true пробрасывается в Ansible для эскалации внутри плейбука (требует настроенного NOPASSWD sudo на хосте).

warningbecome + sudo = root

Запуск не от root не означает «безопасно»: при become=true и наличии NOPASSWD sudo плейбук всё равно эскалирует до root. Используйте run_as_user для принципа наименьших привилегий только там, где эскалация не нужна.

Файлы: Windows-контент, ассеты и артефакты#

В «Конфигурациях» всё — файлы, просто разного назначения. Различаются
content_type/os_family и род (kind):

Kind Где живёт Что это
playbook / script config_playbooks (с content_type=yaml/powershell) Исполняемый файл; редактируется в UI («Сценарии и скрипты»)
asset config_assets + config_asset_versions Файл-нагрузка на хост (сертификат/конфиг); immutable + Ed25519
distribution config_distributions + config_distribution_versions + config_distribution_files Дистрибутив ПО — семейство с версиями: карточка + N версий (immutable-набор файлов, 1..N каждый)
artifact config_run_artifacts Собранный агентом с хоста файл (для отдачи наружу)

Windows-контент (PowerShell)#

PS-скрипт — это не отдельная сущность, а config_playbooks с
content_type='powershell'. В модалке плейбука выберите тип контента
(YAML / PowerShell) и целевую ОС (os_family=windows). Исполняет
служба конфигураций LsusConfigAgent.exe на Windows-хосте; на Linux такой плейбук
физически не попадёт в очередь благодаря os_family-guard.

Конвенция скрипта:

  1. Принимает -Mode {check|apply} (check = dry-run, apply = применить).
  2. В финале выводит в stdout один JSON-блок:
    json {"status":"successful|failed|changed", "summary":{"ok":N,"changed":N,"failed":N}, "tasks":[{"name":"...","status":"ok|failed","changed":false,"msg":"..."}]}
  3. Совместимость с PowerShell 4.0 (Windows Server 2012 R2): WMI/netsh вместо
    новых cmdlet'ов.
  4. extra_vars читает из $env:LSUS_EXTRA_VARS; собираемые файлы — в
    $env:LSUS_ARTIFACTS_DIR.

Builtin-набор Windows-скриптов (6 шт.): проверка Kaspersky/firewall/UAC, сбор
фактов, реестр-хардненинг, состояние службы.

Раздаваемые файлы (файловый менеджер)#

Подвкладка «Раздаваемые файлы» — трёхзонный файловый менеджер:

  • Дерево папок (слева) — иерархия с materialized path (config_assets.folder
  • явные узлы в config_asset_folders). Папки создаются, переименовываются,
    перемещаются и удаляются (с подтверждением для непустых). Перетаскивание
    файла на папку в дереве перемещает его.
  • Список файлов (центр) — файлы текущей папки: отдельные ассеты и
    дистрибутивы. Мультивыбор + батч-операции (переместить/удалить). Dropzone:
    перетащите внешние файлы — каждый станет отдельным ассетом в текущей папке.
  • Drawer деталей (справа) — вкладки «Метаданные / Версии-файлы / Привязки /
    История». История (audit_logs) показывает кто/когда/что загрузил или изменил.

Ассет — immutable-версия файла с Ed25519-подписью (как плейбук, но бинарь).
Привязка к плейбуку (config_playbook_assets) декларирует: какой ассет и куда
положить перед прогоном (dest_path, mode, owner). Агент перед запуском
скачивает ассет, проверяет sha256+подпись и кладёт по пути. Upload версий —
chunked с потоковой склейкой на сервере (прямо на диск, инкрементальный sha256;
без буферизации многогигабайтных файлов в RAM).

Дистрибутив — учётная единица-семейство ПО (Firefox, VLC, …) с карточкой
(издатель/продукт/архитектура/язык/команда установки). Конкретная версия ПО
(152.0.3, 153.0, …) — отдельный immutable-снапшот (config_distribution_versions)
со своим набором файлов (1..N, immutable + Ed25519). Это зеркальный паттерн к
ассетам (config_assets/config_asset_versions): одна карточка, много версий.

Создаётся через мастер «Дистрибутив…»:

  1. Шаг 1 — карточка-семейство: имя/slug, издатель, продукт, версия ПО, архитектура,
    язык, ОС, папка, описание. Модалка сразу показывает 5 карточек этапов
    lifecycle (Определение/Предпроверка/Установка/Контроль/Удаление), включая
    «Сгенерировать с AI» (ad-hoc через staging_token из шага 2). Сразу
    создаётся первая draft-версия (version=1), куда пойдут файлы. Правка
    метаданных готовой карточки — на вкладке «Обзор» drawer'а; новые версии —
    на вкладке «Версии».
  2. Шаг 2 — загрузка файлов версии: несколько файлов или целая папка (через
    webkitdirectory, с сохранением относительных путей rel_path) либо DnD.
    Крупные файлы — потоковая chunked-загрузка (многоГБ, потоковая склейка на диск
    без буферизации в RAM). Дубликаты rel_path в пределах версии отклоняются.
    При добавлении распознаваемого установщика (MSI/EXE/DEB/RPM) автопрофиль
    lifecycle подмешивается в карточки этапов пофазно (не перезатирая уже
    заполненные вручную этапы). Инспекция файла (POST /distributions/inspect)
    также сохраняет копию прочитанного префикса файла и возвращает
    staging_token — по нему кнопка «Сгенерировать с AI» на карточке этапа
    получает контекст файла ещё до создания дистрибутива.
  3. Finalize версии (по кнопке «Создать» или автоматически по загрузке
    файлов) — версия закрывается (статус active): сервер определяет
    dist_type (single_file / archive / folder) и primary-файл (эвристика
    setup.exe/*.msi/install*), авто-детектит версию ПО из метаданных
    файла (см. ниже). Если lifecycle-контракт не готов (нераспознанный EXE,
    архив/папка без известного профиля) — сервер вернёт 409, версия останется
    draft, а UI вместо ошибки сразу откроет карточку дистрибутива на вкладке
    «Установка и проверка»: там нужно донастроить этапы (вручную или AI-генерацией)
    и нажать «Завершить и активировать версию». При успешном finalize карточка
    переходит в active, и та же вкладка открывается автоматически — карточки
    этапов заполнены автопрофилем, если файл распознан.

Версии дистрибутива (latest / pinned)#

Карточка хранит указатель current_version_id — latest-версию (ту, что
раздаётся, если в привязке не указано иное). В drawer деталей дистрибутива на
вкладке «Версии» доступны:

  • список всех версий (label, статус, число файлов, объём, источник авто-детекта,
    бейдж «текущая»);
  • кнопка «Добавить версию» — создаёт новую draft-версию и сразу переводит в
    шаг загрузки файлов (карточку-семейство править не нужно);
  • кнопка «сделать latest» (promote) — назначает выбранную finalized-версию
    current; кнопка finalize для draft-версий прямо из drawer;
  • файлы выбранной версии (с скачиванием).

Привязка к сценарию («Файлы на хост») для дистрибутива поддерживает два режима:

  • latest (по умолчанию) — раздаётся current-версия; её смена (promote
    новой) автоматически подхватывается новыми прогонами без правки привязки;
  • pinned — фиксируется конкретная версия (distribution_version_id); для
    регламентированных окружений, где нужен точный build.

Авто-детект версии ПО (универсальный)#

При finalize версии сервер определяет version_label с многоуровневым fallback
(без новых зависимостей):

  1. Метаданные бинарника — для .exe/.dll: разбор PE-ресурса VS_VERSIONINFO
    (FileVersion/ProductVersion). Для Firefox/VLC/Chrome даёт точную версию.
    Для .msi — ProductVersion из summary info.
  2. Regex имени файла — \d+(\.\d+){1,3} (напр. vlc-3.0.20-win64.exe) либо
    чисто-цифровой build (7z2407 → 2407).
  3. Ручной ввод в визарде/finalize — всегда побеждает авто-детект.

Источник записывается в detected_from (metadata/filename/manual) и виден
в drawer для диагностики.

Доставка приложений (end-to-end)#

Рекомендуемый путь для администратора — мастер «Доставить на хосты» в карточке
приложения (вкладка «Обзор»), а не ручная цепочка назначений:

  1. Загрузка пакета (MSI/EXE/DEB/RPM) и finalize с автопрофилем lifecycle.
  2. Мастер: пакет → установка/проверка → хосты → канарейка → запуск.
    Экспериментальный сценарий доставки ставится только на коллекции с включёнными
    испытаниями (флажок в свойствах коллекции; потомки наследуют допуск). Хосты
    вне таких коллекций в предпросмотре аудитории отсекаются. Окно мастера
    фиксированной высоты, прокручивается тело шага.
  3. Prepare идемпотентно создаёт managed playbook, профиль и draft release.
  4. Согласование ревизии (separation of duties).
  5. Application rollout с target_action (install/upgrade/repair/uninstall).
  6. Мониторинг: release → approval → rollout → waves → config_host_distribution_state.

Настройка этапов lifecycle (карточки + AI)#

Раньше lifecycle-контракт (detect/check/install/verify/uninstall × Windows/Linux)
редактировался только как сырой JSON на отдельной вкладке — это было тяжело для
администратора и оператора. Теперь основной способ настройки — отдельная вкладка
«Установка и проверка» в карточке приложения (не путать с вкладкой «Обзор» —
там только карточка семейства, версия/пакет и чеклист готовности). Те же самые
карточки этапов (с кнопкой «Сгенерировать с AI») показываются и в модалке
«Новый дистрибутив» ещё до создания записи — см. шаг 1 мастера выше; разница
только в том, что там нет раздельных «Сохранить для версии/базовым» (всё уходит
в lifecycle_defaults вместе при «Создать»), а AI работает в ad-hoc режиме через
временный застейдженный файл. Вкладка «Установка и проверка» сверху вниз показывает:

  1. «Как это работает» — поток Определение → Предпроверка → Установка →
    Контроль, разница между «для версии» и «базовым для всех версий». Установка
    и удаление настраиваются только здесь (lifecycle JSON); отдельных полей
    install_command в карточке больше нет.
  2. «Этапы установки и проверки» — секция с разворачиваемыми карточками
    этапов:
    - каждый этап — отдельная карточка с понятной формой: тумблер
    «Этап включён», способ выполнения (powershell/ansible/shell/
    package_manager/none), поле со скриптом/командой, коды успеха, таймаут.
    Для Windows скрипт — PowerShell. Для Linux ansible означает, что скрипт —
    настоящий YAML-список задач Ansible (модули ansible.builtin.apt/dnf/
    command/…), которые вставляются как есть в собираемый playbook и
    исполняются встроенным локальным Ansible агента lsus-config-agent; коды
    успеха для этой ветки не нужны — успех/неуспех этапа определяется тем,
    упали задачи или нет. shell/package_manager — по-прежнему bash-команды.
    Подсказка под селектором и плейсхолдер поля меняются в зависимости от
    выбранного способа выполнения;
    - кнопка «Сгенерировать с AI» на карточке — просит AI-ассистента заполнить
    только этот этап (модель получает целевую ОС и данные пакета); результат
    показывается прямо в карточке с явным указанием способа выполнения
    (executor) — для Windows и Linux shell/package_manager также с кодами
    успеха (для Linux ansible коды успеха не показываются — не применимы),
    плюс кнопками «Принять» (подставить в форму) и «Отклонить» —
    ничего не сохраняется без ручного подтверждения. Модель проинструктирована
    возвращать для Linux executor=ansible именно YAML-список задач Ansible,
    а не bash; если она вернула пустой/нераспознанный executor, UI подставляет
    согласованный с ОС вариант (powershell для Windows, ansible для Linux);
    - «Сохранить для версии» — изменения применяются только к выбранной версии
    (override); «Сделать базовым для всех версий» — меняет сценарий
    приложения (defaults), которым пользуются все версии без своего override;
    - если AI недоступен или вернул невалидный ответ, для MSI/EXE/DEB/RPM
    подставляется детерминированный автопрофиль —
    генерация с AI никогда не оставляет этап пустым при распознанном пакете.
    Для MSI все Windows-фазы (включая install) намеренно используют executor
    powershell: detect/verify/uninstall читают реестр (Get-ItemProperty),
    а сама команда msiexec /i "{{installer_path}}" /qn /norestart проверяет
    код завершения через $LASTEXITCODE — PowerShell исполняет и обычные
    команды, поэтому это не ошибка распознавания. Для DEB/RPM автопрофиль —
    настоящие задачи Ansible (ansible.builtin.apt/dnf, с fallback через
    apt -f install/yum), executor ansible — запускает lifecycle-скрипты
    как настоящие Ansible-задачи;
    - если версия ещё draft (не прошла finalize, например пакет не распознан
    автоматически), в конце секции показывается заметный блок с кнопкой
    «Завершить и активировать версию» — после настройки этапов вручную
    или через AI её можно активировать прямо здесь, без возврата в мастер.
  3. Кнопка «Экспертный режим (JSON)» — раскрывает свёрнутый по умолчанию блок
    с сырым JSON-контрактом (defaults/overrides/итоговый эффективный контракт).
    Он показывает то же самое, что и карточки этапов, но предназначен для
    точечных правок и просмотра, а не для повседневной настройки.

Дистрибутив привязывается к сценарию так же, как ассет
(config_playbook_assets.distribution_id, опционально distribution_version_id);
Windows .NET-агент получает в claim-спеке файлы резолвнутой версии
(rel_path + подпись + checksum + version_label для диагностики), стримит их
на диск в dest_path, проверяет sha256 и Ed25519; установка/удаление выполняются
сгенерированным playbook по lifecycle-контракту (политика lsus.software.install,
auto_install=false на привязке). Привязка доступна через UI «Файлы на хост»
(переключатель Ассет/Дистрибутив + селектор версии).

Поддержка агентами: Windows .NET-агент (сборка с config-distributions) — полная
(доставка + verify + install, latest/pinned). Linux config-агент пока не поддерживает
дистрибутивы (только обычные ассеты).

Пример E2E (демо-стенд): карточка-семейство «Mozilla Firefox» (os=windows,
lifecycle с этапом install через msiexec) → загрузка установщика 152.0.3
(88 МБ, sha256+Ed25519) → finalize (active, авто-детект версии из PE-метаданных,
версия становится current/latest) → привязка к сценарию из политики
lsus.software.install (dest_path=C:\Deploy\firefox, pinned/latest) →
apply-прогон: агент скачал файл, проверил подпись, playbook выполнил lifecycle
install (rc=0), verify подтвердил версию → Firefox 152.0.3 установлен. Позже:
загрузка версии 153.0 → promote в latest → новые прогоны автоматически ставят
153.0 без правки привязки.

Артефакты (файл с хоста наружу)#

Скрипт складывает собираемые файлы (отчёты, факты для сторонней системы) в
LSUS_ARTIFACTS_DIR; после прогона агент грузит их на сервер (single-shot /
chunked) в config_run_artifacts. Артефакты:

  • read-only, TTL (по умолчанию 7 дней, чистятся воркером по expires_at);
  • доступны в модалке прогона (скачать/превью);
  • форвардятся во внешнюю систему через integration-gateway (эпик внешних
    интеграций) — target_provider_id. Пока gateway не подключён — хранятся
    инертно, доступ через API/UI.

Диагностика#

Проверка работоспособности#

# статус службы
systemctl status lsus-config-agent

# журнал службы
journalctl -u lsus-config-agent -f

# файловый лог
tail -f /var/log/lsus-config-agent/agent.log

Стартовая строка в логе при успешном запуске: lsus-config-agent <version> запущен (server=<url>).

Ручной запуск spec (dry-run)#

Для диагностики playbook'а без сервера есть CLI-обёртка:

/var/lib/lsus-config-agent/venv/bin/python3 /var/lib/lsus-config-agent/lsus_ansible_runner.py <spec.json> [output.json]

Принимает JSON spec (файл или строку), выполняет playbook через тот же AnsibleRunner, печатает результат (или пишет в output.json). Exit-код 0 при successful.

infoЖурналы

  • journal: journalctl -u lsus-config-agent (StandardOutput=journal).
  • Файловый лог: /var/log/lsus-config-agent/agent.log (ротация 5 МБ × 5 копий, уровень INFO).
  • Архив диагностики клиента забирает этот конфиг, файловый лог и journal, если служба установлена.

Связь с lsus-client#

Что Как
server_url наследуется из конфигов lsus-client (если не задан в собственном конфиге)
Bearer-токен всегда из /etc/lsus-client/.api_token (тот же, что у lsus-client)
Зависимость пакета Depends: lsus-client (>= <версия>) — обязательная
Автономная работа невозможна — нужен server_url/токен из lsus-client
Heartbeat не шлёт; версию отправляет один раз при старте (POST /clients/ansible/version)

infoВерсия в `config_agent_version`

При старте агент отправляет свою версию (POST /api/v1/clients/ansible/version), сервер записывает её в колонку хоста config_agent_version — видна на вкладке «Хосты → Версии агента».

Регистрация на сервере#

lsus-config-agent не регистрируется отдельно — использует регистрацию и Bearer-токен хоста, созданные lsus-client. Просто начинает опрашивать /clients/ansible/runs/pending с тем же токеном. User-Agent во всех запросах: lsus-config-agent/<version>.

Что нужно серверу#

Чтобы вкладка Конфигурации появилась в Master и агент начал получать задания, на сервере должны быть:
- созданы плейбуки/профили (через Конструктор политик или импорт);
- создано назначение (профиль → группа/тег/хост) с режимом check/apply;
- на клиентах установлен lsus-config-agent и запущен сервис;
- в «Управление обновлениями → Клиент LSUS → Настройки» включён тумблер «Агент конфигураций на хостах» и в лицензии есть модуль «Управление конфигурациями». Если тумблер выключен, lsus-client останавливает юнит lsus-config-agent и не забирает прогоны; патч-агент при этом жив. Если пакета нет, состояние missing — патч-агент не падает.

Связанные страницы#