Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
85cecf78f6 | ||
|
|
35d81332fa |
+13
@@ -0,0 +1,13 @@
|
|||||||
|
# Python / virtualenv
|
||||||
|
.venv/
|
||||||
|
venv/
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
|
||||||
|
# Salt runtime artifacts
|
||||||
|
.salt/
|
||||||
|
|
||||||
|
# IDE / OS files
|
||||||
|
.idea/
|
||||||
|
.vscode/
|
||||||
|
.DS_Store
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
extends: default
|
||||||
|
|
||||||
|
ignore: |
|
||||||
|
.git/
|
||||||
|
.venv/
|
||||||
|
venv/
|
||||||
|
|
||||||
|
rules:
|
||||||
|
comments-indentation: disable
|
||||||
|
document-start:
|
||||||
|
present: false
|
||||||
|
line-length:
|
||||||
|
max: 120
|
||||||
|
level: warning
|
||||||
|
truthy:
|
||||||
|
check-keys: false
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
SHELL := /usr/bin/env bash
|
||||||
|
.RECIPEPREFIX := >
|
||||||
|
|
||||||
|
SALT_CALL ?= salt-call
|
||||||
|
SALT_LINT ?= salt-lint
|
||||||
|
YAMLLINT ?= yamllint
|
||||||
|
STATE_ROOT ?= .
|
||||||
|
PILLAR_ROOT ?= ./pillar
|
||||||
|
MINION_ID ?= p-mailgw-x2-01.lmru.tech
|
||||||
|
|
||||||
|
.PHONY: lint check apply verify update-check update
|
||||||
|
|
||||||
|
lint:
|
||||||
|
>@if command -v $(SALT_LINT) >/dev/null 2>&1; then \
|
||||||
|
> $(SALT_LINT) pmg/*.sls pillar/*.sls top.sls; \
|
||||||
|
>else \
|
||||||
|
> echo "salt-lint не найден, пропускаю"; \
|
||||||
|
>fi
|
||||||
|
>@if command -v $(YAMLLINT) >/dev/null 2>&1; then \
|
||||||
|
> $(YAMLLINT) .; \
|
||||||
|
>else \
|
||||||
|
> echo "yamllint не найден, пропускаю"; \
|
||||||
|
>fi
|
||||||
|
|
||||||
|
check:
|
||||||
|
>sudo $(SALT_CALL) --local --id $(MINION_ID) --file-root=$(STATE_ROOT) --pillar-root=$(PILLAR_ROOT) state.apply pmg.init test=True
|
||||||
|
|
||||||
|
apply:
|
||||||
|
>sudo $(SALT_CALL) --local --id $(MINION_ID) --file-root=$(STATE_ROOT) --pillar-root=$(PILLAR_ROOT) state.apply pmg.init
|
||||||
|
|
||||||
|
verify:
|
||||||
|
>sudo $(SALT_CALL) --local --id $(MINION_ID) --file-root=$(STATE_ROOT) --pillar-root=$(PILLAR_ROOT) state.apply pmg.verify
|
||||||
|
|
||||||
|
update-check:
|
||||||
|
>sudo $(SALT_CALL) --local --id $(MINION_ID) --file-root=$(STATE_ROOT) --pillar-root=$(PILLAR_ROOT) state.apply pmg.update test=True
|
||||||
|
|
||||||
|
update:
|
||||||
|
>sudo $(SALT_CALL) --local --id $(MINION_ID) --file-root=$(STATE_ROOT) --pillar-root=$(PILLAR_ROOT) state.apply pmg.update
|
||||||
@@ -1,2 +1,91 @@
|
|||||||
# mailgw-salt
|
# Salt baseline для PMG
|
||||||
|
|
||||||
|
Репозиторий содержит автономный набор Salt states для базовой эксплуатации и hardening Proxmox Mail Gateway.
|
||||||
|
|
||||||
|
## Что внутри
|
||||||
|
|
||||||
|
- `top.sls` — привязка состояний к minion ID.
|
||||||
|
- `pillar/pmg.sls` — переменные и параметры PMG.
|
||||||
|
- `pmg/*.sls` — состояния:
|
||||||
|
- `common` (базовые пакеты),
|
||||||
|
- `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-доступ на узел.
|
||||||
|
|
||||||
|
## Быстрый запуск
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make lint
|
||||||
|
make check
|
||||||
|
make apply
|
||||||
|
make verify
|
||||||
|
make update-check
|
||||||
|
make update
|
||||||
|
```
|
||||||
|
|
||||||
|
По умолчанию `MINION_ID=p-mailgw-x2-01.lmru.tech`. Можно переопределить:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
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.pmg_services`
|
||||||
|
- `pmg.update_dist_upgrade`
|
||||||
|
- `pmg.update_auto_reboot`
|
||||||
|
- `pmg.update_reboot_delay_minutes`
|
||||||
|
- `pmg.custom_check.*`
|
||||||
|
- `pmg.manage_hosts_file`
|
||||||
|
- `pmg.hosts_file_entries`
|
||||||
|
- `pmg.wazuh.*`
|
||||||
|
- `pmg.qualys.*`
|
||||||
|
|
||||||
|
## Отдельное обновление PMG
|
||||||
|
|
||||||
|
Перед обновлением:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make update-check MINION_ID=p-mailgw-x1-01.lmru.tech
|
||||||
|
```
|
||||||
|
|
||||||
|
Применение:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
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/klnagent64` установлены — включает сервисы и `custom_check` в PMG, если нет — выводит уведомление "ставится через Kaspersky Administration Center"; сервисы включатся вторым прогоном после установки пакетов.
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
pmg:
|
||||||
|
base_packages:
|
||||||
|
- curl
|
||||||
|
- vim-tiny
|
||||||
|
- rsync
|
||||||
|
- ca-certificates
|
||||||
|
- jq
|
||||||
|
|
||||||
|
ssh_allow_users: []
|
||||||
|
ssh_password_authentication: true
|
||||||
|
|
||||||
|
journald_system_max_use: 1G
|
||||||
|
journald_max_file_sec: 1month
|
||||||
|
|
||||||
|
pmg_services:
|
||||||
|
- postfix
|
||||||
|
- pmg-smtp-filter
|
||||||
|
- pmgpolicy
|
||||||
|
- pmgdaemon
|
||||||
|
- pmgmirror
|
||||||
|
- pmgtunnel
|
||||||
|
update_dist_upgrade: true
|
||||||
|
update_auto_reboot: false
|
||||||
|
update_reboot_delay_minutes: 1
|
||||||
|
|
||||||
|
custom_check:
|
||||||
|
enabled: true
|
||||||
|
script_path: /usr/local/bin/pmg-custom-check
|
||||||
|
log_dir: /var/log/mail_av
|
||||||
|
managed_packages:
|
||||||
|
- pwgen
|
||||||
|
ksc_superuser:
|
||||||
|
enabled: true
|
||||||
|
name: superuser
|
||||||
|
manage_sudoers: true
|
||||||
|
required_services:
|
||||||
|
- kesl
|
||||||
|
- klnagent64
|
||||||
|
|
||||||
|
manage_hosts_file: false
|
||||||
|
hosts_file_entries:
|
||||||
|
- ip: 10.80.38.152
|
||||||
|
hostname: p-mailgw-x1-01
|
||||||
|
aliases:
|
||||||
|
- p-mailgw-x1-01.lmru.tech
|
||||||
|
- ip: 10.220.41.152
|
||||||
|
hostname: p-mailgw-x2-01
|
||||||
|
aliases:
|
||||||
|
- p-mailgw-x2-01.lmru.tech
|
||||||
|
|
||||||
|
wazuh:
|
||||||
|
enabled: true
|
||||||
|
version: 4.14.0-1
|
||||||
|
manager: 10.80.120.205
|
||||||
|
group: test_auditd_unix
|
||||||
|
|
||||||
|
qualys:
|
||||||
|
enabled: true
|
||||||
|
package_url: https://storage.yandexcloud.net/qualys-agent/QualysCloudAgent.deb
|
||||||
|
package_path: /opt/QualysCloudAgent.deb
|
||||||
|
activation_id: 5eb9ad8e-02cc-431a-9afb-b8caad175ec1
|
||||||
|
customer_id: 4d868109-dad3-5536-82b4-9f3a6f3010bc
|
||||||
|
server_uri: https://qagpublic.qg1.apps.qualys.eu/CloudAgent/
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
base:
|
||||||
|
'*':
|
||||||
|
- pmg
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
{% set journald_system_max_use = salt['pillar.get']('pmg:journald_system_max_use', '1G') %}
|
||||||
|
{% set journald_max_file_sec = salt['pillar.get']('pmg:journald_max_file_sec', '1month') %}
|
||||||
|
|
||||||
|
pmg-journald-dropin-dir:
|
||||||
|
file.directory:
|
||||||
|
- name: /etc/systemd/journald.conf.d
|
||||||
|
- user: root
|
||||||
|
- group: root
|
||||||
|
- mode: '0755'
|
||||||
|
|
||||||
|
pmg-journald-retention:
|
||||||
|
file.managed:
|
||||||
|
- name: /etc/systemd/journald.conf.d/99-retention.conf
|
||||||
|
- source: salt://pmg/files/journald-retention.conf.jinja
|
||||||
|
- template: jinja
|
||||||
|
- context:
|
||||||
|
journald_system_max_use: {{ journald_system_max_use }}
|
||||||
|
journald_max_file_sec: {{ journald_max_file_sec }}
|
||||||
|
- user: root
|
||||||
|
- group: root
|
||||||
|
- mode: '0644'
|
||||||
|
|
||||||
|
pmg-restart-journald:
|
||||||
|
cmd.run:
|
||||||
|
- name: systemctl restart systemd-journald
|
||||||
|
- onchanges:
|
||||||
|
- file: pmg-journald-retention
|
||||||
|
|
||||||
|
pmg-auditd-package:
|
||||||
|
pkg.installed:
|
||||||
|
- name: auditd
|
||||||
|
|
||||||
|
pmg-audit-rules:
|
||||||
|
file.managed:
|
||||||
|
- name: /etc/audit/rules.d/99-pmg-baseline.rules
|
||||||
|
- source: salt://pmg/files/99-pmg-baseline.rules.jinja
|
||||||
|
- template: jinja
|
||||||
|
- user: root
|
||||||
|
- group: root
|
||||||
|
- mode: '0640'
|
||||||
|
|
||||||
|
pmg-reload-audit-rules:
|
||||||
|
cmd.run:
|
||||||
|
- name: augenrules --load
|
||||||
|
- onchanges:
|
||||||
|
- file: pmg-audit-rules
|
||||||
|
|
||||||
|
pmg-auditd-service:
|
||||||
|
service.running:
|
||||||
|
- name: auditd
|
||||||
|
- enable: true
|
||||||
|
|
||||||
|
pmg-rsyslog-service:
|
||||||
|
service.running:
|
||||||
|
- name: rsyslog
|
||||||
|
- enable: true
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
pmg-updates-packages:
|
||||||
|
pkg.installed:
|
||||||
|
- pkgs:
|
||||||
|
- unattended-upgrades
|
||||||
|
- apt-listchanges
|
||||||
|
|
||||||
|
pmg-apt-auto-upgrades:
|
||||||
|
file.managed:
|
||||||
|
- name: /etc/apt/apt.conf.d/20auto-upgrades
|
||||||
|
- source: salt://pmg/files/20auto-upgrades.jinja
|
||||||
|
- template: jinja
|
||||||
|
- user: root
|
||||||
|
- group: root
|
||||||
|
- mode: '0644'
|
||||||
|
|
||||||
|
pmg-unattended-policy:
|
||||||
|
file.managed:
|
||||||
|
- name: /etc/apt/apt.conf.d/50unattended-upgrades
|
||||||
|
- source: salt://pmg/files/50unattended-upgrades.jinja
|
||||||
|
- template: jinja
|
||||||
|
- user: root
|
||||||
|
- group: root
|
||||||
|
- mode: '0644'
|
||||||
|
|
||||||
|
pmg-unattended-service:
|
||||||
|
service.running:
|
||||||
|
- name: unattended-upgrades
|
||||||
|
- enable: true
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
{% set base_packages = salt['pillar.get']('pmg:base_packages', []) %}
|
||||||
|
|
||||||
|
pmg-base-packages:
|
||||||
|
pkg.installed:
|
||||||
|
- pkgs: {{ base_packages }}
|
||||||
@@ -0,0 +1,111 @@
|
|||||||
|
{% set custom_check_enabled = salt['pillar.get']('pmg:custom_check:enabled', True) %}
|
||||||
|
{% set custom_check_script_path = salt['pillar.get']('pmg:custom_check:script_path', '/usr/local/bin/pmg-custom-check') %}
|
||||||
|
{% set custom_check_log_dir = salt['pillar.get']('pmg:custom_check:log_dir', '/var/log/mail_av') %}
|
||||||
|
{% set custom_check_managed_packages = salt['pillar.get']('pmg:custom_check:managed_packages', ['pwgen']) %}
|
||||||
|
{% set custom_check_required_services = salt['pillar.get']('pmg:custom_check:required_services', ['kesl', 'klnagent64']) %}
|
||||||
|
{% set ksc_superuser_enabled = salt['pillar.get']('pmg:custom_check:ksc_superuser:enabled', False) %}
|
||||||
|
{% set ksc_superuser_name = salt['pillar.get']('pmg:custom_check:ksc_superuser:name', '') %}
|
||||||
|
{% set ksc_superuser_manage_sudoers = salt['pillar.get']('pmg:custom_check:ksc_superuser:manage_sudoers', True) %}
|
||||||
|
{% set kesl_installed = salt['pkg.version']('kesl') != '' %}
|
||||||
|
{% set klnagent64_installed = salt['pkg.version']('klnagent64') != '' %}
|
||||||
|
{% set custom_check_kaspersky_ready = kesl_installed and klnagent64_installed %}
|
||||||
|
|
||||||
|
{% if custom_check_enabled %}
|
||||||
|
{% if ksc_superuser_enabled and ksc_superuser_name %}
|
||||||
|
pmg-custom-check-ksc-superuser:
|
||||||
|
user.present:
|
||||||
|
- name: {{ ksc_superuser_name }}
|
||||||
|
- shell: /bin/bash
|
||||||
|
- createhome: true
|
||||||
|
|
||||||
|
{% if ksc_superuser_manage_sudoers %}
|
||||||
|
pmg-custom-check-ksc-superuser-sudo-package:
|
||||||
|
pkg.installed:
|
||||||
|
- name: sudo
|
||||||
|
|
||||||
|
pmg-custom-check-ksc-superuser-sudoers:
|
||||||
|
file.managed:
|
||||||
|
- name: /etc/sudoers.d/90-kaspersky-superuser
|
||||||
|
- user: root
|
||||||
|
- group: root
|
||||||
|
- mode: '0440'
|
||||||
|
- contents:
|
||||||
|
- {{ ksc_superuser_name }} ALL = (ALL) NOPASSWD: ALL
|
||||||
|
- check_cmd: visudo -cf
|
||||||
|
- require:
|
||||||
|
- pkg: pmg-custom-check-ksc-superuser-sudo-package
|
||||||
|
- user: pmg-custom-check-ksc-superuser
|
||||||
|
{% endif %}
|
||||||
|
{% elif ksc_superuser_enabled %}
|
||||||
|
pmg-custom-check-ksc-superuser-missing-name:
|
||||||
|
test.fail_without_changes:
|
||||||
|
- name: "pmg.custom_check.ksc_superuser.enabled=true but pmg.custom_check.ksc_superuser.name is empty."
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
pmg-custom-check-managed-packages:
|
||||||
|
pkg.installed:
|
||||||
|
- pkgs: {{ custom_check_managed_packages }}
|
||||||
|
|
||||||
|
pmg-custom-check-log-dir:
|
||||||
|
file.directory:
|
||||||
|
- name: {{ custom_check_log_dir }}
|
||||||
|
- user: root
|
||||||
|
- group: root
|
||||||
|
- mode: '0755'
|
||||||
|
|
||||||
|
pmg-custom-check-log-file:
|
||||||
|
file.touch:
|
||||||
|
- name: {{ custom_check_log_dir }}/checked
|
||||||
|
- require:
|
||||||
|
- file: pmg-custom-check-log-dir
|
||||||
|
|
||||||
|
pmg-custom-check-script:
|
||||||
|
file.managed:
|
||||||
|
- name: {{ custom_check_script_path }}
|
||||||
|
- source: salt://pmg/files/pmg-custom-check.jinja
|
||||||
|
- template: jinja
|
||||||
|
- user: root
|
||||||
|
- group: root
|
||||||
|
- mode: '0755'
|
||||||
|
- context:
|
||||||
|
custom_check_log_dir: {{ custom_check_log_dir }}
|
||||||
|
- require:
|
||||||
|
- pkg: pmg-custom-check-managed-packages
|
||||||
|
- file: pmg-custom-check-log-dir
|
||||||
|
|
||||||
|
{% if custom_check_kaspersky_ready %}
|
||||||
|
pmg-custom-check-kaspersky-ready:
|
||||||
|
test.nop:
|
||||||
|
- name: "KESL and klnagent64 are installed."
|
||||||
|
{% else %}
|
||||||
|
pmg-custom-check-kaspersky-missing-note:
|
||||||
|
test.show_notification:
|
||||||
|
- text: "KESL/klnagent64 не найдены. Установите через Kaspersky Administration Center (сервисный superuser/NOPASSWD), затем повторите state.apply pmg.custom_check."
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if custom_check_kaspersky_ready %}
|
||||||
|
{% for service_name in custom_check_required_services %}
|
||||||
|
pmg-custom-check-service-{{ service_name }}:
|
||||||
|
service.running:
|
||||||
|
- name: {{ service_name }}
|
||||||
|
- enable: true
|
||||||
|
- require:
|
||||||
|
- test: pmg-custom-check-kaspersky-ready
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
pmg-custom-check-enable-in-pmg:
|
||||||
|
cmd.run:
|
||||||
|
- name: pmgsh set /config/admin --custom_check 1
|
||||||
|
- unless: "pmgsh get /config/admin | grep -q '\"custom_check\" : 1'"
|
||||||
|
- require:
|
||||||
|
- file: pmg-custom-check-script
|
||||||
|
- pkg: pmg-custom-check-managed-packages
|
||||||
|
{% for service_name in custom_check_required_services %}
|
||||||
|
- service: pmg-custom-check-service-{{ service_name }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
pmg-custom-check-disabled-note:
|
||||||
|
test.show_notification:
|
||||||
|
- text: "PMG custom_check disabled by pillar (pmg.custom_check.enabled=false)."
|
||||||
|
{% endif %}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
APT::Periodic::Update-Package-Lists "1";
|
||||||
|
APT::Periodic::Download-Upgradeable-Packages "1";
|
||||||
|
APT::Periodic::Unattended-Upgrade "1";
|
||||||
|
APT::Periodic::AutocleanInterval "7";
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
Unattended-Upgrade::Origins-Pattern {
|
||||||
|
"origin=Debian,codename=${distro_codename},label=Debian-Security";
|
||||||
|
"origin=Debian,codename=${distro_codename}-security,label=Debian-Security";
|
||||||
|
};
|
||||||
|
|
||||||
|
Unattended-Upgrade::Package-Blacklist {
|
||||||
|
};
|
||||||
|
|
||||||
|
Unattended-Upgrade::MinimalSteps "true";
|
||||||
|
Unattended-Upgrade::InstallOnShutdown "false";
|
||||||
|
Unattended-Upgrade::MailOnlyOnError "true";
|
||||||
|
Unattended-Upgrade::Remove-Unused-Dependencies "true";
|
||||||
|
Unattended-Upgrade::Automatic-Reboot "false";
|
||||||
|
Unattended-Upgrade::SyslogEnable "true";
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
# Managed by Salt.
|
||||||
|
PasswordAuthentication {{ "yes" if ssh_password_authentication else "no" }}
|
||||||
|
PermitRootLogin prohibit-password
|
||||||
|
PubkeyAuthentication yes
|
||||||
|
X11Forwarding no
|
||||||
|
MaxAuthTries 3
|
||||||
|
LoginGraceTime 30
|
||||||
|
{% if ssh_allow_users %}
|
||||||
|
AllowUsers {{ " ".join(ssh_allow_users) }}
|
||||||
|
{% endif %}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
## Managed by Salt.
|
||||||
|
-D
|
||||||
|
-b 8192
|
||||||
|
|
||||||
|
-w /etc/passwd -p wa -k identity
|
||||||
|
-w /etc/group -p wa -k identity
|
||||||
|
-w /etc/shadow -p wa -k identity
|
||||||
|
-w /etc/gshadow -p wa -k identity
|
||||||
|
|
||||||
|
-w /etc/sudoers -p wa -k privilege-escalation
|
||||||
|
-w /etc/sudoers.d/ -p wa -k privilege-escalation
|
||||||
|
|
||||||
|
-w /etc/ssh/sshd_config -p wa -k ssh
|
||||||
|
-w /etc/ssh/sshd_config.d/ -p wa -k ssh
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
[Journal]
|
||||||
|
SystemMaxUse={{ journald_system_max_use }}
|
||||||
|
MaxFileSec={{ journald_max_file_sec }}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Managed by Salt: PMG custom check via Kaspersky KESL.
|
||||||
|
|
||||||
|
set -u
|
||||||
|
|
||||||
|
LOG_DIR="{{ custom_check_log_dir }}"
|
||||||
|
KESL_BIN="/opt/kaspersky/kesl/bin/kesl-control"
|
||||||
|
SCAN_TARGET="${2:-}"
|
||||||
|
|
||||||
|
if [ -z "${SCAN_TARGET}" ]; then
|
||||||
|
echo "v1"
|
||||||
|
echo "ERROR: empty scan target"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "${LOG_DIR}"
|
||||||
|
|
||||||
|
POLICY_NAME="$(pwgen 10 -1 -s -0)"
|
||||||
|
POLICY_FILE="${LOG_DIR}/${POLICY_NAME}.pol"
|
||||||
|
|
||||||
|
cat > "${POLICY_FILE}" <<EOF
|
||||||
|
ActionOnThreat=Inform
|
||||||
|
ReportCleanObjects=No
|
||||||
|
ScanFiles=Yes
|
||||||
|
ScanMailBases=Yes
|
||||||
|
ScanPlainMail=Yes
|
||||||
|
UseAnalyzer=Yes
|
||||||
|
HeuristicLevel=Medium
|
||||||
|
[ScanScope.item_0000]
|
||||||
|
Path=${SCAN_TARGET}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
"${KESL_BIN}" --create-task "${POLICY_NAME}" --type ODS --file "${POLICY_FILE}" >/dev/null
|
||||||
|
VIRUS_NAME="$("${KESL_BIN}" --start-task "${POLICY_NAME}" -W | grep 'DetectName' | awk -F'=' '{print $2}' | head -1)"
|
||||||
|
"${KESL_BIN}" --delete-task "${POLICY_NAME}"
|
||||||
|
|
||||||
|
if [ -z "${VIRUS_NAME}" ]; then
|
||||||
|
rm -f "${POLICY_FILE}"
|
||||||
|
echo "Mail ${SCAN_TARGET} was checked successfully" >> "${LOG_DIR}/checked"
|
||||||
|
echo "v1"
|
||||||
|
echo "OK"
|
||||||
|
else
|
||||||
|
echo "In mail ${SCAN_TARGET} find ${VIRUS_NAME}" >> "${POLICY_FILE}"
|
||||||
|
echo "Mail ${SCAN_TARGET} was blocked. More info in ${POLICY_FILE}" >> "${LOG_DIR}/checked"
|
||||||
|
echo "v1"
|
||||||
|
echo "VIRUS: ${VIRUS_NAME}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit 0
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
include:
|
||||||
|
- pmg.common
|
||||||
|
- pmg.ssh_hardening
|
||||||
|
- pmg.custom_check
|
||||||
|
- pmg.security_agents
|
||||||
|
- pmg.auto_updates
|
||||||
|
- pmg.audit_logging
|
||||||
|
- pmg.pmg_baseline
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
{% set pmg_services = salt['pillar.get']('pmg:pmg_services', []) %}
|
||||||
|
{% set manage_hosts_file = salt['pillar.get']('pmg:manage_hosts_file', False) %}
|
||||||
|
{% set hosts_file_entries = salt['pillar.get']('pmg:hosts_file_entries', []) %}
|
||||||
|
|
||||||
|
{% for svc in pmg_services %}
|
||||||
|
pmg-service-{{ svc }}:
|
||||||
|
service.running:
|
||||||
|
- name: {{ svc }}
|
||||||
|
- enable: true
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
pmg-cluster-status:
|
||||||
|
cmd.run:
|
||||||
|
- name: pmgcm status
|
||||||
|
|
||||||
|
{% if manage_hosts_file %}
|
||||||
|
pmg-managed-hosts:
|
||||||
|
file.blockreplace:
|
||||||
|
- name: /etc/hosts
|
||||||
|
- marker_start: "#-- SALT PMG HOSTS START --"
|
||||||
|
- marker_end: "#-- SALT PMG HOSTS END --"
|
||||||
|
- append_if_not_found: true
|
||||||
|
- content: |
|
||||||
|
{% for host in hosts_file_entries %}
|
||||||
|
{% if host.get('aliases', []) %}
|
||||||
|
{{ host['ip'] }} {{ host['hostname'] }} {{ ' '.join(host['aliases']) }}
|
||||||
|
{% else %}
|
||||||
|
{{ host['ip'] }} {{ host['hostname'] }}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
{% set wazuh_enabled = salt['pillar.get']('pmg:wazuh:enabled', True) %}
|
||||||
|
{% set wazuh_version = salt['pillar.get']('pmg:wazuh:version', '4.14.0-1') %}
|
||||||
|
{% set wazuh_manager = salt['pillar.get']('pmg:wazuh:manager', '10.80.120.205') %}
|
||||||
|
{% set wazuh_group = salt['pillar.get']('pmg:wazuh:group', 'test_auditd_unix') %}
|
||||||
|
{% set wazuh_pkg_name = 'wazuh-agent_' ~ wazuh_version ~ '_amd64.deb' %}
|
||||||
|
{% set wazuh_pkg_url = 'https://packages.wazuh.com/4.x/apt/pool/main/w/wazuh-agent/' ~ wazuh_pkg_name %}
|
||||||
|
{% set wazuh_pkg_path = '/var/tmp/' ~ wazuh_pkg_name %}
|
||||||
|
|
||||||
|
{% set qualys_enabled = salt['pillar.get']('pmg:qualys:enabled', True) %}
|
||||||
|
{% set qualys_package_url = salt['pillar.get']('pmg:qualys:package_url', 'https://storage.yandexcloud.net/qualys-agent/QualysCloudAgent.deb') %}
|
||||||
|
{% set qualys_package_path = salt['pillar.get']('pmg:qualys:package_path', '/opt/QualysCloudAgent.deb') %}
|
||||||
|
{% set qualys_activation_id = salt['pillar.get']('pmg:qualys:activation_id', '') %}
|
||||||
|
{% set qualys_customer_id = salt['pillar.get']('pmg:qualys:customer_id', '') %}
|
||||||
|
{% set qualys_server_uri = salt['pillar.get']('pmg:qualys:server_uri', 'https://qagpublic.qg1.apps.qualys.eu/CloudAgent/') %}
|
||||||
|
|
||||||
|
{% if wazuh_enabled %}
|
||||||
|
pmg-wazuh-download:
|
||||||
|
cmd.run:
|
||||||
|
- name: wget -qO {{ wazuh_pkg_path }} {{ wazuh_pkg_url }}
|
||||||
|
- unless: test -f {{ wazuh_pkg_path }}
|
||||||
|
|
||||||
|
pmg-wazuh-install:
|
||||||
|
cmd.run:
|
||||||
|
- name: WAZUH_MANAGER='{{ wazuh_manager }}' WAZUH_AGENT_GROUP='{{ wazuh_group }}' WAZUH_AGENT_NAME="$(hostname -f)" dpkg -i {{ wazuh_pkg_path }}
|
||||||
|
- unless: dpkg-query -W -f='${Status}' wazuh-agent 2>/dev/null | grep -q 'install ok installed'
|
||||||
|
- require:
|
||||||
|
- cmd: pmg-wazuh-download
|
||||||
|
|
||||||
|
pmg-wazuh-service:
|
||||||
|
service.running:
|
||||||
|
- name: wazuh-agent
|
||||||
|
- enable: true
|
||||||
|
- require:
|
||||||
|
- cmd: pmg-wazuh-install
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if qualys_enabled and qualys_package_path and qualys_activation_id and qualys_customer_id %}
|
||||||
|
pmg-qualys-download:
|
||||||
|
cmd.run:
|
||||||
|
- name: wget -qO {{ qualys_package_path }} {{ qualys_package_url }}
|
||||||
|
- unless: test -f {{ qualys_package_path }}
|
||||||
|
|
||||||
|
pmg-qualys-install:
|
||||||
|
cmd.run:
|
||||||
|
- name: dpkg --install {{ qualys_package_path }}
|
||||||
|
- onlyif: test -f {{ qualys_package_path }}
|
||||||
|
- unless: dpkg-query -W -f='${Status}' qualys-cloud-agent 2>/dev/null | grep -q 'install ok installed'
|
||||||
|
- require:
|
||||||
|
- cmd: pmg-qualys-download
|
||||||
|
|
||||||
|
pmg-qualys-activate:
|
||||||
|
cmd.run:
|
||||||
|
- name: /usr/local/qualys/cloud-agent/bin/qualys-cloud-agent.sh ActivationId={{ qualys_activation_id }} CustomerId={{ qualys_customer_id }} ServerUri={{ qualys_server_uri }}
|
||||||
|
- onchanges:
|
||||||
|
- cmd: pmg-qualys-install
|
||||||
|
- onlyif: test -x /usr/local/qualys/cloud-agent/bin/qualys-cloud-agent.sh
|
||||||
|
|
||||||
|
pmg-qualys-service:
|
||||||
|
service.running:
|
||||||
|
- name: qualys-cloud-agent
|
||||||
|
- enable: true
|
||||||
|
- onlyif: test -f {{ qualys_package_path }}
|
||||||
|
- require:
|
||||||
|
- cmd: pmg-qualys-install
|
||||||
|
{% elif qualys_enabled %}
|
||||||
|
pmg-qualys-skipped:
|
||||||
|
test.show_notification:
|
||||||
|
- text: "Qualys agent skipped: set package_url + package_path + activation_id + customer_id in pillar."
|
||||||
|
{% endif %}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
{% set ssh_allow_users = salt['pillar.get']('pmg:ssh_allow_users', []) %}
|
||||||
|
{% set ssh_password_authentication = salt['pillar.get']('pmg:ssh_password_authentication', True) %}
|
||||||
|
|
||||||
|
pmg-sshd-dropin-dir:
|
||||||
|
file.directory:
|
||||||
|
- name: /etc/ssh/sshd_config.d
|
||||||
|
- user: root
|
||||||
|
- group: root
|
||||||
|
- mode: '0755'
|
||||||
|
|
||||||
|
pmg-sshd-hardening-config:
|
||||||
|
file.managed:
|
||||||
|
- name: /etc/ssh/sshd_config.d/99-hardening.conf
|
||||||
|
- source: salt://pmg/files/99-hardening.conf.jinja
|
||||||
|
- template: jinja
|
||||||
|
- context:
|
||||||
|
ssh_allow_users: {{ ssh_allow_users }}
|
||||||
|
ssh_password_authentication: {{ ssh_password_authentication }}
|
||||||
|
- user: root
|
||||||
|
- group: root
|
||||||
|
- mode: '0644'
|
||||||
|
|
||||||
|
pmg-validate-sshd-config:
|
||||||
|
cmd.run:
|
||||||
|
- name: sshd -t
|
||||||
|
- onchanges:
|
||||||
|
- file: pmg-sshd-hardening-config
|
||||||
|
|
||||||
|
pmg-sshd-service:
|
||||||
|
service.running:
|
||||||
|
- name: ssh
|
||||||
|
- enable: true
|
||||||
|
- reload: true
|
||||||
|
- watch:
|
||||||
|
- cmd: pmg-validate-sshd-config
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
{% set pmg_services = salt['pillar.get']('pmg:pmg_services', []) %}
|
||||||
|
{% set pmg_update_dist_upgrade = salt['pillar.get']('pmg:update_dist_upgrade', True) %}
|
||||||
|
{% set pmg_update_auto_reboot = salt['pillar.get']('pmg:update_auto_reboot', False) %}
|
||||||
|
{% set pmg_update_reboot_delay_minutes = salt['pillar.get']('pmg:update_reboot_delay_minutes', 1) %}
|
||||||
|
|
||||||
|
pmg-update-precheck-cluster:
|
||||||
|
cmd.run:
|
||||||
|
- name: pmgcm status
|
||||||
|
|
||||||
|
{% for svc in pmg_services %}
|
||||||
|
pmg-update-precheck-service-{{ svc }}:
|
||||||
|
cmd.run:
|
||||||
|
- name: systemctl is-active --quiet {{ svc }}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
pmg-update-packages:
|
||||||
|
pkg.uptodate:
|
||||||
|
- refresh: true
|
||||||
|
- dist_upgrade: {{ pmg_update_dist_upgrade }}
|
||||||
|
|
||||||
|
pmg-update-postcheck-cluster:
|
||||||
|
cmd.run:
|
||||||
|
- name: pmgcm status
|
||||||
|
- require:
|
||||||
|
- pkg: pmg-update-packages
|
||||||
|
|
||||||
|
{% for svc in pmg_services %}
|
||||||
|
pmg-update-postcheck-service-{{ svc }}:
|
||||||
|
cmd.run:
|
||||||
|
- name: systemctl is-active --quiet {{ svc }}
|
||||||
|
- require:
|
||||||
|
- pkg: pmg-update-packages
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
pmg-update-reboot-required-note:
|
||||||
|
test.show_notification:
|
||||||
|
- text: "После обновления требуется reboot: /var/run/reboot-required"
|
||||||
|
- onlyif: test -f /var/run/reboot-required
|
||||||
|
|
||||||
|
{% if pmg_update_auto_reboot %}
|
||||||
|
pmg-update-schedule-reboot:
|
||||||
|
cmd.run:
|
||||||
|
- name: "shutdown -r +{{ pmg_update_reboot_delay_minutes }} \"Salt pmg.update: reboot required\""
|
||||||
|
- onlyif: test -f /var/run/reboot-required
|
||||||
|
- require:
|
||||||
|
- cmd: pmg-update-postcheck-cluster
|
||||||
|
{% for svc in pmg_services %}
|
||||||
|
- cmd: pmg-update-postcheck-service-{{ svc }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
{% set pmg_services = salt['pillar.get']('pmg:pmg_services', []) %}
|
||||||
|
|
||||||
|
{% for svc in pmg_services %}
|
||||||
|
pmg-verify-service-{{ svc }}:
|
||||||
|
cmd.run:
|
||||||
|
- name: systemctl is-active --quiet {{ svc }}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
pmg-verify-cluster:
|
||||||
|
cmd.run:
|
||||||
|
- name: pmgcm status
|
||||||
|
|
||||||
|
pmg-verify-sshd-config:
|
||||||
|
cmd.run:
|
||||||
|
- name: sshd -t
|
||||||
Reference in New Issue
Block a user