Ruslan PetrovichandCursor 664a544aa9 Fix PMG custom-check log ownership to avoid permission denied errors.
Updated the custom_check state to manage /var/log/mail_av and checked file with pmg-smtp-filter ownership and configurable modes, and documented new pillar settings for log owner/group/modes.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-24 21:26:13 +03:00

Salt baseline для PMG

Репозиторий содержит автономный набор Salt states для базовой эксплуатации и hardening Proxmox Mail Gateway.

Что внутри

  • top.sls — привязка состояний к minion ID.
  • pillar/pmg.sls — переменные и параметры PMG.
  • pmg/*.sls — состояния:
    • common (базовые пакеты),
    • node_exporter (установка и включение Prometheus node exporter),
    • smtp_monitoring (SMTP-метрики: blackbox probe для 25/26 и postfix queue/connection gauges),
    • ssh_hardening,
    • custom_check (кастомная AV-проверка PMG через KESL),
    • security_agents (Wazuh/Qualys),
    • update (пакетные обновления + pre/post проверки PMG),
    • auto_updates (security-only, без auto reboot),
    • audit_logging,
    • pmg_baseline (проверка/поддержание сервисов PMG),
    • verify (проверки состояния).
  • pmg/files/* — шаблоны конфигов.

Требования

  • Salt (рекомендуется актуальная LTS-ветка).
  • Debian/PMG узлы с systemd.
  • root-доступ на узел.

Быстрый запуск

make lint
make check
make apply
make verify
make update-check
make update

По умолчанию MINION_ID=p-mailgw-x2-01.lmru.tech. Можно переопределить:

make check MINION_ID=p-mailgw-x1-01.lmru.tech

Основные переменные

Все параметры задаются в pillar/pmg.sls:

  • pmg.base_packages
  • pmg.ssh_allow_users
  • pmg.ssh_password_authentication
  • pmg.journald_system_max_use
  • pmg.journald_max_file_sec
  • pmg.node_exporter.*
  • pmg.smtp_monitoring.*
  • pmg.pmg_services
  • pmg.pmg_cluster_only_services
  • pmg.cluster_join.*
  • pmg.update_dist_upgrade
  • pmg.update_auto_reboot
  • pmg.update_reboot_delay_minutes
  • pmg.custom_check.*
    • pmg.custom_check.log_dir_user|log_dir_group|log_dir_mode|log_file_mode
  • pmg.manage_hosts_file
  • pmg.hosts_file_entries
  • pmg.wazuh.*
  • pmg.kesl.*
  • pmg.klnagent.*
  • pmg.qualys.*

pmg.node_exporter.args по умолчанию включает textfile collector: --collector.textfile.directory=/var/lib/prometheus/node-exporter.

pmg.smtp_monitoring публикует расширенные SMTP метрики в node_exporter:

  • queue total/deferred + age oldest message;
  • SMTP listen/established для портов 25/26;
  • recent window counters (pmg.smtp_monitoring.log_window_seconds) по логам postfix: sent, received, deferred, bounced, rejected, tls failures, smtp connections.

pmg.cluster_join делает:

  • precheck passwordless SSH с новой ноды на pmg.cluster_join.master_ip;
  • non-interactive pmgcm join при заданном pmg.cluster_join.password.

Важно: pmgcm join использует пароль PMG (root@pam на master) для получения ticket (это не SSH-пароль). Без pmg.cluster_join.password state делает skip-уведомление.

Рекомендуется передавать пароль через переменную окружения (без сохранения в pillar/pmg.sls):

export PMG_CLUSTER_JOIN_PASSWORD='***'
PILLAR_B64="$(python3 -c 'import json, os, base64; print(base64.b64encode(json.dumps({\"pmg\": {\"cluster_join\": {\"password\": os.environ[\"PMG_CLUSTER_JOIN_PASSWORD\"]}}}).encode()).decode())')"
ssh root@p-mailgw-x1-02.lmru.tech "cd /root/mailgw-salt && salt-call --local --id p-mailgw-x1-02.lmru.tech --file-root=. --pillar-root=./pillar state.apply pmg.cluster_join pillar=\"\$(python3 -c \"import base64; print(base64.b64decode(\\\"${PILLAR_B64}\\\").decode())\")\""

Для полностью автоматического bootstrap SSH-доверия (без паролей) с управляющей машины:

make cluster-bootstrap MINION_ID=p-mailgw-x1-02.lmru.tech MASTER_HOST=p-mailgw-x1-01.lmru.tech MASTER_IP=10.80.38.152

Отдельное обновление PMG

Перед обновлением:

make update-check MINION_ID=p-mailgw-x1-01.lmru.tech

Применение:

make update MINION_ID=p-mailgw-x1-01.lmru.tech
make verify MINION_ID=p-mailgw-x1-01.lmru.tech

State pmg.update выполняет:

  • precheck кластера (pmgcm status);
  • precheck критичных PMG сервисов;
  • пакетное обновление (pkg.uptodate, с dist_upgrade по pmg.update_dist_upgrade=true);
  • postcheck кластера и сервисов;
  • уведомление, если требуется reboot (/var/run/reboot-required).
  • опциональный автоперезапуск по pmg.update_auto_reboot=true (через shutdown -r +N).

PMG custom check (Kaspersky)

Коротко про pmg.custom_check:

  • готовит окружение (pwgen, /var/log/mail_av, /usr/local/bin/pmg-custom-check);
  • готовит Kaspersky-учетку (pmg.custom_check.ksc_superuser.*; сейчас superuser + NOPASSWD);
  • настраивает исключения KESL из сканирования через pmg.custom_check.kesl_excluded_paths (по умолчанию: /var/spool/pmg, /var/lib/clamav, /tmp/.proxdump_*) и делает systemctl restart kesl только при изменении этих настроек;
  • если kesl/klnagent64 установлены — включает сервисы и custom_check в PMG, если нет — выводит уведомление "ставится через Kaspersky Administration Center"; сервисы включатся вторым прогоном после установки пакетов.

pmg.security_agents дополнительно ставит/настраивает kesl и klnagent64:

  • для kesl:
    • скачивает .deb из pmg.kesl.package_url;
    • формирует autoinstall.ini и запускает /opt/kaspersky/kesl/bin/kesl-setup.pl --autoinstall=...;
    • поднимает сервис kesl;
  • скачивает .deb из pmg.klnagent.package_url;
  • формирует файл ответов KLAUTOANSWERS (минимум: KLNAGENT_SERVER, KLNAGENT_AUTOINSTALL, EULA_ACCEPTED);
  • устанавливает/переустанавливает пакет в тихом режиме и поднимает сервис klnagent64.
S
Description
No description provided
Readme
86 KiB
Languages
SaltStack 65.9%
Jinja 28.8%
Makefile 3%
Shell 2.3%