Custom Decoder & Rules

In Wazuh, custom decoders and rules are used to extend the functionality of the system to detect and analyze specific log formats or events that may not be covered by the default decoders and rules. Here we integrate Fail2ban logs into our wazuh manager.

What is decoder ?

In Wazuh, a decoder is a component that processes and interprets incoming log data. Its primary function is to extract useful information from raw logs generated by various devices, applications, and systems, and transform them into a structured format that Wazuh can understand and analyze.

We will take this Fail2ban log samples into our consideration :

  1. IP Whitelist & Blacklist

2025-03-06T10:52:53.005505+05:30 workstation fail2ban.actions[17409]: NOTICE [sshd] Ban 3.3.3.117
2025-03-06T10:53:48.522507+05:30 workstation fail2ban.actions[17409]: NOTICE [sshd] Unban 3.3.3.117
  1. Service Status

2025-03-06T10:50:52.298830+05:30 workstation fail2ban-server[17298]: Server ready
2025-03-06T10:51:11.811298+05:30 workstation fail2ban.server[17298]: INFO Exiting Fail2ban
  1. Time Imcrement upon rule violation

2025-03-06T11:04:48.072538+05:30 workstation fail2ban.observer[17990]: NOTICE [sshd] Increase Ban 3.3.3.117 (2 # 2m -> 2025-03-06 11:06:47)

By default wazuh server is not able to understand the logs so we will need to make the custom decoder to parse this log and visulaize it with the wazuh dashboard.

Before starting learning how to make custom decoder we will need to lean the supported regex format for wazuh to understand logs.

Wazuh - Regex

Now we will start building decoders , The basic decoder block given by wazuh is :

<decoder name="example">
  <program_name>^example</program_name>
</decoder>
<decoder name="example">
  <parent>example</parent>
  <regex>User '(\w+)' logged from '(\d+.\d+.\d+.\d+)'</regex>
  <order>user, srcip</order>
</decoder>

The decoder which is required to integrate logs of fail2ban is as follows :

sudo nano /var/ossec/etc/decoders/local_decoders.xml
<!-- FAIL2BAN - Observer -->
<decoder name="fail2ban.observer">
  <program_name>^fail2ban.observer</program_name>
  <prematch>NOTICE \p\w+\p Increase Ban</prematch>
</decoder>
<decoder name="fail2ban_observer_child">
  <parent>fail2ban.observer</parent>
  <regex>NOTICE (\.+) Increase Ban (\.+) \p\d+ \p (\d+\w+) \.+</regex>
  <order>service,srcip,bantime</order>
</decoder>
<!-- FAIL2BAN - SERVICE STATUS EXITED-->
<decoder name="fail2ban.server">
  <program_name>^fail2ban.server</program_name>
  <prematch>INFO Exiting Fail2ban</prematch>
</decoder>
<decoder name="fail2ban_server_exited">
  <parent>fail2ban.server</parent>
  <regex>(\.+)</regex>
  <order>exited_status</order>
</decoder>
<!-- FAIL2BAN - SERVICE STATUS STARTED-->
<decoder name="fail2ban-server">
  <program_name>^fail2ban-server</program_name>
  <prematch>^Server ready</prematch>
</decoder>
<decoder name="fail2ban_server_started">
  <parent>fail2ban-server</parent>
  <regex>(\.+)</regex>
  <order>started_status</order>
</decoder>
<!-- FAIL2BAN - ACTIONS -->
<decoder name="fail2ban.actions">
  <program_name>^fail2ban.actions</program_name>
  <prematch>NOTICE \p\w+\p \w+ \d+</prematch>
</decoder>
<decoder name="fail2ban_actions_child">
  <parent>fail2ban.actions</parent>
  <regex>NOTICE (\.+) (\.+) (\d+.\d+.\d+.\d+)</regex>
  <order>service,status,srcip</order>
</decoder>

We can test the decoders working properly using the logtester available in wazuh :

/var/ossec/bin/wazuh-logtest

Here as we can see our decoder is working great, You can test all the log samples which is given above to check the decoders are working fine. Now we will start creating the rules

sudo nano /var/ossec/etc/rules/local_rules.xml
<!-- FAIL2BAN -->
<group name="failban_logs,">
  <rule id="100002" level="8">
    <decoded_as>fail2ban.actions</decoded_as>
    <description>Fail2ban Updates [ Host : $(srcip) , status: $(status) , Service: $(service) ]</description>
  </rule>
  <rule id="100003" level="10">
    <decoded_as>fail2ban.observer</decoded_as>
    <description>Fail2ban Updates [BANTIME] [ HOST : $(srcip) , Service: $(service) , Bantime Increment (mins) : $(bantime) ]</description>
  </rule>
  <rule id="100004" level="5">
    <decoded_as>fail2ban.server</decoded_as>
    <description>Fail2ban Updates [ Fail2Ban Service Stoppped ]</description>
  </rule>
  <rule id="100005" level="5">
    <decoded_as>fail2ban-server</decoded_as>
    <description>Fail2ban Updates [ Fail2Ban Service Started / Restarted ]</description>
  </rule>
</group>

Now we can test the logs once again in the log tester /var/ossec/bin/wazuh-logtest

As from the above image we can see our decoders & rules are woking good in the log tester so now we will integrate it with wazuh dashboard

sudo systemctl restart wazuh-manager

Upon restart we will recreate the pattern to generate logs and we can see the corroponding logs in our wazuh dashboard :

Here we have completed creating our first set of rules & decoders and to learn more on decoders & rules we can follow this page :

Wazuh - Regex

Last updated