Декодеры Wazuh 4.14 - извлечение данных из логов
Декодеры Wazuh извлекают структурированные данные из необработанных лог-сообщений: IP-адреса, имена пользователей, действия, коды ошибок и другие поля. Без корректного декодирования правила не смогут анализировать события, и алерты не будут содержать полезной информации. В этом руководстве описан синтаксис декодеров, иерархия родительских и дочерних декодеров, встроенные декодеры и процесс создания пользовательских декодеров.
Фазы обработки событий
Каждое событие проходит две фазы декодирования:
Фаза 1: Предварительное декодирование (pre-decoding)
Выполняется автоматически для всех событий. Извлекаются стандартные поля syslog:
- timestamp - временная метка события
- hostname - имя хоста-источника
- program_name - имя программы (из заголовка syslog)
Пример входного лога:
Mar 5 10:15:01 web-server sshd[12345]: Failed password for root from 192.168.1.100 port 22 ssh2Результат pre-decoding:
timestamp: 'Mar 5 10:15:01'
hostname: 'web-server'
program_name: 'sshd'Оставшаяся часть сообщения (Failed password for root from 192.168.1.100 port 22 ssh2) передается в фазу декодирования.
Фаза 2: Декодирование (decoding)
На этой фазе декодеры анализируют тело сообщения и извлекают специфичные поля. Декодеры применяются в порядке определения: сначала родительские, затем дочерние.
Структура XML-декодера
Каждый декодер определяется элементом <decoder>:
<decoder name="sshd-failed">
<parent>sshd</parent>
<prematch>^Failed password</prematch>
<regex>^Failed password for (\S+) from (\S+) port (\d+)</regex>
<order>srcuser, srcip, srcport</order>
</decoder>Элементы декодера
Основные элементы
name (атрибут) - уникальное имя декодера:
<decoder name="my-app">parent - связь с родительским декодером. Дочерний декодер применяется только если родительский сработал:
<parent>sshd</parent>Родительский декодер может иметь множество дочерних, но дочерний декодер не может быть родителем для других.
program_name - сопоставление с именем программы из заголовка syslog. Поддерживает типы regex, sregex, pcre2:
<program_name>sshd</program_name>
<program_name type="pcre2">nginx|apache2?</program_name>prematch - предварительное условие, которое должно совпасть перед применением основного regex. Работает с телом сообщения после извлечения syslog-заголовков:
<prematch>^Failed password</prematch>
<prematch type="pcre2">^(?:Failed|Invalid) password</prematch>regex - регулярное выражение для извлечения полей. Поля, заключенные в круглые скобки, извлекаются как значения:
<regex>^Failed password for (\S+) from (\S+) port (\d+)</regex>order - определяет имена полей, соответствующие группам захвата в regex:
<order>srcuser, srcip, srcport</order>Доступные стандартные имена полей:
| Поле | Описание |
|---|---|
srcip | IP-адрес источника |
dstip | IP-адрес назначения |
srcport | Порт источника |
dstport | Порт назначения |
srcuser | Пользователь источника |
dstuser | Пользователь назначения |
user | Пользователь (общий) |
protocol | Протокол |
action | Действие |
id | Идентификатор события |
url | URL |
data | Произвольные данные |
extra_data | Дополнительные данные |
status | Статус |
system_name | Имя системы |
Помимо стандартных полей допускается использование произвольных имен - они станут динамическими полями.
Дополнительные элементы
type - тип лога. Определяет категорию для использования в правилах:
<type>syslog</type>Доступные типы: syslog (по умолчанию), firewall, ids, web-log, squid, windows, host-information, ossec.
accumulate - отслеживание многострочных событий по полю id:
<accumulate />fts (First Time Seen) - генерирует событие при первом появлении указанной комбинации полей:
<fts>srcuser, srcip</fts>use_own_name - дочерний декодер использует собственное имя вместо наследования имени родителя:
<use_own_name>true</use_own_name>plugin_decoder - вызов специализированного встроенного декодера:
<plugin_decoder>JSON_Decoder</plugin_decoder>Доступные плагины: JSON_Decoder, PF_Decoder, SymantecWS_Decoder, SonicWall_Decoder, OSSECAlert_Decoder.
Иерархия декодеров (parent-child)
Декодеры организованы в иерархическую структуру для повышения эффективности и точности парсинга.
Принцип работы
- Wazuh ищет подходящий родительский декодер по
program_nameилиprematch - После срабатывания родительского декодера проверяются все его дочерние декодеры
- Дочерний декодер, чей
prematchилиregexсовпал, извлекает поля
Пример иерархии
Родительский декодер (определяет источник - sshd):
<decoder name="sshd">
<program_name>^sshd</program_name>
</decoder>Дочерний декодер (извлекает поля при неудачном входе):
<decoder name="sshd-failed">
<parent>sshd</parent>
<prematch>^Failed password</prematch>
<regex>^Failed password for (\S+) from (\S+) port (\d+)</regex>
<order>srcuser, srcip, srcport</order>
</decoder>Дочерний декодер (извлекает поля при успешном входе):
<decoder name="sshd-success">
<parent>sshd</parent>
<prematch>^Accepted</prematch>
<regex>^Accepted \S+ for (\S+) from (\S+) port (\d+)</regex>
<order>srcuser, srcip, srcport</order>
</decoder>Дочерний декодер (разрыв соединения):
<decoder name="sshd-disconnect">
<parent>sshd</parent>
<prematch>^Disconnected from</prematch>
<regex>^Disconnected from user (\S+) (\S+) port (\d+)</regex>
<order>srcuser, srcip, srcport</order>
</decoder>JSON-декодер
Wazuh включает встроенный плагин JSON_Decoder для автоматического парсинга JSON-логов. Это особенно полезно для приложений, логирующих в формате JSON, и облачных сервисов.
Базовое использование
<decoder name="json-app">
<prematch>^{"</prematch>
<plugin_decoder>JSON_Decoder</plugin_decoder>
</decoder>JSON-декодер автоматически извлекает все поля из JSON-объекта. Вложенные поля представляются через точечную нотацию: data.source.ip.
Пример JSON-лога
Входной лог:
{"timestamp":"2025-03-05T10:15:01Z","event":"login_failed","user":"admin","src_ip":"192.168.1.100","port":22}Результат декодирования:
timestamp: '2025-03-05T10:15:01Z'
event: 'login_failed'
user: 'admin'
src_ip: '192.168.1.100'
port: '22'Настройки JSON-декодера
json_null_field - поведение при значении null:
<json_null_field>discard</json_null_field> <!-- игнорировать null-поля -->
<json_null_field>string</json_null_field> <!-- сохранить как строку "null" -->json_array_structure - обработка массивов:
<json_array_structure>csv</json_array_structure> <!-- массив как CSV -->Стандартные декодеры
Wazuh включает более 1500 декодеров в стандартной поставке, расположенных в /var/ossec/ruleset/decoders/. Основные файлы:
| Файл | Описание |
|---|---|
0005-sshd_decoders.xml | OpenSSH (sshd) |
0010-syslog_decoders.xml | Общие syslog-сообщения |
0020-apache_decoders.xml | Apache HTTP Server |
0025-nginx_decoders.xml | Nginx |
0040-pam_decoders.xml | PAM-аутентификация |
0050-postfix_decoders.xml | Postfix MTA |
0100-windows_decoders.xml | Windows Event Log |
0150-cisco_decoders.xml | Cisco устройства |
0200-amazon_decoders.xml | AWS CloudTrail |
0350-docker_decoders.xml | Docker |
Стандартные декодеры обновляются при обновлении Wazuh и не должны редактироваться напрямую.
Создание пользовательских декодеров
Пользовательские декодеры размещаются в /var/ossec/etc/decoders/local_decoder.xml. Этот файл не затрагивается при обновлении.
Пример: декодер для пользовательского приложения
Допустим, приложение генерирует логи в формате:
Mar 5 10:15:01 app-server myapp[9876]: AUTH_FAIL user=admin ip=192.168.1.100 reason=invalid_passwordШаг 1: Создайте родительский декодер
<decoder name="myapp">
<program_name>^myapp</program_name>
</decoder>Шаг 2: Создайте дочерний декодер для извлечения полей
<decoder name="myapp-auth-fail">
<parent>myapp</parent>
<prematch>^AUTH_FAIL</prematch>
<regex>^AUTH_FAIL user=(\S+) ip=(\S+) reason=(\S+)</regex>
<order>srcuser, srcip, data</order>
</decoder>Шаг 3: Протестируйте декодер
/var/ossec/bin/wazuh-logtestВведите лог-строку и убедитесь, что поля извлекаются корректно.
Шаг 4: Создайте правило для события
В /var/ossec/etc/rules/local_rules.xml:
<group name="myapp,">
<rule id="100200" level="5">
<decoded_as>myapp</decoded_as>
<match>AUTH_FAIL</match>
<description>MyApp: authentication failure.</description>
<group>authentication_failed,</group>
</rule>
</group>Шаг 5: Перезагрузите менеджер
/var/ossec/bin/wazuh-control reloadПример: декодер для веб-приложения
Лог веб-приложения:
2025-03-05 10:15:01 [ERROR] SQL injection attempt detected: query="SELECT * FROM users WHERE id=1 OR 1=1" client=192.168.1.100 path=/api/usersДекодер:
<decoder name="webapp">
<prematch>^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} \[</prematch>
</decoder>
<decoder name="webapp-sqli">
<parent>webapp</parent>
<prematch>SQL injection attempt</prematch>
<regex>client=(\S+) path=(\S+)</regex>
<order>srcip, url</order>
</decoder>Пример: декодер для JSON-логов приложения
Если приложение логирует в JSON:
{"level":"error","message":"unauthorized access","user":"guest","ip":"10.0.0.5","path":"/admin","timestamp":"2025-03-05T10:15:01Z"}Декодер:
<decoder name="json-webapp">
<prematch>^{"level":</prematch>
<plugin_decoder>JSON_Decoder</plugin_decoder>
</decoder>Правило может обращаться к полям JSON через элемент <field>:
<rule id="100210" level="8">
<decoded_as>json-webapp</decoded_as>
<field name="level">error</field>
<field name="message">unauthorized access</field>
<description>Web application: unauthorized access attempt.</description>
</rule>Тестирование декодеров с wazuh-logtest
Интерактивный режим
/var/ossec/bin/wazuh-logtestВведите лог и проверьте фазы pre-decoding и decoding:
Type one log per line
Mar 5 10:15:01 app-server myapp[9876]: AUTH_FAIL user=admin ip=192.168.1.100 reason=invalid_password
**Phase 1: Completed pre-decoding.
full event: '...'
timestamp: 'Mar 5 10:15:01'
hostname: 'app-server'
program_name: 'myapp'
**Phase 2: Completed decoding.
name: 'myapp-auth-fail'
parent: 'myapp'
srcuser: 'admin'
srcip: '192.168.1.100'
data: 'invalid_password'Отладка декодеров
Если декодер не срабатывает:
- Проверьте, что
program_nameв родительском декодере совпадает с именем программы в логе - Убедитесь, что
prematchсовпадает с началом тела сообщения (после pre-decoding) - Проверьте regex на корректность групп захвата
- Используйте флаг
-vдля подробного вывода:
/var/ossec/bin/wazuh-logtest -vТипичные ошибки
| Ошибка | Причина | Решение |
|---|---|---|
| Декодер не срабатывает | program_name не совпадает | Проверьте формат syslog-заголовка |
| Поля не извлекаются | Неверный regex или порядок в order | Проверьте количество групп захвата |
| Дочерний декодер не применяется | parent не совпадает с именем родительского декодера | Сверьте имена |
| JSON-поля не извлекаются | Отсутствует plugin_decoder | Добавьте <plugin_decoder>JSON_Decoder</plugin_decoder> |
Устранение проблем с декодерами
Декодер не определяет program_name
Некоторые источники логов не используют стандартный формат syslog. В этом случае program_name не извлекается на этапе pre-decoding. Используйте prematch вместо program_name для идентификации источника.
Конфликт декодеров
Если два декодера совпадают для одного лога, приоритет получает первый загруженный. Пользовательские декодеры загружаются после стандартных. Для решения конфликта используйте более специфичный prematch.
Производительность декодеров
Избегайте сложных регулярных выражений с вложенными квантификаторами ((.*)*, (a+)+), которые могут вызвать катастрофический бэктрекинг. Используйте pcre2 с атомарными группами для критичных по производительности декодеров.
Связанные разделы
- Правила обнаружения - правила, использующие данные декодеров
- Анализ журналов - сбор логов для декодирования
- Устранение неполадок - диагностика проблем с декодерами