Add an idempotent baseline step that enforces myhostname/mydomain from hostname -f and reloads postfix only when drift is detected. Co-authored-by: Cursor <cursoragent@cursor.com>
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_packagespmg.ssh_allow_userspmg.ssh_password_authenticationpmg.journald_system_max_usepmg.journald_max_file_secpmg.node_exporter.*pmg.smtp_monitoring.*pmg.pmg_servicespmg.pmg_cluster_only_servicespmg.cluster_join.*pmg.update_dist_upgradepmg.update_auto_rebootpmg.update_reboot_delay_minutespmg.custom_check.*pmg.custom_check.log_dir_user|log_dir_group|log_dir_mode|log_file_mode
pmg.manage_hosts_filepmg.hosts_file_entriespmg.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.