Привет, защитники! На связи Pensecfort.
В видео я разобрал, что такое SCA (Security Configuration Assessment) в Wazuh — ваш личный системный аудитор, который автоматически проверяет серверы на соответствие стандартам безопасности (CIS, NIST, PCI DSS и вашим внутренним политикам).
Wazuh из коробки даёт отличные политики на основе CIS Benchmarks. Но что делать, если у вас:
специфичный корпоративный стандарт?
нужно проверять кастомные приложения?
хочется убедиться, что разработчики не оставили
debug: trueв продакшене?
Ответ один — писать свои кастомные политики.
Сегодня я разберу анатомию SCA-политик от и до, покажу все подводные камни и в конце дам готовый мощный пример для SSH Hardening. Также вот ссылка на официальную документацию.
Анатомия SCA-политики
Любая политика — это обычный YAML-файл с четырьмя основными секциями:
Секция | Обязательна? | Для чего |
| Да | Паспорт политики (id, название, описание) |
| Нет | «Фейс-контроль» — если не выполнено, сканирование даже не запустится |
| Нет | Переменные ( |
| Да | Самое мясо — список проверок |
Синтаксис правил — всё, что нуж��о знать
Формула правила: ТИП:ЛОКАЦИЯ -> ОПЕРАТОР:ЗНАЧЕНИЕ
Тип | Что проверяет | Пример |
| файл (существование или содержимое) |
|
| директория (рекурсивно!) |
|
| процесс (только существование) |
|
| вывод команды |
|
| реестр Windows |
|
Операторы проверки контента:
Оператор | Что делает | Пример |
(без оператора) | точное совпадение строки |
|
| регулярное выражение |
|
| числовое сравнение |
|
| отрицание |
|
| логическое И (цепочки) |
|
> Важно: пробелы вокруг ->, &&, compare обязательны!
Как работает condition (таблица оценки)
condition | Все правила Passed | Есть Failed | Есть Not applicable | Итог |
| Да | Нет | Нет | Passed |
| — | Да | — | Failed |
| — | Нет | Да | Not applicable |
| Да | — | — | Passed |
| Нет | Да | Нет | Failed |
| Нет | — | Да | Not applicable |
| Нет | Да | — | Passed |
| Да | — | — | Failed |
Рекурсивные проверки директорий (d:)
Очень мощная фича, которой многие не пользуются:
```yaml - id: 200025 title: "SSH: в sshd_config.d нет слабых алгоритмов" rules: - 'd:/etc/ssh/sshd_config.d -> r:\.conf$ -> !r:(MD5|DES|RC4|3DES)'
Частые ошибки (чек-лист)
Ошибка | Последствия | Как исправить |
Забыли sca.remote_commands=1 | Все c: → Not applicable / Failed | Добавить в local_internal_options.conf и перезапустить агент |
Пропущены пробелы вокруг ->, &&, compare | Правило не парсится → Not applicable | Проверять строго: -> , &&, compare |
«Жадное» отрицание !r: | Ложные Passed | Писать явно: r:^PermitRootLogin\s+no вместо !r:PermitRootLogin |
Не учли Include /etc/ssh/sshd_config.d/*.conf | Пропускаются настройки из дополнительных файлов | Добавлять переменную $sshd_config_d и рекурсивные d: проверки |
ID пересекаются с дефолтными политиками | Конфликты при обновлении | Используйте диапазон 100000–299999 |
Практика: разбор sca_ssh_hardening.yml
Самый важный трюк — проверяем и файл, и реальную конфигурацию в памяти:
- id: 200000 title: "SSH: Ciphers настроены безопасно" condition: all rules: - 'f:$sshd_config -> r:^Ciphers\s+chacha20-poly1305@openssh.com,aes256-gcm...' - 'c:sshd -T -> r:^ciphers chacha20-poly1305@openssh.com,aes256-gcm...'
Если вы изменили файл, но забыли systemctl restart sshd — получите Failed. Это защита от configuration drift.
Как раздавать политику централизованно
Никогда не кладите свои политики в /var/ossec/ruleset/sca — при обновлении всё затрётся!
Правильно:
На менеджере: /var/ossec/etc/shared/default/sca_ssh_hardening.yml (или в нужной группе)
В agent.conf группы:
<agent_config> <sca> <policies> <policy>etc/shared/sca_ssh_hardening.yml</policy> </policies> </sca> </agent_config>
Как протестировать локально (не ломая прод)
1.Скопируйте .yml только на один тестовый агент в /var/ossec/etc/shared/, либо через менеджер, создать тестовую группу, поместить туда тестовый агент в /var/ossec/etc/shared/TEST/
2.Добавьте в локальный ossec.conf, либо если используете тестирование через менеджер в /var/ossec/etc/shared/TEST/agent.conf:
<sca> <policies> <policy>etc/shared/sca_ssh_hardening.yml</policy> </policies> </sca>
3. systemctl restart wazuh-agent
4.Смотреть результат в Wazuh-dashboard->Endpoint security->Configuration Assessment
Минимальный шаблон для старта
policy: id: "my_custom_policy" file: "my_custom_policy.yml" name: "Моя кастомная политика" description: "Проверка внутренних стандартов" variables: $my_app_config: "/opt/myapp/config.yaml" checks: - id: 100001 title: "MyApp: debug mode выключен" rationale: "Режим отладки выводит чувствительные данные" remediation: "Установите debug: false и перезапустите сервис" compliance: - internal_corp: ["SEC-007"] condition: all rules: - 'f:$$ my_app_config -> r:^debug:\s*false $$'
Дополнительно:
Исходная конфигурация sshd_config для которой была разработана политика sca_linux_auditd.yml в видео для детального анализа.
Include /etc/ssh/sshd_config.d/*.conf Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr LogLevel VERBOSE LoginGraceTime 60 MaxAuthTries 4 MaxSessions 10 AllowGroups ssh_access PubkeyAuthentication yes HostbasedAuthentication no IgnoreRhosts yes KbdInteractiveAuthentication no UsePAM yes PermitRootLogin no AllowTcpForwarding no X11Forwarding no PrintMotd no PermitUserEnvironment no ClientAliveCountMax 3 MaxStartups 10:30:60 AcceptEnv LANG LC_* Subsystem sftp /usr/lib/openssh/sftp-server PasswordAuthentication no MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512,hmac-sha2-256 KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group14-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256 Banner /etc/issue.net
Политика sca_linux_auditd.yml:
# Security Configuration Assessment # SSH Hardening Policy for Linux systems # Copyright (C) 2025, @pensecfort # # This program is free software; you can redistribute it # and/or modify it under the terms of the GNU General Public # License (version 2) as published by the FSF - Free Software # Foundation policy: id: "ssh_hardening" file: "sca_ssh_hardening.yml" name: "SSH Hardening Configuration Assessment" description: "Полная проверка конфигурации SSH для обеспечения безопасности: проверка ключевых параметров в файле sshd_config и через команду sshd -T." references: - "https://cisecurity.org/benchmark/linux_server" - "https://www.ssh.com/academy/ssh/config" - "https://www.nist.gov/itl/applied-cybersecurity/nist-cybersecurity-framework" requirements: title: "Требования для запуска сканирования SSH" description: "Проверяем наличие ключевых компонентов SSH перед сканированием (файлы конфигурации и наличие sshd)." condition: any rules: - 'c:which sshd' # Проверяем наличие бинарника sshd - 'f:/etc/ssh/sshd_config' # Основной файл конфигурации - 'd:/etc/ssh/sshd_config.d' # Директория include variables: $sshd_config: "/etc/ssh/sshd_config" $sshd_config_d: "/etc/ssh/sshd_config.d/.*\\.conf" # Паттерн для include-файлов $sshd_banner: "/etc/issue.net" # Файл баннера checks: - id: 200000 title: "SSH: Ciphers настроены безопасно" description: "Проверяем, что список Ciphers включает только сильные шифры (chacha20-poly1305, aes-gcm, aes-ctr)." rationale: "Использование слабых шифров может привести к MITM-атакам; сильные шифры обеспечивают конфиденциальность (CIS 5.2.12, NIST SC-8)." remediation: "Добавьте в sshd_config: Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr; перезапустите sshd: systemctl restart sshd." compliance: - cis: ["5.2.12"] - nist_800_53: ["SC-8"] condition: all rules: - 'f:$sshd_config -> r:^Ciphers\s+chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr' - 'c:sshd -T -> r:^ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr' - id: 200001 title: "SSH: LogLevel установлен на VERBOSE" description: "Проверяем, что уровень логирования LogLevel = VERBOSE для детального аудита." rationale: "VERBOSE логи позволяют отслеживать подозрительные попытки аутентификации (CIS 5.2.3, NIST AU-3)." remediation: "Добавьте в sshd_config: LogLevel VERBOSE; перезапустите sshd." compliance: - cis: ["5.2.3"] - nist_800_53: ["AU-3"] condition: all rules: - 'f:$sshd_config -> r:^LogLevel\s+VERBOSE' - 'c:sshd -T -> r:^loglevel verbose' - id: 200002 title: "SSH: LoginGraceTime = 60" description: "Проверяем, что время ожидания логина LoginGraceTime = 60 секунд." rationale: "Ограничение времени снижает риск brute-force атак (CIS 5.2.4, NIST AC-7)." remediation: "Добавьте в sshd_config: LoginGraceTime 60; перезапустите sshd." compliance: - cis: ["5.2.4"] - nist_800_53: ["AC-7"] condition: all rules: - 'f:$sshd_config -> r:^LoginGraceTime\s+60' - 'c:sshd -T -> r:^logingracetime 60' - id: 200003 title: "SSH: MaxAuthTries = 4" description: "Проверяем, что максимум попыток аутентификации MaxAuthTries = 4." rationale: "Ограничение попыток защищает от brute-force (CIS 5.2.5, NIST AC-7)." remediation: "Добавьте в sshd_config: MaxAuthTries 4; перезапустите sshd." compliance: - cis: ["5.2.5"] - nist_800_53: ["AC-7"] condition: all rules: - 'f:$sshd_config -> r:^MaxAuthTries\s+4' - 'c:sshd -T -> r:^maxauthtries 4' - id: 200004 title: "SSH: MaxSessions = 10" description: "Проверяем, что максимум сессий MaxSessions = 10." rationale: "Ограничение сессий снижает нагрузку и риск DoS (CIS 5.2.6, NIST SC-5)." remediation: "Добавьте в sshd_config: MaxSessions 10; перезапустите sshd." compliance: - cis: ["5.2.6"] - nist_800_53: ["SC-5"] condition: all rules: - 'f:$sshd_config -> r:^MaxSessions\s+10' - 'c:sshd -T -> r:^maxsessions 10' - id: 200005 title: "SSH: AllowGroups = ssh_access" description: "Проверяем, что доступ ограничен группой AllowGroups = ssh_access." rationale: "Ограничение по группам повышает контроль доступа (CIS 5.2.7, NIST AC-3)." remediation: "Добавьте в sshd_config: AllowGroups ssh_access; перезапустите sshd." compliance: - cis: ["5.2.7"] - nist_800_53: ["AC-3"] condition: all rules: - 'f:$sshd_config -> r:^AllowGroups\s+ssh_access' - 'c:sshd -T -> r:^allowgroups ssh_access' - id: 200006 title: "SSH: PubkeyAuthentication = yes" description: "Проверяем, что аутентификация по ключу PubkeyAuthentication = yes." rationale: "Ключевая аутентификация безопаснее паролей (CIS 5.2.8, NIST IA-5)." remediation: "Добавьте в sshd_config: PubkeyAuthentication yes; перезапустите sshd." compliance: - cis: ["5.2.8"] - nist_800_53: ["IA-5"] condition: all rules: - 'f:$sshd_config -> r:^PubkeyAuthentication\s+yes' - 'c:sshd -T -> r:^pubkeyauthentication yes' - id: 200007 title: "SSH: HostbasedAuthentication = no" description: "Проверяем, что HostbasedAuthentication отключена (no)." rationale: "Hostbased уязвима к spoofing; отключение повышает безопасность (CIS 5.2.9, NIST IA-2)." remediation: "Добавьте в sshd_config: HostbasedAuthentication no; перезапустите sshd." compliance: - cis: ["5.2.9"] - nist_800_53: ["IA-2"] condition: all rules: - 'f:$sshd_config -> r:^HostbasedAuthentication\s+no' - 'c:sshd -T -> r:^hostbasedauthentication no' - id: 200008 title: "SSH: IgnoreRhosts = yes" description: "Проверяем, что IgnoreRhosts = yes (игнорировать .rhosts)." rationale: "Игнорирование rhosts предотвращает старые уязвимые методы аутентификации (CIS 5.2.10, NIST IA-2)." remediation: "Добавьте в sshd_config: IgnoreRhosts yes; перезапустите sshd." compliance: - cis: ["5.2.10"] - nist_800_53: ["IA-2"] condition: all rules: - 'f:$sshd_config -> r:^IgnoreRhosts\s+yes' - 'c:sshd -T -> r:^ignorerhosts yes' - id: 200009 title: "SSH: KbdInteractiveAuthentication = no" description: "Проверяем, что KbdInteractiveAuthentication отключена (no)." rationale: "Отключение keyboard-interactive снижает риск слабых методов аутентификации (CIS 5.2.11, NIST IA-2)." remediation: "Добавьте в sshd_config: KbdInteractiveAuthentication no; перезапустите sshd." compliance: - cis: ["5.2.11"] - nist_800_53: ["IA-2"] condition: all rules: - 'f:$sshd_config -> r:^KbdInteractiveAuthentication\s+no' - 'c:sshd -T -> r:^kbdinteractiveauthentication no' - id: 200010 title: "SSH: UsePAM = yes" description: "Проверяем, что UsePAM = yes для интеграции с PAM." rationale: "PAM обеспечивает дополнительный контроль аутентификации (CIS 5.2.1, NIST IA-5)." remediation: "Добавьте в sshd_config: UsePAM yes; перезапустите sshd." compliance: - cis: ["5.2.1"] - nist_800_53: ["IA-5"] condition: all rules: - 'f:$sshd_config -> r:^UsePAM\s+yes' - 'c:sshd -T -> r:^usepam yes' - id: 200011 title: "SSH: PermitRootLogin = no" description: "Проверяем, что логин root запрещён (PermitRootLogin = no)." rationale: "Запрет root-логинов снижает риск компрометации (CIS 5.2.2, NIST AC-6)." remediation: "Добавьте в sshd_config: PermitRootLogin no; перезапустите sshd." compliance: - cis: ["5.2.2"] - nist_800_53: ["AC-6"] condition: all rules: - 'f:$sshd_config -> r:^PermitRootLogin\s+no' - 'c:sshd -T -> r:^permitrootlogin no' - id: 200012 title: "SSH: AllowTcpForwarding = no" description: "Проверяем, что TCP-форвардинг отключён (no)." rationale: "Отключение форвардинга предотвращает туннелирование (CIS 5.2.13, NIST SC-7)." remediation: "Добавьте в sshd_config: AllowTcpForwarding no; перезапустите sshd." compliance: - cis: ["5.2.13"] - nist_800_53: ["SC-7"] condition: all rules: - 'f:$sshd_config -> r:^AllowTcpForwarding\s+no' - 'c:sshd -T -> r:^allowtcpforwarding no' - id: 200013 title: "SSH: X11Forwarding = no" description: "Проверяем, что X11-форвардинг отключён (no)." rationale: "X11 уязвим к захвату сессий; отключение повышает безопасность (CIS 5.2.14, NIST SC-7)." remediation: "Добавьте в sshd_config: X11Forwarding no; перезапустите sshd." compliance: - cis: ["5.2.14"] - nist_800_53: ["SC-7"] condition: all rules: - 'f:$sshd_config -> r:^X11Forwarding\s+no' - 'c:sshd -T -> r:^x11forwarding no' - id: 200014 title: "SSH: PrintMotd = no" description: "Проверяем, что печать MOTD отключена (no)." rationale: "Отключение MOTD снижает утечку информации о системе (CIS 5.2.15, NIST SC-18)." remediation: "Добавьте в sshd_config: PrintMotd no; перезапустите sshd." compliance: - cis: ["5.2.15"] - nist_800_53: ["SC-18"] condition: all rules: - 'f:$sshd_config -> r:^PrintMotd\s+no' - 'c:sshd -T -> r:^printmotd no' - id: 200015 title: "SSH: PermitUserEnvironment = no" description: "Проверяем, что PermitUserEnvironment отключено (no)." rationale: "Отключение предотвращает инъекции переменных окружения (CIS 5.2.16, NIST SC-18)." remediation: "Добавьте в sshd_config: PermitUserEnvironment no; перезапустите sshd." compliance: - cis: ["5.2.16"] - nist_800_53: ["SC-18"] condition: all rules: - 'f:$sshd_config -> r:^PermitUserEnvironment\s+no' - 'c:sshd -T -> r:^permituserenvironment no' - id: 200016 title: "SSH: ClientAliveCountMax = 3" description: "Проверяем, что максимум живых клиентов ClientAliveCountMax = 3." rationale: "Ограничение снижает риск DoS от неактивных сессий (CIS 5.2.17, NIST SC-5)." remediation: "Добавьте в sshd_config: ClientAliveCountMax 3; перезапустите sshd." compliance: - cis: ["5.2.17"] - nist_800_53: ["SC-5"] condition: all rules: - 'f:$sshd_config -> r:^ClientAliveCountMax\s+3' - 'c:sshd -T -> r:^clientalivecountmax 3' - id: 200017 title: "SSH: MaxStartups = 10:30:60" description: "Проверяем, что ограничение стартапов MaxStartups = 10:30:60." rationale: "Ограничение защищает от DoS на соединения (CIS 5.2.18, NIST SC-5)." remediation: "Добавьте в sshd_config: MaxStartups 10:30:60; перезапустите sshd." compliance: - cis: ["5.2.18"] - nist_800_53: ["SC-5"] condition: all rules: - 'f:$sshd_config -> r:^MaxStartups\s+10:30:60' - 'c:sshd -T -> r:^maxstartups 10:30:60' - id: 200018 title: "SSH: AcceptEnv = LANG LC_*" description: "Проверяем, что AcceptEnv ограничено LANG LC_*." rationale: "Ограничение переменных снижает риск инъекций (CIS 5.2.19, NIST SC-18)." remediation: "Добавьте в sshd_config: AcceptEnv LANG LC_*; перезапустите sshd." compliance: - cis: ["5.2.19"] - nist_800_53: ["SC-18"] condition: all rules: - 'f:$sshd_config -> r:AcceptEnv LANG LC_*' - 'c:sshd -T -> r:acceptenv LANG' - 'c:sshd -T -> r:acceptenv LC_*' - id: 200019 title: "SSH: Subsystem sftp настроен" description: "Проверяем, что Subsystem sftp установлен на /usr/lib/openssh/sftp-server." rationale: "Правильный subsystem обеспечивает безопасный SFTP (CIS 5.2.20, NIST SC-8)." remediation: "Добавьте в sshd_config: Subsystem sftp /usr/lib/openssh/sftp-server; перезапустите sshd." compliance: - cis: ["5.2.20"] - nist_800_53: ["SC-8"] condition: all rules: - 'f:$sshd_config -> r:^Subsystem\s+sftp\s+/usr/lib/openssh/sftp-server' - 'c:sshd -T -> r:^subsystem sftp /usr/lib/openssh/sftp-server' - id: 200020 title: "SSH: PasswordAuthentication = no" description: "Проверяем, что аутентификация по паролю отключена (no)." rationale: "Отключение паролей заставляет использовать ключи, повышая безопасность (CIS 5.2.21, NIST IA-5)." remediation: "Добавьте в sshd_config: PasswordAuthentication no; перезапустите sshd." compliance: - cis: ["5.2.21"] - nist_800_53: ["IA-5"] condition: all rules: - 'f:$sshd_config -> r:^PasswordAuthentication\s+no' - 'c:sshd -T -> r:^passwordauthentication no' - id: 200021 title: "SSH: MACs настроены безопасно" description: "Проверяем, что список MACs включает hmac-sha2-etm и hmac-sha2." rationale: "Сильные MAC защищают от подмены сообщений (CIS 5.2.22, NIST SC-13)." remediation: "Добавьте в sshd_config: MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512,hmac-sha2-256; перезапустите sshd." compliance: - cis: ["5.2.22"] - nist_800_53: ["SC-13"] condition: all rules: - 'f:$sshd_config -> r:^MACs\s+hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512,hmac-sha2-256' - 'c:sshd -T -> r:^macs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512,hmac-sha2-256' - id: 200022 title: "SSH: KexAlgorithms настроены безопасно" description: "Проверяем, что KexAlgorithms включает curve25519, diffie-hellman-group14-sha256 и другие сильные алгоритмы." rationale: "Сильные KEX защищают обмен ключами (CIS 5.2.23, NIST SC-13)." remediation: "Добавьте в sshd_config: KexAlgorithms curve25519-sha256,... (полный список из твоего конфига); перезапустите sshd." compliance: - cis: ["5.2.23"] - nist_800_53: ["SC-13"] condition: all rules: - 'f:$sshd_config -> r:^KexAlgorithms\s+curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group14-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256' - 'c:sshd -T -> r:^kexalgorithms curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group14-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256' - id: 200023 title: "SSH: Banner = /etc/issue.net" description: "Проверяем, что баннер установлен на /etc/issue.net." rationale: "Баннер может содержать предупреждение о мониторинге, отпугивая атакующих (CIS 5.2.24, NIST AC-8)." remediation: "Добавьте в sshd_config: Banner /etc/issue.net; перезапустите sshd." compliance: - cis: ["5.2.24"] - nist_800_53: ["AC-8"] condition: all rules: - 'f:$sshd_config -> r:^Banner\s+/etc/issue.net' - 'c:sshd -T -> r:^banner /etc/issue.net' - id: 200024 title: "SSH: Include sshd_config.d/*.conf" description: "Проверяем, что include из /etc/ssh/sshd_config.d/*.conf включён." rationale: "Include позволяет модульную конфигурацию, облегчая управление (CIS 5.2.25, NIST CM-6)." remediation: "Добавьте в sshd_config: Include /etc/ssh/sshd_config.d/*.conf; перезапустите sshd." compliance: - cis: ["5.2.25"] - nist_800_53: ["CM-6"] condition: all rules: - 'f:$sshd_config -> r:^Include\s+/etc/ssh/sshd_config.d/*.conf' - 'd:/etc/ssh/sshd_config.d' # Проверка директории include
