DEV Community

Nguyen Dong
Nguyen Dong

Posted on

Wazuh custom rule never fires, and analysisd -t still exits 0: the file name decides

You write a child rule for a stock Wazuh rule, drop it into /var/ossec/etc/rules/, and run the config check. wazuh-analysisd -t exits 0. You restart the manager. The rule never fires, and wazuh-logtest shows the event landing on the parent instead.

One common cause has nothing to do with the rule itself. It is the name of the file you put it in.

What we measured

On a throwaway wazuh-manager:4.14.7 container we used one test rule, a child of the stock sshd rule 5715:

<group name="test,">
  <rule id="100080" level="9">
    <if_sid>5715</if_sid>
    <match>Accepted password</match>
    <description>test child of 5715</description>
  </rule>
</group>
Enter fullscreen mode Exit fullscreen mode

5715 lives in /var/ossec/ruleset/rules/0095-sshd_rules.xml. We put the same rule in five differently named files in /var/ossec/etc/rules/, ran wazuh-analysisd -t, restarted, and sent one line through wazuh-logtest:

Sep 26 10:00:00 host1 sshd[1234]: Accepted password for root from 203.0.113.5 port 22 ssh2
Enter fullscreen mode Exit fullscreen mode
file -t exit 7617 / 7619 warnings logtest lands on
0094-test.xml 0 yes 5715 (our rule ignored)
0096-test.xml 0 no 100080 (fires)
local_rules.xml 0 no 100080 (fires)
0095-aaa.xml 0 yes 5715 (our rule ignored)
0095-zzz.xml 0 no 100080 (fires)

The two warnings, word for word:

WARNING: (7617): Signature ID '5715' was not found and will be ignored in the 'if_sid' option of rule '100080'.
WARNING: (7619): Empty 'if_sid' value. Rule '100080' will be ignored.
Enter fullscreen mode Exit fullscreen mode

What it means

Files in etc/rules are not loaded after the stock ruleset. They are merged with ruleset/rules and loaded in order of the full file name. The last two rows show it: 0095-aaa.xml sorts before 0095-sshd_rules.xml, so when our rule is read, 5715 does not exist yet and the rule is dropped. 0095-zzz.xml sorts after it, and the same rule fires.

local_rules.xml is safe for this reason: letters sort after digits, and all 168 stock rule files in 4.14.7 start with a digit (0010 to 0999), so it loads after every one of them.

The trap is the config check. wazuh-analysisd -t exits 0 in all five cases. It prints the two warnings, but a warning is not a failure, and nothing in a deploy script that checks the exit code will stop. The manager then starts cleanly with one rule fewer than you think.

Check yours in a minute

After a restart, the warnings are also in the manager log:

grep -E '\((7617|7619)\)' /var/ossec/logs/ossec.log
Enter fullscreen mode Exit fullscreen mode

Every rule id you see in a 7619 line is a rule that is not running. The 7617 line on the same second tells you which parent it was waiting for.

Before a restart, run the check yourself and read its output instead of trusting the exit code:

/var/ossec/bin/wazuh-analysisd -t 2>&1 | grep -E '\((7617|7619)\)'
Enter fullscreen mode Exit fullscreen mode

For a single rule, wazuh-logtest with a real sample line is the final word: if the output shows the parent's id and not yours, your rule did not load or did not match.

The fix

Move the child rule into a file whose name sorts after the file that holds its parent:

  • put it in local_rules.xml, or
  • give your file a prefix above the parent's file (0096-... or higher for children of sshd rules), or a name that starts with a letter.

To find the parent's file:

grep -l 'id="5715"' /var/ossec/ruleset/rules/*.xml /var/ossec/etc/rules/*.xml
Enter fullscreen mode Exit fullscreen mode

Then run the check again and confirm the 7619 line is gone, and that logtest lands on your rule.

What we did not measure

One Wazuh version (4.14.7), a single manager, one parent rule, and only if_sid. We did not test if_matched_sid, if_group, decoders, or a cluster. If you run a cluster, check the warnings on every node.

Credit to Francisco Sousa, who found the file name half of this in his own container before we did.


If one of your rules loads and never fires and you would rather not dig into it yourself, send us the rule, your Wazuh version and a sample event: we find why, then write and test the fix on that version. USD 490 per rule case, paid only after it runs clean on your side. vct.atkvn.com/#fix-pack

Dong Nguyen, ATK New Technology

Top comments (0)