Wazuh
Free · OSSHost & Endpoint
Endpoint truth for every laptop and server — the keystone of the stack.
Wazuh homepage ↗The keystone of your stack. Wazuh agents sit on every laptop and server, watching files, processes, and system events. It's how you know if something on a machine just got compromised — and how you know what changed.
Production-shippable. Integration test coverage + battle-tested in design-partner installs.
What it watches
- File-integrity changes (FIM) — a config, binary, or sensitive file modified
- Suspicious process execution — a shell spawned from Office, a new SUID binary
- Authentication events — failed + successful logins, sudo, new admin
- Rootkit + anomaly detections from the built-in rulesets
- Software-inventory drift across the fleet
MITRE ATT&CK coverage
Tactics this connector gives CyberCLI visibility into.
Every alert this connector surfaces
5 event types
Every matrix-covered event_type on the passthrough lane — pinned by the engine's coverage matrix.
The right column shows the operator-friendly phrase the dashboard renders. High-severity
AI-lane signals are summarized in What it watches above (Warden + Herald
handle those); the rest take the substrate's passthrough lane (no AI tokens burned).
| event_type | dashboard renders |
|---|---|
| 3002.0001 | Authentication failed on wazuh |
| 3002.0002 | Authentication success on wazuh |
| 1007.0001 | File integrity event on wazuh |
| 4001.0001 | Firewall activity on wazuh |
| 4002.0001 | IDS event on wazuh |
What it helps you catch
What you'd see in CyberCLI
illustrativePowerShell spawned by WINWORD.EXE on CEO-LAPTOP
- host
- CEO-LAPTOP
- parent
- WINWORD.EXE
- process
- powershell -enc JABz…
- user
- j.doe
Routed to Warden (triage) → Knight (detection) → Paladin (containment) → Scribe (record)
Suggested Isolate host · kill process (needs approval)
⛓ every step hash-chained · replayable
What CyberCLI reads from Wazuh
audit our mathWazuh ships a normalized alert per security event — login failures, integrity changes, firewall blocks, vulnerability findings. The 17 fields we read tell us what fired (rule_id, rule_level, description), where (agent, location, srcip), who (srcuser, dstuser), what MITRE technique it maps to (mitre), and the raw evidence. Every field is operator-readable in the CYCON view — nothing is hidden behind an embedding.
Event categories we parse
- Authentication failure authentication_failure.json
SSH/RDP/console login failures + brute-force patterns. Carries srcip, srcuser, agent identity, and the raw auth-log line.
- File integrity change file_integrity_change.json
FIM hits on watched paths (system binaries, config dirs). Carries the file path, before/after hashes, and which integrity policy fired.
- Firewall block firewall_block.json
Host firewall drops surfaced through Wazuh's decoder pack. Includes srcip, dstip, dport, and rule context.
Sample event · Authentication failure ↓
{
"timestamp": "2026-05-11T18:21:14.000+0000",
"rule": {
"id": "5710",
"level": 10,
"description": "Attempt to login using a non-existent user",
"groups": [
"syslog",
"authentication_failed",
"invalid_login"
],
"mitre": {
"id": [
"T1110"
],
"tactic": [
"Credential Access"
]
}
},
"agent": {
"id": "001",
"name": "hal6000"
},
"manager": {
"name": "wazuh-manager"
},
"id": "1778523290.42",
"decoder": {
"name": "sshd"
},
"data": {
"srcip": "203.0.113.42",
"srcuser": "chris@bladeglobal.com"
},
"location": "/var/log/auth.log",
"full_log": "May 11 18:21:14 hal6000 sshd[12345]: Invalid user chris@bladeglobal.com from 203.0.113.42 port 51842"
} Full field index · 17 fields ↓
.agent_id.agent_name.cybercli_low_signal.cybercli_parse_error.cybercli_parse_status.cybercli_wire_format.dst_ip.dst_user.event_id.event_timestamp.mitre.rule_description.rule_id.rule_level.src_ip.src_user.wazuh MITRE techniques typically mapped
Trust Ladder ceiling · L0 → L4
- ·L0–L2: digest the alert · notify Herald · summarize for the operator
- ·L3 (Knight verification): IOC lookup, sandbox detonation, EDR query — read-only
- ·L4 (Paladin containment, Pro+): Wazuh-agent-side isolate via wazuh.isolate_agent
- ·L5+: host quarantine, account disable across multiple systems
- ·Any action that touches a system Wazuh doesn't own (firewall, identity)
Full ladder semantics · /trust →
Field count + sample event auto-derived from src/cybercli/connectors/wazuh/vector.vrl at build time. Numbers update the moment the engine's parser changes — no drift.
Close more of the kill chain
Wazuh covers 10 of 14 ATT&CK tactics. Pair it with these to widen coverage:
How to connect
- 1 Install the Wazuh manager + deploy agents to your hosts (one-liner below).
- 2 In CyberCLI, point the connector at your Wazuh indexer/API endpoint + credentials (stored in the vault, never in config).
- 3 Run `cybercli onboard wazuh` — it validates the connection and starts the event stream.
- 4 Confirm events are flowing via the substrate receipt in the dashboard's Connectors panel.
curl -sO https://packages.wazuh.com/4.x/wazuh-install.sh && sudo bash wazuh-install.sh -a
Real Onboarding Manual
v1.0 — 2026-06-18Within 5 minutes of `cybercli onboard wazuh` completing, the dashboard's Connectors panel shows wazuh as healthy with non-zero events-today, and the next time you log into a Wazuh-monitored host you see the auth event surface as a CyberCLI signal within ~10 seconds. File-integrity changes flow within the agent's syscheck cadence (default 12h — speed up for testing).
Pre-flight
- 1Wazuh Manager has at least one enrolled agent reporting
CyberCLI polls the manager API for alerts — if no agents are enrolled, you'll connect cleanly but see zero events forever, which reads as a broken connector. Enrol at least the local host as a smoke-test agent before onboarding.
/var/ossec/bin/agent_control -l # lists enrolled agents (run on the manager)
- 2Manager API is reachable from the CyberCLI host on 55000/tcp
The Manager API (port 55000) is what CyberCLI polls. NOT the Indexer (9200) and NOT the Dashboard (443) — those are separate services. All-in-one deploys bind all three; if you've split the manager onto its own host, make sure 55000 is the one CyberCLI can reach.
curl -k -u <user>:<pass> https://<manager>:55000/ # expect JSON {error: 0} - 3API user with read-only role exists (don't use admin)
CyberCLI only needs read access for the polling lane. Wazuh's default 'wazuh' user has admin rights — giving CyberCLI those keys is a needless blast-radius if the credential ever leaks. Create a dedicated read-only user via the Wazuh dashboard before onboarding.
Configure
- 1Create a read-only API user in WazuhWazuh Dashboard → Server Management → Security → Users → Create user
Make a dedicated user for CyberCLI rather than reusing the master 'wazuh' account. Assign the built-in `readonly` role — sufficient for the alerts + agent-list + group-list endpoints CyberCLI polls. Save the username + password; you'll paste them in the next step.
- Username
-
cybercli-readonlyOr whatever you prefer; pick something obvious in audit logs. - Password
-
<strong unique value>Will be stored in CyberCLI's vault (chmod 600 + master-key encrypted). - Roles
-
readonlyDO NOT assign the administrator role; readonly is enough.
ImportantDon't reuse the master 'wazuh' user. If that credential leaks, an attacker can add/remove agents and modify rule configs. Read-only contains the blast.
- 2Run the CyberCLI onboarding commandOn your CyberCLI host
The onboarding flow prompts for the manager URL + credentials, validates the connection, stores the credentials in the vault, and starts the poller. The first poll runs immediately so you should see events within the manager's alert cadence.
- command
-
cybercli onboard wazuh - Manager URL
-
https://<manager-host>:5500055000 = manager API. NOT 9200 (indexer) or 443/9443 (dashboard). - Username
-
cybercli-readonlyThe dedicated user from step 1. - Password
-
<paste at prompt>Never typed in clear; vault-stored on save. - Verify TLS
-
yes (or no for self-signed lab deploys)Default Wazuh installs self-signed — answer 'no' only if you trust the network path. Production: install a real cert + answer yes.
- 3Confirm the connector shows healthy in the dashboardCyberCLI Dashboard → Connectors
After ~30 seconds the Wazuh row should show a green health indicator + last-poll timestamp + non-zero events-today (assuming agents are reporting). If health is yellow, the poller is up but no alerts are arriving — check the agent fleet on the manager side.
- 4(Optional) Speed up FIM cadence on test agentsManager → /var/ossec/etc/ossec.conf → <syscheck>
Wazuh agents run file-integrity checks every 12 hours by default. For smoke-testing the connector you can drop this to 1 hour temporarily — but DO NOT leave it short in production (cpu cost on the agent fleet).
- <frequency>
-
3600Seconds. Default is 43200 (12h). Revert after testing. - <scan_on_start>
-
yesForces a scan on agent restart — useful to see FIM events flow during onboarding without waiting for the natural cadence.
Why thisNewcomers onboard the connector, see the health indicator go green, then stare at the dashboard for an hour waiting for an event. Speeding up FIM on a test agent + tripping a sentinel file (touch ~/.wazuh-test-file) produces a visible signal in under 10 minutes.
Verify
- 1
Confirm the manager API is reachable + creds work
curl -k -u cybercli-readonly:<pwd> https://<manager>:55000/security/user/authenticate
You should see{"data": {"token": "ey..."}, "error": 0}If this fails401 = wrong creds. 404 = wrong path or wrong port (you might be hitting the dashboard instead of the manager). Connection refused = manager not running or firewall blocking. Verify with `systemctl status wazuh-manager` on the manager host.
- 2
Trigger an event to confirm signals flow
touch /etc/wazuh-fim-test && sleep 60 # on an FIM-monitored path
You should seeNew file detected: /etc/wazuh-fim-test (or similar agent log line)
If this failsIf FIM scan_on_start is off + frequency is at default, you can wait 12 hours. Speed up the cadence (step 4 above) or trigger an auth event instead (ssh in + out — produces an event in seconds).
- 3
Confirm CyberCLI sees the signal
cybercli signals list --connector wazuh --limit 5
You should seeRecent Wazuh signals — count: 5
If this failsIf signals stay at 0 but the connector is healthy: the manager IS emitting alerts but CyberCLI's poller hasn't caught up. Check `cybercli doctor` for poller-cursor lag and `sudo journalctl -u cybercli` for connector errors.
Pitfalls (what bit us so it doesn't bite you)
▸ Don't use the master 'wazuh' user — make a read-only dedicated one
Wazuh's 'wazuh' user has full admin including agent registration, rule modification, and key generation. Storing its credential in a long-lived config (even in CyberCLI's vault) is a blast-radius mistake — any credential leak hands the attacker your entire endpoint estate.
Create a dedicated `cybercli-readonly` user with the `readonly` role (step 1 above). All the polling lanes CyberCLI uses are read-only endpoints; admin scope buys nothing operationally.
▸ Manager API is 55000, NOT the dashboard (443) or indexer (9200)
Wazuh's three-tier architecture (manager + indexer + dashboard) confuses everyone the first time. The dashboard is the web UI you log into; the manager is where the rules + agents live and where the API is. CyberCLI polls the manager API. Pointing at the dashboard returns a redirect or 404; pointing at the indexer returns a different JSON schema and the adopter fails to parse.
Always use port 55000 with HTTPS. The all-in-one installer puts all three on the same host; in split deployments find the manager IP via `/etc/wazuh-server` config or `netstat -lntp | grep 55000` on the manager.
▸ Self-signed certs require `verify_tls=false` — fine for lab, NOT prod
Default wazuh-install.sh ships with self-signed certs. CyberCLI's default is verify=on, which means the first onboarding pass fails with a TLS validation error. Operators flip verify off to get past it and forget to re-enable.
For production: install a proper cert (Let's Encrypt internal, your own CA) and keep verify_tls=on. For lab: ok to verify=off but document it; treat it as a yellow flag in `cybercli doctor`.
▸ FIM events take up to 12 hours to fire on default config
Wazuh's syscheck (file integrity) module scans every 12 hours by default. Newcomers onboard the connector, see health green, do nothing to trigger an event, and conclude the connector is broken because they don't see FIM signals appear for hours.
Speed up the cadence on a test agent (step 4 above) OR use an auth event for the smoke test instead — `sudo -l && exit` produces an audit log event the rules pick up within seconds, no waiting required.
▸ Agents NOT enrolled = healthy connector + zero events forever
CyberCLI polls the manager API regardless of agent count. Zero enrolled agents = the API returns empty alert arrays = the connector indicator stays green but no signals flow. This looks identical to 'I forgot to enable FIM' but the fix is different.
Before declaring the connector broken: run `agent_control -l` on the manager. If the agent list is empty (or only shows '000' which is the manager itself), enrol at least one host. The `wazuh-agent` package + `/var/ossec/bin/agent-auth` is the standard enrolment path.
▸ Wazuh 5.x main is breaking — pin agents + manager to 4.10.x for v1
Wazuh's 5.x branch reshapes the alert JSON schema. The v1 adopter pack targets 4.x; running against a 5.x manager will surface partial events with missing required fields and dump to deadletter.
Pin both manager and agent fleet to the latest 4.10.x point release until CyberCLI ships the 5-flavour adopter (tracked for v1.x). The wazuh-install.sh script lets you pin: `--wazuh-version 4.10`.
Troubleshoot
▸ Symptom: `cybercli onboard wazuh` succeeds but Connectors panel shows red
Cause: Poller started but failed first call — usually wrong URL/port or TLS verify failure.
Fix: Check `sudo journalctl -u cybercli -n 50 | grep wazuh`. The error is usually obvious: 'Connection refused' (wrong port / firewall), '401 Unauthorized' (wrong creds), 'certificate verify failed' (self-signed + verify_tls=true). Re-run `cybercli onboard wazuh --force` with corrected inputs.
▸ Symptom: Connector healthy but signals stuck at 0
Cause: Either no agents enrolled, or no events of interest are firing.
Fix: On the manager run `agent_control -l` — if it shows only '000' (the manager itself) you need to enrol an agent. If agents are listed, force a test event: `sudo touch /etc/test-cybercli && sudo rm /etc/test-cybercli` on a FIM-monitored agent (assuming you've enabled scan_on_start).
▸ Symptom: Some events arrive but specific rule-IDs are missing
Cause: Wazuh's `<group>` or `<rule_id>` filter may be excluding events at the manager level before they get queryable via API. CyberCLI's poller can only see what the API exposes.
Fix: Check `/var/ossec/etc/ossec.conf` for `<email_alerts>` or similar filtering blocks. The alert exclusion happens at the alerting-config level, not at the API. Adjust those filters or enable more rule groups.
FAQ
▸ Can CyberCLI also push commands to Wazuh (Active Response)?
▸ Do I need the Wazuh dashboard / indexer at all?
▸ What about Wazuh agents on Windows? macOS?
- Warden (triage)
- Knight (detection)
- Paladin (containment)
- Scribe (record)
Fully local. Wazuh runs on your hardware and CyberCLI reads it in-network — host telemetry never leaves your environment.