Files
KNELSiem/docs/wazuh-tuning.md
T
mrcharles bbbfa9fb90
ci / audit (push) Successful in 23s
SOC: Wazuh alert tuning + #823-pattern detections
16 level/frequency overrides (overwrite semantics documented), new
100500/100501/100510 WordPress-compromise rules, tuning doc with
before/after numbers. Zero L7+ email after deploy.

https://projects.knownelement.com/issues/825#note-5008
2026-09-06 14:09:49 -05:00

5.5 KiB

Wazuh Alert Tuning — KNEL SOC

Date: 2026-09-06 · Ticket: Redmine #825 · Change: GLPI CR 23 Applied on: tsys-siem (Wazuh manager 4.14.1), /var/ossec/etc/rules/local_rules.xml Discourse: https://community.turnsys.com/t/soc-security-operations-lane-wazuh-tuning-823-follow-through-soc-team/340 Rollback: cp /var/ossec/etc/rules/local_rules.xml.bak-20260906-soc /var/ossec/etc/rules/local_rules.xml && systemctl restart wazuh-manager

Why

The manager emails every alert of level >= 7 to coo@turnsys.com (max 12/hour). September 2026 through 09-06: 664k alerts this month (518k from tsys-cloudron-new web 400s alone, ingested via journald = every Cloudron app's container stdout), and a permanent L7+ email storm: scanner-storm composites (31151 @ L10), CVE backlog refires (23505 High @ L10, 23506 Critical @ L13, 23504 Medium @ L7 — the whole backlog re-fires every scan), SCA failures (19007 @ L7), ssh/PAM fail amplifiers (2502 @ L10, 5551 @ L10), dpkg events (2902/2904 @ L7), generic syscheck churn (550 @ L7).

Design rule going forward: email (L7+) is reserved for genuine incidents. Everything else lives in dashboards and the SOC weekly loop (triage notes on #825, OpenVAS/GLPI tickets for vulnerabilities, hardening backlog for SCA).

Mechanism note (learned the hard way)

Wazuh 4.14 rule overwrite="yes" in local_rules.xml REPLACES the original rule definition — it is not a merge. An override with only a level would match every event (observed: rule 2502 flagging kernel i2c lines at 1000/min). Therefore every override below carries the FULL original rule body with only level/frequency/timeframe changed. Also: nested <group> elements are invalid in rule files — single root group only. Level-0 rules do not index but still count as "fired" for frequency composites (verified: 31151 keeps firing over the L0 31101 parent).

Changes

Rule Meaning Was Now Rationale
31101 web 400 per-line L5 L0 492k/mo bot noise; raw logs stay in journald
31120 / 31122 web 500 per-line L5 L3 real app errors, dashboard-only
31151 web 400 storm composite L10 freq 14/90s L6 freq 40/240s sustained scans only, no email
5501 / 5502 PAM session open/close L3 L0 session accounting
23502 / 23507 CVE solved / cleared L3 L0 lifecycle info
23503 CVE low L5 L3
23504 CVE medium/untriaged L7 L4 was emailing; backlog refire
23505 CVE high L10 L6 vulns = weekly OpenVAS/GLPI loop, not email
23506 CVE critical L13 L6 same — backlog refire storm made email useless
19007 SCA check failed L7 L5 hardening backlog
2902 / 2904 dpkg installed / half-configured L7 L3 ops inventory, not incidents
550 syscheck checksum changed (generic) L7 L5 churn; high-signal subcases below
2502 "missed password >once" L10 L5 dup of 5503/5760
5551 PAM multiple failed logins L10 L6 2.3k/mo on routine churn
31510 CMS brute force L8 freq 8/30s L6 freq 20/120s bot storms
40704 systemd unit failed L5 L3 145k/mo churn; root-cause dig tracked on #825

Kept at L7+ deliberately: 5712 (sshd brute, L10), 5763 (sshd max-auth), 31152/31153 (401/403 storms, L10), 31162 (suspicious URI, L10), plus all auth failures at L5 (5710/5760/5503) — cheap and real now that SSH is tailnet-only (#769).

New detections (the #823 pattern)

The July 2026 ezeda.org compromise (Redmine #823) persisted via wp-config.php backdoor + 41 webshells in uploads. New rules + Cloudron agent syscheck watchers catch a repeat:

Rule Level Fires when
100500 L12 (email) any wp-config.php under Cloudron app data changes (syscheck)
100501 L10 (email) a .php file appears/changes inside any WP uploads/ dir (syscheck)
100510 L8 web request reaches .php inside an uploads/ path (access-log)

Agent 001 (tsys-cloudron-new) ossec.conf additions: syscheck /home/yellowtent/appsdata/*/data/wp-config.php + */data/wp-content/uploads (frequency 12h); quarantine dirs excluded (#823 evidence holds known malware).

Verification (2026-09-06, clean window after deploy)

Metric Before (per hour) After (per hour)
Total alerts ~19,000+ ~2,500
L5 web-400 flood ~25,000 0
2502 misfire flood ~60,000 at peak 0 (7 per 10 min = genuine)
L7+ (email to coo@) constant (12/h cap hit) 0
L10 scanner storms (31151) continuous L6, sustained scans only

Remaining L3 volume = systemd churn (40704) + apparmor denials (52002) + web 500s + sshd successes: visible for triage, below every notification path.

Week-loop plan (adjustment cadence)

  1. Daily: triage new L6+ in the Wazuh dashboard; note dispositions on #825.
  2. Watch 5710/5760/5503 — should stay near-zero with tailnet-only SSH; a spike = someone knocking from inside the tailnet.
  3. 100500/100501/100510 must stay at zero; any fire = possible #823 recurrence → incident.
  4. Investigate 40704 root cause on tsys-siem (which unit churns) as an ops item.
  5. Re-check email volume at coo@ weekly; tune further only on evidence.
  6. Vulnerability backlog: OpenVAS scans (GLPI-fed targets) → tickets per the triage standard; Wazuh vuln alerts feed the same weekly review.