Host-Based Detection Part 6: File Integrity Monitoring and Rootcheck
An enrolled, alerting agent, Parts 5 and, in more depth, Part 7 of this series, tells you about things that happen. It says nothing about whether the system is still in the state it’s supposed to be in right now, a permission quietly loosened, a binary quietly swapped, a config file drifting out of the shape an earlier hardening pass put it in. That’s a different job, and Wazuh has three distinct modules for it, not one: FIM, rootcheck, and SCA.
File integrity monitoring (syscheck)
Wazuh’s FIM module, internally still called syscheck, watches specific files and directories for changes to content, permissions, or ownership, either in near real time, via the OS’s own file-change notification mechanism on Linux, or on a scheduled scan, and reports exactly what changed and how. It’s configured with a <syscheck> block naming the directories to watch, and it’s on by default. From Dropbox to Daily Driver Part 7 noted its own agent log showing FIM start scanning unprompted, right alongside the SCA scan that post was actually configuring, with no separate install step and no explicit enable.
The real design tradeoff with FIM isn’t whether to turn it on, it already is, it’s what to point it at. Watching too little misses the point entirely. Watching too much, an active web root, /var/log itself, anything that legitimately changes constantly, buries every genuinely interesting change under noise from files that were never going to matter, which is a real cost. Alert fatigue isn’t just a NIDS problem, and a FIM policy that watches indiscriminately produces exactly the same effect this site’s own Alert Fatigue Is a Routing Problem post named for a completely different pipeline. Scoping FIM to genuinely sensitive, genuinely static locations, /etc, binaries, SSH configuration, is what keeps its output worth reading.
Rootcheck
Older and narrower than FIM: a set of policy-style checks originally aimed squarely at rootkit detection, known trojan signatures, processes or open ports that don’t match what a normal system call would report, a classic rootkit-hiding technique, and a handful of generic system-hardening checks that predate Wazuh’s newer SCA module and overlap with it in spirit, if not in scope or presentation. It runs on the same agent, needs no separate install, and its findings show up in the same alert stream as everything else Part 7 of this series covers.
SCA, and how it’s different from both
Security Configuration Assessment is the module From Dropbox to Daily Driver Part 7 actually put through its paces: a scheduled scan against a policy file of expected configuration values, SSH settings, PAM rules, filesystem permissions, kernel parameters, loosely modelled on CIS Benchmarks, with a default policy shipped per major distribution, cis_debian13.yml was already present and correctly matched on that Pi, no manual download needed. Where FIM answers “did this file change” and rootcheck answers “does anything look like it’s hiding,” SCA answers a narrower, more specific question: does this exact setting match a known-good baseline. That distinction mattered in practice on the real run. SCA correctly flagged a genuine PermitRootLogin drift caused by a leftover cloud-init config file silently overriding an earlier hardening pass, exactly the kind of fragile, load-order-dependent misconfiguration FIM alone, which would only notice the file changed, not that the change mattered, or rootcheck alone, looking for hidden rootkits rather than soft misconfiguration, wouldn’t have caught on their own. It also produced two confirmed false negatives on that same run, a ufw state check and a root account lock check both failing to detect settings that were genuinely correct, a reminder that a shipped policy file is a starting point to verify against the real system, not an infallible ground truth, the same caution Part 7 of this series applies to the ruleset itself.
Three modules, one habit
FIM, rootcheck, and SCA all answer some version of “is the system still the way I think it is,” and all three run by default on an enrolled agent with no separate install. The habit worth carrying out of this part: none of the three should be trusted blind. Every finding in the one real run this series draws on got checked against the live system before being called a real gap, a false negative, or a deliberate exception, and that verification step is what turned 105 initial SCA failures into a genuinely useful list rather than noise.