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. Это позволяет эффективно мониторить базу данных и системные события.

Комментарии (0)