Wazuh — мощная платформа для мониторинга безопасности, которая позволяет анализировать логи систем и приложений. В этой статье мы разберём, как создать кастомный декодер для логов PostgreSQL, чтобы отслеживать подключения, запросы и ошибки базы данных, а также как улучшить дефолтный декодер auditd для более точной обработки системных логов.
Понимание логов PostgreSQL
Логи PostgreSQL обычно записываются в формате CSV, если настроен параметр log_line_prefix. Вот пример лога:
Jul 13 22:55:56 databases postgresql: 2025-07-13 22:55:55.221 +03,"testuser","testdb",67399,"localhost:35366",68740f4b.10747,2,"authentication",2025-07-13 22:55:55 +03,3/14,0,LOG,00000,"connection authenticated: identity=""testuser"" method=scram-sha-256 (/etc/postgresql/16/main/pg_hba.conf:125)",,,,,,,,"set_authn_id, auth.c:369","","client backend",,0
Jul 13 22:56:56 databases postgresql: 2025-07-13 22:56:56.034 +03,"testuser","testdb",67399,"localhost:35366",68740f4b.10747,5,"ALTER ROLE",2025-07-13 22:55:55 +03,3/16,0,ERROR,42501,"permission denied to rename role","Only roles with the CREATEROLE attribute and the ADMIN option on role ""testrole"" may rename this role.",,,,,"ALTER ROLE testrole RENAME TO new_testrole;",,"RenameRole, user.c:1430","psql","client backend",,0
Эти логи содержат ценную информацию: имя пользователя, база данных, IP-адрес клиента, выполненные команды и коды ошибок. Однако встроенные декодеры Wazuh могут не справляться с кастомным CSV-форматом, поэтому мы создадим свой декодер.
Предварительная настройка: агенты и группы
Для эффективного мониторинга мы разбиваем агентов Wazuh по группам. В нашем случае создана группа postgre, куда добавлен агент с PostgreSQL. Чтобы упростить обработку CSV-логов, преобразуем их в формат Syslog. Настраиваем агента в файле /var/ossec/etc/shared/postgre/agent.conf через CLI, либо Agents management → Groups → postgre → Files → agent.conf через Web-интерфейс:
<agent_config>
<localfile>
<location>/var/log/postgresql/postgresql-*.csv</location>
<log_format>syslog</log_format>
<out_format>$(timestamp) $(hostname) postgresql: $(log)</out_format>
</localfile>
</agent_config>
<location> указывает путь к логам PostgreSQL (маска *.csv захватывает все файлы).
<log_format>syslog</log_format> говорит Wazuh обрабатывать логи как Syslog.
<out_format> добавляет метку времени, имя хоста и программу postgresql, чтобы логи соответствовали Syslog-формату и корректно парсились декодером.
Разделение агентов по группам упрощает управление и позволяет применять разные декодеры и правила к разным типам данных.
Создание кастомного декодера для PostgreSQL
Декодер для PostgreSQL, который извлекает ключевые поля из CSV-логов. Файл декодера находится в /var/ossec/etc/decoders/postgresql_custom.xml (не забыть выставить необходимого пользователя и группу) это если создавать через CLI, Server management → Decoders → Add new decoders file через Web-интерфейс:
<decoder name="postgresql">
<program_name>postgresql</program_name>
</decoder>
<decoder name="postgresql-fields">
<parent>postgresql</parent>
<regex type="pcre2">\d+-\d+-\d+\s+\d+:\d+:\d+\.\d+.+?,[^,](.+?)",</regex>
<order>srcuser</order>
</decoder>
<decoder name="postgresql-fields">
<parent>postgresql</parent>
<regex type="pcre2">\d+-\d+-\d+\s+\d+:\d+:\d+\.\d+.+?,[^,]*,[^,](.+?)",</regex>
<order>database</order>
</decoder>
<decoder name="postgresql-fields">
<parent>postgresql</parent>
<regex type="pcre2">\d+-\d+-\d+\s+\d+:\d+:\d+\.\d+.+?,[^,]*,[^,]*,(\d+)</regex>
<order>process_id</order>
</decoder>
<decoder name="postgresql-fields">
<parent>postgresql</parent>
<regex type="pcre2">\d+-\d+-\d+\s+\d+:\d+:\d+\.\d+.+?,[^,]*,[^,]*,[^,]*,"(\S+):</regex>
<order>srcip</order>
</decoder>
<decoder name="postgresql-fields">
<parent>postgresql</parent>
<regex type="pcre2">\d+-\d+-\d+\s+\d+:\d+:\d+\.\d+.+?,[^,]*,[^,]*,[^,]*,"\S+:(\d+)</regex>
<order>srcport</order>
</decoder>
<decoder name="postgresql-fields">
<parent>postgresql</parent>
<regex type="pcre2">\d+-\d+-\d+\s+\d+:\d+:\d+\.\d+.+?,[^,]*,[^,]*,[^,]*,[^,]*,(.+?),</regex>
<order>session_id</order>
</decoder>
<decoder name="postgresql-fields">
<parent>postgresql</parent>
<regex type="pcre2">\d+-\d+-\d+\s+\d+:\d+:\d+\.\d+.+?,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,"(.+?)"?,</regex>
<order>command_tag</order>
</decoder>
<decoder name="postgresql-fields">
<parent>postgresql</parent>
<regex type="pcre2">\d+-\d+-\d+\s+\d+:\d+:\d+\.\d+.+?,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,(.+?),</regex>
<order>error_severity</order>
</decoder>
<decoder name="postgresql-fields">
<parent>postgresql</parent>
<regex type="pcre2">(authentication\s+failed)</regex>
<order>message</order>
</decoder>
<decoder name="postgresql-fields">
<parent>postgresql</parent>
<regex type="pcre2">\d+-\d+-\d+\s+\d+:\d+:\d+\.\d+.+?,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,"(.+?):</regex>
<order>message</order>
</decoder>
<decoder name="postgresql-fields">
<parent>postgresql</parent>
<regex type="pcre2">\d+-\d+-\d+\s+\d+:\d+:\d+\.\d+.+?,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,"(.+?):</regex>
<order>message</order>
</decoder>
<decoder name="postgresql-fields">
<parent>postgresql</parent>
<regex type="pcre2">\d+-\d+-\d+\s+\d+:\d+:\d+\.\d+.+?,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,""(.+?);</regex>
<order>command</order>
</decoder>
<decoder name="postgresql-fields">
<parent>postgresql</parent>
<regex type="pcre2">\d+-\d+-\d+\s+\d+:\d+:\d+\.\d+.+?,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,(.+?);</regex>
<order>command</order>
</decoder>
\d+-\d+-\d+\s+\d+:\d+:\d+\.\d+.+? --- соответствует временной метке в формате YYYY-MM-DD HH:MM:SS.sss.
[^,]* — пропускает поля, разделённые запятыми, до нужного.
(.+?) — извлекает содержимое поля (например, имя пользователя).
Специфичные паттерны, такие как (authentication\s+failed), обрабатывают ошибки аутентификации
Зачем такой подход?
Родительский декодер postgresql: Фильтрует логи по имени программы postgresql, которое мы добавили в конфигурации агента. Это обеспечивает обработку только соответствующих событий. Множественные декодеры postgresql-fields: Каждый декодер извлекает одно поле (например, srcuser, database, srcip) с помощью регулярных выражений PCRE2. Такой подход удобен для сложных CSV-логов, где поля строго определены и не меняются. Почему отдельные декодеры? Это упрощает отладку и добавление новых полей без изменения общей структуры.
Редактирование дефолтного декодера auditd
В файле /var/ossec/etc/ossec.conf добавляем исключения (Server management -> Settings -> Edit configuration) в блок <ruleset> </ruleset>
добавляем:
<ruleset>
<rule_exclude>0365-auditd_rules.xml</rule_exclude>
<decoder_exclude>ruleset/decoders/0040-auditd_decoders.xml</decoder_exclude>
</ruleset>
Зачем это нужно?
Дефолтный декодер auditd (0040-auditd_decoders.xml) и правила (0365-auditd_rules.xml) могут конфликтовать с кастомным декодером, так как Wazuh обрабатывает дефолтные декодеры в приоритете.
При обновлении Wazuh изменения в дефолтных файлах будут перезаписаны, поэтому мы используем кастомные файлы.
Исключение правил предотвращает ошибки, связанные с ссылками на дефолтный декодер.
В кластере Wazuh исключение нужно сделать на всех нодах для синхронизации.
Создание кастомного декодера auditd
Скопируйте содержимое /var/ossec/ruleset/decoders/0040-auditd_decoders.xml в /var/ossec/etc/decoders/0040-auditd_decoders.xml. Это сохраняет оригинальную логику, но позволяет добавить изменения. Пример изменения, добавления полей для парсинга при execve:
<!--....-->
<decoder name="auditd-syscall">
<parent>auditd</parent>
<regex offset="after_regex">a6="(\.+)" </regex>
<order>audit.execve.a6</order>
</decoder>
<decoder name="auditd-syscall">
<parent>auditd</parent>
<regex offset="after_regex">a7="(\.+)" </regex>
<order>audit.execve.a7</order>
</decoder>
<!--Добавленные поля-->
<decoder name="auditd-syscall">
<parent>auditd</parent>
<regex offset="after_regex">a8="(\.+)" </regex>
<order>audit.execve.a8</order>
</decoder>
<decoder name="auditd-syscall">
<parent>auditd</parent>
<regex offset="after_regex">9="(\.+)" </regex>
<order>audit.execve.a9</order>
</decoder>
<decoder name="auditd-syscall">
<parent>auditd</parent>
<regex offset="after_regex">a10="(\.+)" </regex>
<order>audit.execve.a10</order>
</decoder>
<!--....-->
После создания кастомного декодера уберите исключение правил в /var/ossec/etc/ossec.conf (Server management -> Settings -> Edit configuration) в блоке <ruleset> </ruleset>
:
<ruleset>
<decoder_exclude>ruleset/decoders/0040-auditd_decoders.xml</decoder_exclude>
</ruleset>
Заключение
Теперь вы знаете, как настроить кастомный декодер для PostgreSQL и улучшить декодер auditd в Wazuh. Это позволяет эффективно мониторить базу данных и системные события.