Add SIEM
This commit is contained in:
@@ -43,6 +43,8 @@ serving/kiosk-app/ Svelte+Tailwind spaceship-terminal SP
|
|||||||
OS-side kiosk runtime stays in files/kiosk/
|
OS-side kiosk runtime stays in files/kiosk/
|
||||||
serving/dot1x-bench/ Secure-path bench: step-ca + FreeRADIUS +
|
serving/dot1x-bench/ Secure-path bench: step-ca + FreeRADIUS +
|
||||||
hostapd authenticator + TPM enrolment
|
hostapd authenticator + TPM enrolment
|
||||||
|
serving/siem/ Wazuh SIEM overlay (audit analysis;
|
||||||
|
agentless relay from audit-collector)
|
||||||
.gitea/workflows/ Gitea CI: lint -> packer build -> push OCI
|
.gitea/workflows/ Gitea CI: lint -> packer build -> push OCI
|
||||||
docs/ Design PDF and supporting notes
|
docs/ Design PDF and supporting notes
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -220,6 +220,32 @@ reconnect — no records lost. Documented in
|
|||||||
When the **workstation** firewall is re-enabled (#4 / register #4) it needs the
|
When the **workstation** firewall is re-enabled (#4 / register #4) it needs the
|
||||||
reciprocal **egress** allow for 514/tcp to the collector.
|
reciprocal **egress** allow for 514/tcp to the collector.
|
||||||
|
|
||||||
|
**SIEM (Wazuh) added 2026-06-27 — [serving/siem/](../serving/siem/).** Upgrades the
|
||||||
|
"Detect" pillar from file-collection-only to parse/search/correlate/alert.
|
||||||
|
**Runs on a DEDICATED node — `wazuh1.bitasylum.org`** (managed independently),
|
||||||
|
keeping the memory-hungry indexer JVM **off** the serving host so it can't OOM SPDK
|
||||||
|
(the fleet's root disk / SPOF, #6/#7). **Agentless** (diskless hosts stay stateless,
|
||||||
|
invariant #1): the serving-host audit-collector **relays a copy** to wazuh1's
|
||||||
|
manager syslog listener (`omfwd` → `wazuh1.bitasylum.org:514` in
|
||||||
|
`audit-collector/rsyslog.conf`; rebuild the collector to apply) while still writing
|
||||||
|
durable per-host files. `serving/siem/` is the INTEGRATION (the `<remote>` syslog
|
||||||
|
block to add on wazuh1 + reference deploy overlay), not a local deployment.
|
||||||
|
**DECODING BENCH-VERIFIED 2026-06-27** (`wazuh-logtest`): the audisp-syslog records
|
||||||
|
carry a `node=<host>` prefix (STIG `name_format=hostname`, SSG `auditd_name_format`
|
||||||
|
— kept, it's compliance) that breaks Wazuh's built-in auditd decoder, so a custom
|
||||||
|
**`fleet-auditd`** decoder + rules (`serving/siem/config/local_decoder.xml` +
|
||||||
|
`local_rules.xml`, mounted declaratively via `/wazuh-config-mount`) decode them
|
||||||
|
into the **`fleet_audit`** group. **Decode + alert confirmed:** `wazuh-logtest`
|
||||||
|
shows `decoder.name=fleet-auditd` + `audit.type` extracted (base rule `100100`);
|
||||||
|
and a live `sudo` on a booted host (`cygnus-cruiser-99`) surfaced `USER_CMD` →
|
||||||
|
rule `100130` and `CRED_*`/`USER_ACCT` → rule `100110` (level 5) in the dashboard
|
||||||
|
Threat Hunting view. Wazuh runs multi-node on `wazuh1.bitasylum.org`.
|
||||||
|
**REMAINING (prod):** the relay→wazuh1 hop is **plaintext** — **TLS it** (gtls/6514,
|
||||||
|
fleet CA; ISM protect-logs-in-transit) since it's now on the wire; rotate all Wazuh
|
||||||
|
creds; restrict dashboard/API to admin hosts; set `allowed-ips`→/32 of the serving
|
||||||
|
host; ISM retention/archival; then update the SSP "Detect" + ISM event-logging
|
||||||
|
controls.
|
||||||
|
|
||||||
### Original spec (retained for reference)
|
### Original spec (retained for reference)
|
||||||
|
|
||||||
OpenSCAP + SCAP Security Guide (`xccdf_org.ssgproject.content_profile_stig`), run
|
OpenSCAP + SCAP Security Guide (`xccdf_org.ssgproject.content_profile_stig`), run
|
||||||
|
|||||||
@@ -14,7 +14,10 @@
|
|||||||
> confinement, audit offload verified, PXE/iPXE boot path added, and **UEFI Secure
|
> confinement, audit offload verified, PXE/iPXE boot path added, and **UEFI Secure
|
||||||
> Boot signing verified enforcing on real hardware** (VM HTTP + 820 PXE) — R-13
|
> Boot signing verified enforcing on real hardware** (VM HTTP + 820 PXE) — R-13
|
||||||
> reduced from Medium to Low (residual is making signed + SB-on the standing
|
> reduced from Medium to Low (residual is making signed + SB-on the standing
|
||||||
> default).
|
> default); and (2026-06-27) a **Wazuh SIEM** (dedicated multi-node, agentless)
|
||||||
|
> now decodes + alerts on the fleet auditd stream — "event log analysis/alerting"
|
||||||
|
> moves Planned → Implemented, R-07 reduced toward Low (residual = TLS transport +
|
||||||
|
> retention).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -67,7 +70,7 @@ ISM/PSPF style). Ratings are **pre-treatment** unless stated; the AO accepts the
|
|||||||
|---|---|---|---|---|---|
|
|---|---|---|---|---|---|
|
||||||
| System Security Plan | ISM-0041* | An SSP is developed and maintained. | This document set ([SSP](ssp.md) + this annex). | Partial | Formal sign-off, role appointment pending. |
|
| System Security Plan | ISM-0041* | An SSP is developed and maintained. | This document set ([SSP](ssp.md) + this annex). | Partial | Formal sign-off, role appointment pending. |
|
||||||
| Incident Response Plan | ISM-0043* | An IRP is developed, maintained, exercised. | Not yet authored; inherent recovery via reboot/redeploy. | Planned | R-12 |
|
| Incident Response Plan | ISM-0043* | An IRP is developed, maintained, exercised. | Not yet authored; inherent recovery via reboot/redeploy. | Planned | R-12 |
|
||||||
| Continuous monitoring plan | ISM-1163* | Continuous monitoring strategy documented. | auditd + log offload exist; plan not formalised. | Partial | R-07 |
|
| Continuous monitoring plan | ISM-1163* | Continuous monitoring strategy documented. | auditd + centralised offload + **Wazuh SIEM** (analysis/alerting) exist; formal monitoring *plan/runbook* not yet documented. | Partial | R-07 |
|
||||||
| Strategies maintained & approved | ISM-0027* | Documentation approved by the authorising authority. | Pending AO appointment & approval. | Planned | — |
|
| Strategies maintained & approved | ISM-0027* | Documentation approved by the authorising authority. | Pending AO appointment & approval. | Planned | — |
|
||||||
|
|
||||||
### 2.2 Guidelines for Cyber Security Roles
|
### 2.2 Guidelines for Cyber Security Roles
|
||||||
@@ -117,11 +120,11 @@ ISM/PSPF style). Ratings are **pre-treatment** unless stated; the AO accepts the
|
|||||||
|
|
||||||
| Topic | ISM (rep.) | Requirement intent | System implementation | Status | Residual |
|
| Topic | ISM (rep.) | Requirement intent | System implementation | Status | Residual |
|
||||||
|---|---|---|---|---|---|
|
|---|---|---|---|---|---|
|
||||||
| Centralised event logging | ISM-0988*, ISM-1405* | Logs centrally collected. | `audisp-syslog`→rsyslog `omfwd` (disk-assisted queue) → dedicated collector (`serving/audit-collector/`); **bench-verified end-to-end 2026-06-20**. auditd `space_left_action`→syslog (no MTA). | Partial | R-07 |
|
| Centralised event logging | ISM-0988*, ISM-1405* | Logs centrally collected. | `audisp-syslog`→rsyslog `omfwd` (disk-assisted queue) → dedicated collector (`serving/audit-collector/`), which **relays to a dedicated multi-node Wazuh SIEM** (`wazuh1.bitasylum.org`). **Agentless** (no agent/state on hosts, invariant #1). Bench-verified end-to-end 2026-06-20 (collector) + 2026-06-27 (Wazuh). | Implemented | R-07 (transport/retention) |
|
||||||
| Required events logged | ISM-0582*, ISM-1537* | Log security-relevant events. | STIG auditd rule set; kernel `audit=1`, `audit_backlog_limit=8192`. | Implemented | — |
|
| Required events logged | ISM-0582*, ISM-1537* | Log security-relevant events. | STIG auditd rule set; kernel `audit=1`, `audit_backlog_limit=8192`. | Implemented | — |
|
||||||
| Protect logs in transit | ISM-1432*, ISM-0407* | Encrypt/authenticate log transport. | **Plaintext** offload on isolated LAN (rsyslog TLS rules waived — see [STIG #6](stig-deviations.md)). | Waived (lab) | **R-07** |
|
| Protect logs in transit | ISM-1432*, ISM-0407* | Encrypt/authenticate log transport. | **Plaintext** on both hops (host→collector, collector→Wazuh across a routed mgmt LAN); rsyslog TLS rules waived (see [STIG #6](stig-deviations.md)). | Waived (lab) | **R-07** |
|
||||||
| Log retention & integrity | ISM-0859*, ISM-1815* | Retain & protect logs. | Per-source-host files on collector; retention policy & tamper-protection not yet defined. | Planned | R-07 |
|
| Log retention & integrity | ISM-0859*, ISM-1815* | Retain & protect logs. | Per-source-host files on collector; Wazuh indexer available for retention/ISM but **archival/retention policy not yet configured**. | Planned | R-07 |
|
||||||
| Event log analysis / alerting | ISM-0109*, ISM-1228* | Review logs; alert on incidents. | No SIEM correlation/alerting defined. | Planned | R-07, R-12 |
|
| Event log analysis / alerting | ISM-0109*, ISM-1228* | Review logs; alert on incidents. | **Wazuh SIEM** with a custom **`fleet-auditd`** decoder + severity-tiered rules (`fleet_audit` group; auth, privilege/`USER_CMD`, SELinux). **Decode + alert bench-verified 2026-06-27** (`wazuh-logtest` + live `sudo` in the dashboard). Detection content to expand. | Implemented (content to mature) | R-07 |
|
||||||
|
|
||||||
### 2.7 Guidelines for Networking
|
### 2.7 Guidelines for Networking
|
||||||
|
|
||||||
@@ -177,7 +180,7 @@ asked to accept. Treatments map to [docs/TODO.md](TODO.md) (working POA&M).
|
|||||||
| **R-04** | NVMe/TCP **root traffic plaintext** on the LAN — exposure of OS content / injection if the segment is compromised. | 2.9 (ISM-1139*/1453*) | Unlikely × Major → **Medium** | Isolated boot LAN; MACsec on the access link (once R-01 done) protects the first hop; dm-verity makes injected root blocks fail verification (integrity preserved even if confidentiality isn't). | Production: TLS/IPsec for the storage transport, or rely on MACsec end-to-end across the fabric; document the decision. | **Low–Medium** | Platform/network — *production* |
|
| **R-04** | NVMe/TCP **root traffic plaintext** on the LAN — exposure of OS content / injection if the segment is compromised. | 2.9 (ISM-1139*/1453*) | Unlikely × Major → **Medium** | Isolated boot LAN; MACsec on the access link (once R-01 done) protects the first hop; dm-verity makes injected root blocks fail verification (integrity preserved even if confidentiality isn't). | Production: TLS/IPsec for the storage transport, or rely on MACsec end-to-end across the fabric; document the decision. | **Low–Medium** | Platform/network — *production* |
|
||||||
| **R-05** | **NOPASSWD key-only admin**; no per-host or rotatable access model; human admin MFA on the mgmt plane not enforced. | 2.4 (ISM-1507*/1173*) | Possible × Moderate → **Medium** | Single fleet-generic admin, key-only, root disabled, ECDSA/RSA key, **now SELinux-confined to `staff_u`** with sudo role/type elevation, fully audited; no interactive password to attack. | Per-host/rotatable access (SSH CA / config-agent) + admin MFA on the management plane. | **Low–Medium** | Platform team — *roadmap* |
|
| **R-05** | **NOPASSWD key-only admin**; no per-host or rotatable access model; human admin MFA on the mgmt plane not enforced. | 2.4 (ISM-1507*/1173*) | Possible × Moderate → **Medium** | Single fleet-generic admin, key-only, root disabled, ECDSA/RSA key, **now SELinux-confined to `staff_u`** with sudo role/type elevation, fully audited; no interactive password to attack. | Per-host/rotatable access (SSH CA / config-agent) + admin MFA on the management plane. | **Low–Medium** | Platform team — *roadmap* |
|
||||||
| **R-06** | **FIPS off**; ISM **AACA/AACP conformance not formally asserted**; crypto-module evaluation status unconfirmed. | 2.9 (ISM-0471*/1139*/1277*) | Possible × Major → **Medium** | Modern STIG crypto policy; non-exportable TPM key; no deliberately weak algorithms. Acceptable at OFFICIAL; **mandatory to resolve for PROTECTED+.** | Assert AACA/AACP conformance; decide on FIPS module / evaluated crypto alongside Secure Boot signing. | **Low** (at appropriate classification) | Security + Platform — *before PROTECTED+* |
|
| **R-06** | **FIPS off**; ISM **AACA/AACP conformance not formally asserted**; crypto-module evaluation status unconfirmed. | 2.9 (ISM-0471*/1139*/1277*) | Possible × Major → **Medium** | Modern STIG crypto policy; non-exportable TPM key; no deliberately weak algorithms. Acceptable at OFFICIAL; **mandatory to resolve for PROTECTED+.** | Assert AACA/AACP conformance; decide on FIPS module / evaluated crypto alongside Secure Boot signing. | **Low** (at appropriate classification) | Security + Platform — *before PROTECTED+* |
|
||||||
| **R-07** | Audit-log **offload plaintext**, **single-site**, **no SIEM alerting**; logs interceptable/repudiable and not actively reviewed. (Transport **bench-verified working** 2026-06-20.) | 2.6 (ISM-1432*/0109*/0859*) | Possible × Moderate → **Medium** | Isolated LAN; disk-assisted queue (no loss on collector blip); auditd local copy; per-source files; LinuxAudit captures USBGuard events. | rsyslog **TLS** (gtls/6514) + bundle CA in image (re-select the 3 waived `rsyslog_encrypt_offload_*` rules); define retention + integrity; forward to SIEM with alerting. | **Low** | Platform/SecOps — *production* |
|
| **R-07** | Audit-log **offload plaintext** on both hops (host→collector, collector→Wazuh) and **log retention/archival not yet configured** — logs interceptable in transit and retention/tamper-protection undefined. (**SIEM analysis + alerting now in place** — Wazuh, decode+alert bench-verified 2026-06-27; transport bench-verified 2026-06-20.) | 2.6 (ISM-1432*/0109*/0859*) | Possible × Moderate → **Low–Medium** | Isolated/mgmt LAN; disk-assisted queue (no loss on collector/SIEM blip); auditd local copy; per-source files; **Wazuh now actively decodes + alerts** (`fleet_audit`). | rsyslog **TLS** (gtls/6514) on both hops + bundle CA in image (re-select the 3 waived `rsyslog_encrypt_offload_*` rules); configure Wazuh **retention/archival** (ISM) + rotate default creds + restrict dashboard/API. | **Low** | Platform/SecOps — *production* |
|
||||||
| **R-13** | **Boot-chain signing not yet the standing default** — signing + Secure Boot enforcement are **verified end-to-end on real hardware** (VM HTTP UKI 2026-06-20; 820 PXE signed iPXE→UKI 2026-06-22, SB enforcing, `db` enrolled), but unsigned/SB-OFF lab builds remain possible (CI signs only when `SB_KEY`/`SB_CERT` are set) and not every host has `db` enrolled, so a substituted artifact could still boot on an un-enrolled/unsigned host. | 2.10 (ISM-1542*/0312*) | Unlikely × Major → **Low** | Capability **proven on hardware**; dm-verity rejects a tampered *root* regardless; isolated lab LAN. | Make signed + Secure-Boot-on the **default for all production builds/hosts**: keep `SB_KEY`/`SB_CERT` CI secrets set; enrol `db` fleet-wide; treat an unsigned build as lab-only. | **Low** | Platform team — *before production* |
|
| **R-13** | **Boot-chain signing not yet the standing default** — signing + Secure Boot enforcement are **verified end-to-end on real hardware** (VM HTTP UKI 2026-06-20; 820 PXE signed iPXE→UKI 2026-06-22, SB enforcing, `db` enrolled), but unsigned/SB-OFF lab builds remain possible (CI signs only when `SB_KEY`/`SB_CERT` are set) and not every host has `db` enrolled, so a substituted artifact could still boot on an un-enrolled/unsigned host. | 2.10 (ISM-1542*/0312*) | Unlikely × Major → **Low** | Capability **proven on hardware**; dm-verity rejects a tampered *root* regardless; isolated lab LAN. | Make signed + Secure-Boot-on the **default for all production builds/hosts**: keep `SB_KEY`/`SB_CERT` CI secrets set; enrol `db` fleet-wide; treat an unsigned build as lab-only. | **Low** | Platform team — *before production* |
|
||||||
| **R-08** | **Placeholder RADIUS CA** (`files/etc/dot1x/radius-ca.pem`) — real EAP-TLS trust anchor not provisioned; auth cannot succeed and trust is unestablished. | 2.4 (ISM-1546*) | Certain (lab) × Major → **Medium** | Documented as a placeholder; environment-specific provisioning is the intended path; no real CA committed. | Provision the environment's real RADIUS CA out-of-band (not committed unless classification permits). | **Low** | Environment owner — *before production* |
|
| **R-08** | **Placeholder RADIUS CA** (`files/etc/dot1x/radius-ca.pem`) — real EAP-TLS trust anchor not provisioned; auth cannot succeed and trust is unestablished. | 2.4 (ISM-1546*) | Certain (lab) × Major → **Medium** | Documented as a placeholder; environment-specific provisioning is the intended path; no real CA committed. | Provision the environment's real RADIUS CA out-of-band (not committed unless classification permits). | **Low** | Environment owner — *before production* |
|
||||||
| **R-09** | **Host firewall disabled**; host exposes more network surface than necessary. | 2.7 (ISM-1416*) | Possible × Moderate → **Low–Medium** | Isolated LAN; minimal services; egress controlled at the network/serving layer; no kiosk inbound. | Re-enable firewalld with explicit allow rules (NVMe/TCP `:4420`, DHCP, log offload, SSH) once the secure path is verified. | **Low** | Platform/network — *after R-01* |
|
| **R-09** | **Host firewall disabled**; host exposes more network surface than necessary. | 2.7 (ISM-1416*) | Possible × Moderate → **Low–Medium** | Isolated LAN; minimal services; egress controlled at the network/serving layer; no kiosk inbound. | Re-enable firewalld with explicit allow rules (NVMe/TCP `:4420`, DHCP, log offload, SSH) once the secure path is verified. | **Low** | Platform/network — *after R-01* |
|
||||||
|
|||||||
+22
-10
@@ -16,7 +16,7 @@
|
|||||||
| System name | Diskless Fleet Boot System ("the fleet") |
|
| System name | Diskless Fleet Boot System ("the fleet") |
|
||||||
| Document type | System Security Plan (SSP) |
|
| Document type | System Security Plan (SSP) |
|
||||||
| Version | 0.2 (DRAFT — pre-assessment) |
|
| Version | 0.2 (DRAFT — pre-assessment) |
|
||||||
| Date | 2026-06-22 |
|
| Date | 2026-06-27 |
|
||||||
| Author / maintainer | System Owner (delegate) |
|
| Author / maintainer | System Owner (delegate) |
|
||||||
| Status | Lab / pre-production. STIG hardening applied + bench-verified; **UEFI Secure Boot signing verified enforcing on real hardware** (VM HTTP + EliteBook 820 PXE); secure path (802.1X/MACsec) not yet bench-verified. |
|
| Status | Lab / pre-production. STIG hardening applied + bench-verified; **UEFI Secure Boot signing verified enforcing on real hardware** (VM HTTP + EliteBook 820 PXE); secure path (802.1X/MACsec) not yet bench-verified. |
|
||||||
| Companion documents | [Annex A — ISM control cross-reference & residual risk](ssp-annex-a-ism-residual-risk.md); [Architecture design v2](diskless-fleet-design-v2.pdf); [Design errata](design-v2-errata.md); [STIG deviation register](stig-deviations.md); [Backlog / POA&M source](TODO.md) |
|
| Companion documents | [Annex A — ISM control cross-reference & residual risk](ssp-annex-a-ism-residual-risk.md); [Architecture design v2](diskless-fleet-design-v2.pdf); [Design errata](design-v2-errata.md); [STIG deviation register](stig-deviations.md); [Backlog / POA&M source](TODO.md) |
|
||||||
@@ -164,15 +164,17 @@ This system follows the ISM A&A lifecycle:
|
|||||||
Milestones (POA&M)** (this repo's [TODO.md](TODO.md) is the working POA&M
|
Milestones (POA&M)** (this repo's [TODO.md](TODO.md) is the working POA&M
|
||||||
source).
|
source).
|
||||||
|
|
||||||
**Current status:** Pre-assessment **DRAFT (v0.2, updated 2026-06-22)**. The system
|
**Current status:** Pre-assessment **DRAFT (v0.2, updated 2026-06-27)**. The system
|
||||||
is functional in a lab configuration. **Progress since v0.1 (2026-06-20):** DISA
|
is functional in a lab configuration. **Progress since v0.1 (2026-06-20):** DISA
|
||||||
STIG hardening applied and **bench-verified** on a real build (kiosk, key-only SSH,
|
STIG hardening applied and **bench-verified** on a real build (kiosk, key-only SSH,
|
||||||
audit offload, DHCP-named host, NVMe/verity root all good with hardening on);
|
audit offload, DHCP-named host, NVMe/verity root all good with hardening on);
|
||||||
USBGuard device control enabled + verified; admin confined to `staff_u`; and —
|
USBGuard device control enabled + verified; admin confined to `staff_u`; **UEFI
|
||||||
newly — **UEFI Secure Boot signing verified enforcing end-to-end on real
|
Secure Boot signing verified enforcing end-to-end on real hardware** (CI-signed UKI
|
||||||
hardware**: the CI-signed UKI boots under Secure Boot on a VM (HTTP boot), and the
|
under SB on a VM/HTTP, and the signed iPXE→UKI chain under SB on an EliteBook 820
|
||||||
signed iPXE→UKI chain boots under Secure Boot on an EliteBook 820 G4 (PXE boot),
|
G4/PXE, with `db`/`KEK`/`PK` enrolled via `fleet-sb-enroll`); and — newly — a
|
||||||
with `db`/`KEK`/`PK` enrolled via the baked `fleet-sb-enroll` helper. Several
|
**Wazuh SIEM** (dedicated multi-node, agentless) ingesting the fleet auditd stream
|
||||||
|
with a custom decoder/rules, **decode + alert bench-verified 2026-06-27**, lifting
|
||||||
|
the "Detect" pillar from log-collection-only to analysis + alerting. Several
|
||||||
controls remain **partial or deferred**, tracked as residual risks with treatments
|
controls remain **partial or deferred**, tracked as residual risks with treatments
|
||||||
(Annex A §3). The largest remaining gates on a production ATO: (a) the secure path
|
(Annex A §3). The largest remaining gates on a production ATO: (a) the secure path
|
||||||
(**802.1X/MACsec**) is implemented but **not yet bench-verified** and is disabled
|
(**802.1X/MACsec**) is implemented but **not yet bench-verified** and is disabled
|
||||||
@@ -241,8 +243,18 @@ summarises the implementation posture.
|
|||||||
disk-assisted queue) to a dedicated **audit collector** (`serving/audit-collector/`).
|
disk-assisted queue) to a dedicated **audit collector** (`serving/audit-collector/`).
|
||||||
**Bench-verified end-to-end 2026-06-20** (records reach the collector,
|
**Bench-verified end-to-end 2026-06-20** (records reach the collector,
|
||||||
per-source-host files).
|
per-source-host files).
|
||||||
- *Gaps:* offload currently **plaintext** (TLS planned, R-07); offload is
|
- **SIEM analysis + alerting (Wazuh)** — the collector **relays** the auditd
|
||||||
**local site only**; no SIEM correlation/alerting defined yet.
|
stream to a **dedicated multi-node Wazuh** instance (`wazuh1.bitasylum.org`);
|
||||||
|
ingestion is **agentless** (no agent/state in the diskless image, invariant #1).
|
||||||
|
A custom **`fleet-auditd`** decoder + rules handle the STIG `name_format=hostname`
|
||||||
|
(`node=` prefix) and surface events in the `fleet_audit` group with severity by
|
||||||
|
type (auth, privilege/`USER_CMD`, SELinux/AVC). **Decode + alert bench-verified
|
||||||
|
2026-06-27** (`wazuh-logtest` + a live `sudo` surfacing `USER_CMD`/`CRED_*` in
|
||||||
|
the dashboard). Config is declarative (`serving/siem/`, mounted via
|
||||||
|
`/wazuh-config-mount`).
|
||||||
|
- *Gaps:* both offload hops (host→collector, collector→Wazuh) currently
|
||||||
|
**plaintext** (TLS planned, R-07); **log retention/archival** (ISM) not yet
|
||||||
|
configured; default Wazuh credentials to be rotated before production.
|
||||||
|
|
||||||
### 5.4 Respond
|
### 5.4 Respond
|
||||||
- Known-good recovery is **inherent**: a host returns to a verified state on
|
- Known-good recovery is **inherent**: a host returns to a verified state on
|
||||||
@@ -282,7 +294,7 @@ production ATO:
|
|||||||
| R-04 | NVMe/TCP root traffic **plaintext** on the lab LAN. | **Medium** | Accept (isolated LAN) / treat for production. |
|
| R-04 | NVMe/TCP root traffic **plaintext** on the lab LAN. | **Medium** | Accept (isolated LAN) / treat for production. |
|
||||||
| R-05 | NOPASSWD key-only admin (now `staff_u`-confined); no per-host/rotatable access model or admin-MFA. | **Medium** | Accept with compensating controls / roadmap. |
|
| R-05 | NOPASSWD key-only admin (now `staff_u`-confined); no per-host/rotatable access model or admin-MFA. | **Medium** | Accept with compensating controls / roadmap. |
|
||||||
| R-06 | **FIPS off**; ASD-approved-cryptography conformance not yet asserted. | **Medium** | Treat — required for PROTECTED+; revisit with signing. |
|
| R-06 | **FIPS off**; ASD-approved-cryptography conformance not yet asserted. | **Medium** | Treat — required for PROTECTED+; revisit with signing. |
|
||||||
| R-07 | Audit-log offload **plaintext** (bench-verified working), single-site, no SIEM alerting. | **Medium** | Treat — TLS offload + monitoring on roadmap. |
|
| R-07 | Audit-log offload **plaintext** on both hops (host→collector, collector→Wazuh); **log retention not yet configured**. SIEM **analysis + alerting now in place** (Wazuh, decode+alert bench-verified 2026-06-27). | **Low–Medium** | Treat — TLS both hops + ISM retention/archival + rotate Wazuh creds before production. |
|
||||||
| R-08 | **Placeholder RADIUS CA** in the repo; real trust anchor not yet provisioned. | **Medium** | Treat — environment-specific, before production. |
|
| R-08 | **Placeholder RADIUS CA** in the repo; real trust anchor not yet provisioned. | **Medium** | Treat — environment-specific, before production. |
|
||||||
| R-09 | Host **firewall disabled** (workstation). | **Low–Medium** | Accept (isolated LAN) / treat with explicit allow-rules. |
|
| R-09 | Host **firewall disabled** (workstation). | **Low–Medium** | Accept (isolated LAN) / treat with explicit allow-rules. |
|
||||||
| R-13 | **Boot-chain signing not yet the standing default.** Signing + Secure Boot enforcement **verified end-to-end on hardware** (VM HTTP UKI 2026-06-20; 820 PXE signed iPXE→UKI 2026-06-22), but unsigned/SB-OFF lab builds are still possible (CI signs only when `SB_KEY`/`SB_CERT` are set) and not all hosts have `db` enrolled. | **Low** | Treat — make signed + Secure-Boot-on the default for all production builds/hosts (set CI secrets; enrol `db` fleet-wide). |
|
| R-13 | **Boot-chain signing not yet the standing default.** Signing + Secure Boot enforcement **verified end-to-end on hardware** (VM HTTP UKI 2026-06-20; 820 PXE signed iPXE→UKI 2026-06-22), but unsigned/SB-OFF lab builds are still possible (CI signs only when `SB_KEY`/`SB_CERT` are set) and not all hosts have `db` enrolled. | **Low** | Treat — make signed + Secure-Boot-on the default for all production builds/hosts (set CI secrets; enrol `db` fleet-wide). |
|
||||||
|
|||||||
@@ -53,6 +53,16 @@ DHCP_LEASE=12h
|
|||||||
# 8088 clashes on the serving host (also update http/default.conf proxy_pass).
|
# 8088 clashes on the serving host (also update http/default.conf proxy_pass).
|
||||||
KIOSK_APP_PORT=8088
|
KIOSK_APP_PORT=8088
|
||||||
|
|
||||||
|
# Local testing secrets for the kiosk BFF. This file is GITIGNORED — safe to
|
||||||
|
# paste a real token here. Template/docs: .env.example.
|
||||||
|
|
||||||
|
HASS_URL=http://cortana.bitasylum.org:8123
|
||||||
|
|
||||||
|
# 👇 paste your Home Assistant long-lived access token here, then restart the BFF
|
||||||
|
# (npm run bff). Test it with: curl -s localhost:8787/api/health | jq
|
||||||
|
HASS_TOKEN=<insert-token>
|
||||||
|
|
||||||
|
|
||||||
# --- DNS names -------------------------------------------------------------
|
# --- DNS names -------------------------------------------------------------
|
||||||
BOOT_DOMAIN=fleet.lab
|
BOOT_DOMAIN=fleet.lab
|
||||||
BOOT_HOST=boot.fleet.lab # HTTP boot server name (UKI)
|
BOOT_HOST=boot.fleet.lab # HTTP boot server name (UKI)
|
||||||
|
|||||||
@@ -27,6 +27,28 @@ main_queue(
|
|||||||
queue.saveOnShutdown="on"
|
queue.saveOnShutdown="on"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# --- relay a COPY of audit records to the Wazuh SIEM (separate node) -----------
|
||||||
|
# Forwards audit/local6 records to the Wazuh manager's syslog listener on the
|
||||||
|
# dedicated SIEM node (wazuh1.bitasylum.org) for parsing/correlation/alerting,
|
||||||
|
# WHILE still writing the durable per-host files below (no `stop`, so records
|
||||||
|
# continue to the file actions). Own disk-assisted queue -> a Wazuh outage never
|
||||||
|
# blocks the file writes or drops records (resumeRetryCount=-1 spools + drains on
|
||||||
|
# reconnect). The serving host must resolve + route to the SIEM node. After
|
||||||
|
# editing, rebuild: `docker compose build audit && docker compose up -d audit`.
|
||||||
|
#
|
||||||
|
# ⚠ PLAINTEXT 514 — only acceptable if serving-host → SIEM-node is a TRUSTED
|
||||||
|
# private path. Audit records are sensitive; if this hop crosses any routed/
|
||||||
|
# untrusted network, switch to syslog-over-TLS (gtls, port 6514, fleet CA) BEFORE
|
||||||
|
# relying on it (ISM: protect logs in transit). See serving/siem/README.md.
|
||||||
|
if ($programname == 'audispd')
|
||||||
|
or ($programname startswith 'audit')
|
||||||
|
or ($syslogfacility-text == 'local6') then {
|
||||||
|
action(type="omfwd" target="wazuh1.bitasylum.org" port="514" protocol="tcp"
|
||||||
|
action.resumeRetryCount="-1"
|
||||||
|
queue.type="LinkedList" queue.filename="wazuhfwdq"
|
||||||
|
queue.maxDiskSpace="256m" queue.saveOnShutdown="on")
|
||||||
|
}
|
||||||
|
|
||||||
# --- per-source-host files (keyed by SENDER IP, not the claimed hostname) ---
|
# --- per-source-host files (keyed by SENDER IP, not the claimed hostname) ---
|
||||||
template(name="HostAudit" type="string" string="/var/log/remote/%FROMHOST-IP%/audit.log")
|
template(name="HostAudit" type="string" string="/var/log/remote/%FROMHOST-IP%/audit.log")
|
||||||
template(name="HostMessages" type="string" string="/var/log/remote/%FROMHOST-IP%/messages.log")
|
template(name="HostMessages" type="string" string="/var/log/remote/%FROMHOST-IP%/messages.log")
|
||||||
|
|||||||
@@ -203,7 +203,9 @@ services:
|
|||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
ports:
|
ports:
|
||||||
- "127.0.0.1:${KIOSK_APP_PORT:-8088}:80" # loopback only; main nginx proxies here
|
- "127.0.0.1:${KIOSK_APP_PORT:-8088}:80" # loopback only; main nginx proxies here
|
||||||
|
environment:
|
||||||
|
HASS_URL: ${HASS_URL}
|
||||||
|
HASS_TOKEN: ${HASS_TOKEN}
|
||||||
# --- NTP server (serves time to the boot LAN; handed out via DHCP opt 42) ---
|
# --- NTP server (serves time to the boot LAN; handed out via DHCP opt 42) ---
|
||||||
ntp:
|
ntp:
|
||||||
build: ./chrony
|
build: ./chrony
|
||||||
|
|||||||
@@ -29,5 +29,10 @@ server {
|
|||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
proxy_set_header X-Forwarded-For $remote_addr;
|
proxy_set_header X-Forwarded-For $remote_addr;
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
proxy_set_header Connection ""; # SSE is plain HTTP — no WebSocket upgrade needed
|
||||||
|
proxy_buffering off;
|
||||||
|
proxy_cache off;
|
||||||
|
proxy_read_timeout 1h;
|
||||||
|
chunked_transfer_encoding off;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
# REFERENCE for deploying the SIEM node (wazuh1.bitasylum.org) with the upstream
|
||||||
|
# Wazuh single-node compose. Wazuh is managed on that node, NOT by the fleet
|
||||||
|
# serving stack — so these creds live there, not in the serving repo's runtime.
|
||||||
|
# Copy to upstream/single-node/.env on the SIEM node and CHANGE every password.
|
||||||
|
|
||||||
|
# Wazuh release — pin to current stable (github.com/wazuh/wazuh-docker/releases).
|
||||||
|
WAZUH_VERSION=4.12.0
|
||||||
|
|
||||||
|
# --- credentials (ROTATE — these are public defaults) ----------------------
|
||||||
|
INDEXER_USERNAME=admin
|
||||||
|
INDEXER_PASSWORD=ChangeMe-Indexer-Adm1n!
|
||||||
|
API_USERNAME=wazuh-wui
|
||||||
|
API_PASSWORD=ChangeMe-Api-Passw0rd!
|
||||||
|
DASHBOARD_USERNAME=kibanaserver
|
||||||
|
DASHBOARD_PASSWORD=ChangeMe-Dash-Passw0rd!
|
||||||
|
|
||||||
|
# --- fleet integration (set ON the node / in the manager config) -----------
|
||||||
|
# TCP syslog ingest port the manager listens on (config/fleet-remote-syslog.xml)
|
||||||
|
# and the override publishes. The serving-host audit-collector relays here.
|
||||||
|
WAZUH_SYSLOG_PORT=514
|
||||||
|
# Source the manager accepts syslog from = the SERVING HOST's IP (goes in the
|
||||||
|
# <allowed-ips> of config/fleet-remote-syslog.xml). Confirm the real source in the
|
||||||
|
# manager logs and tighten to /32.
|
||||||
|
WAZUH_ALLOWED_IPS=SET-TO-SERVING-HOST-IP/32
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
# The upstream Wazuh deployment is cloned in, not vendored — never commit it,
|
||||||
|
# its generated TLS certs, or any data/volumes.
|
||||||
|
upstream/
|
||||||
|
*.pem
|
||||||
|
*.key
|
||||||
|
.env
|
||||||
|
data/
|
||||||
@@ -0,0 +1,128 @@
|
|||||||
|
# Wazuh SIEM — fleet integration
|
||||||
|
|
||||||
|
The fleet's auditd stream is analysed by **Wazuh running on its own node:
|
||||||
|
`wazuh1.bitasylum.org`** (deployed + managed independently — keeping the
|
||||||
|
memory-hungry indexer off the serving host, which runs SPDK = the fleet's root
|
||||||
|
disk / a SPOF; see TODO #6/#7). This directory is the **fleet ↔ Wazuh
|
||||||
|
integration**, not a deployment of Wazuh.
|
||||||
|
|
||||||
|
**Ingestion is agentless** (no agent in the diskless image — that would carry
|
||||||
|
per-host registration state, breaking invariant #1). The host side is unchanged;
|
||||||
|
the serving-host collector relays a copy to the SIEM node:
|
||||||
|
|
||||||
|
```
|
||||||
|
host: auditd → audisp-syslog (LOCAL6) → rsyslog omfwd ─┐
|
||||||
|
▼ TCP/514
|
||||||
|
serving host: audit-collector (rsyslog) ──relay(omfwd)──► wazuh1.bitasylum.org
|
||||||
|
│ still writes durable per-host files (manager :514 syslog
|
||||||
|
└ disk-assisted queue (store-and-forward) → indexer → dashboard)
|
||||||
|
```
|
||||||
|
|
||||||
|
The collector keeps its durable file copy + disk queue and **relays a copy**, so a
|
||||||
|
SIEM outage never drops audit records or blocks the file writes.
|
||||||
|
|
||||||
|
## To turn it on (two ends)
|
||||||
|
|
||||||
|
**1. On the SIEM node (`wazuh1`):** add the syslog reception block — insert
|
||||||
|
[config/fleet-remote-syslog.xml](config/fleet-remote-syslog.xml) into the
|
||||||
|
manager's `ossec.conf`, set `<allowed-ips>` to the **serving host's IP**, and make
|
||||||
|
sure the manager's TCP syslog port is reachable (the upstream single-node compose +
|
||||||
|
[docker-compose.override.yml](docker-compose.override.yml) publish `514/tcp`).
|
||||||
|
Restart the manager.
|
||||||
|
|
||||||
|
**2. On the serving host:** the relay is already wired in
|
||||||
|
[../audit-collector/rsyslog.conf](../audit-collector/rsyslog.conf), targeting
|
||||||
|
`wazuh1.bitasylum.org:514`. Apply it by rebuilding the collector image (the conf
|
||||||
|
is COPY'd in at build):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd serving && docker compose build audit && docker compose up -d audit
|
||||||
|
# the serving host must RESOLVE + ROUTE to wazuh1.bitasylum.org
|
||||||
|
```
|
||||||
|
|
||||||
|
## Decode the fleet's auditd (custom decoder + rules)
|
||||||
|
|
||||||
|
The fleet ships auditd **agentlessly** via audisp-syslog, and STIG sets
|
||||||
|
`name_format = hostname` (keep it — compliance), which prepends `node=<host>` to
|
||||||
|
each record. Wazuh's built-in auditd decoder expects the line to start with
|
||||||
|
`type=`, so it decodes **nothing** (`"decoder":{}`) — `rule.groups: audit` stays
|
||||||
|
empty. Install the fleet decoder + rules **on the master** so the records decode + alert.
|
||||||
|
|
||||||
|
**Declarative (recommended) — bind-mount via compose**, using the image's
|
||||||
|
`/wazuh-config-mount` mechanism (entrypoint copies the tree into `/var/ossec` at
|
||||||
|
startup; correct ownership, survives `--force-recreate`, no `docker cp`). Add to
|
||||||
|
the `wazuh.master` service (see [docker-compose.override.yml](docker-compose.override.yml)) —
|
||||||
|
put the files next to your compose / `wazuh_manager.conf`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
volumes:
|
||||||
|
- ./config/local_decoder.xml:/wazuh-config-mount/etc/decoders/local_decoder.xml
|
||||||
|
- ./config/local_rules.xml:/wazuh-config-mount/etc/rules/local_rules.xml
|
||||||
|
```
|
||||||
|
```bash
|
||||||
|
docker compose up -d --force-recreate wazuh.master
|
||||||
|
docker exec <master> grep -iE 'error|rules|decoder' /var/ossec/logs/ossec.log | tail # no errors
|
||||||
|
# verify decoding interactively — paste a full_log line (the `Jun 27 ... node=...`):
|
||||||
|
docker exec -it <master> /var/ossec/bin/wazuh-logtest
|
||||||
|
```
|
||||||
|
In a cluster, mount on the **master only** — Wazuh syncs `etc/decoders` + `etc/rules`
|
||||||
|
to the workers. A config change needs a recreate/restart (the copy is at startup).
|
||||||
|
|
||||||
|
> Quick one-off test without editing compose (lost on recreate):
|
||||||
|
> `docker cp config/local_decoder.xml <master>:/var/ossec/etc/decoders/ && docker cp config/local_rules.xml <master>:/var/ossec/etc/rules/ && docker exec <master> /var/ossec/bin/wazuh-control restart`
|
||||||
|
`wazuh-logtest` should show `decoder 'fleet-auditd'` and `audit.type` extracted,
|
||||||
|
firing rule `100100` (+ a higher rule for auth/SELinux types). Then in the
|
||||||
|
dashboard: **`rule.groups: fleet_audit`** populates. (The base rule is **level 0**
|
||||||
|
— captured but not alerted — so the high-volume SYSCALL/PATH stream doesn't flood
|
||||||
|
alerts; only security-relevant types alert. Tune `config/local_rules.xml`.)
|
||||||
|
|
||||||
|
**Full audit trail (not just alerts):** to make *every* record searchable
|
||||||
|
(forensics / ISM retention), enable archive indexing — `<logall_json>yes</logall_json>`
|
||||||
|
on the manager **and** `archives.enabled: true` in the manager's
|
||||||
|
`/etc/filebeat/filebeat.yml`, then add the `wazuh-archives-*` index pattern in the
|
||||||
|
dashboard. High-volume — slim the auditd rules on the host or filter before
|
||||||
|
indexing.
|
||||||
|
|
||||||
|
## Verify
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# on the SIEM node, after a diskless host has booted + generated auditd events:
|
||||||
|
docker compose logs wazuh.manager | grep -i syslog # listener up, source accepted
|
||||||
|
# Wazuh dashboard → Security events: auditd records from the boot-LAN hosts appear,
|
||||||
|
# decoded (type=SYSCALL/USER_LOGIN/...) and rule-tagged.
|
||||||
|
```
|
||||||
|
|
||||||
|
If nothing arrives: the manager logs rejected sources — confirm `<allowed-ips>`
|
||||||
|
matches the serving host's IP **as wazuh1 sees it** (may be its management IP, not
|
||||||
|
`SERVER_IP`), then tighten to a /32.
|
||||||
|
|
||||||
|
## ⚠ Protect the hop — it's now on the wire
|
||||||
|
|
||||||
|
Co-located it was loopback; serving-host → `wazuh1` now crosses the network, and
|
||||||
|
audit records are sensitive (ISM: protect logs in transit). The relay ships
|
||||||
|
**plaintext 514** for first bring-up — only acceptable on a **trusted private
|
||||||
|
path**. Before relying on it, switch to **syslog-over-TLS** (`gtls`, port 6514,
|
||||||
|
the manager's cert + the fleet CA) on both the relay (`omfwd` with the TLS driver)
|
||||||
|
and the manager `<remote>` block. Same CA work as the secure-path / audit-offload
|
||||||
|
TLS TODO.
|
||||||
|
|
||||||
|
## Production checklist
|
||||||
|
|
||||||
|
- **TLS the relay → wazuh1 hop** (above).
|
||||||
|
- **Rotate all Wazuh credentials** on the node (indexer admin, API, dashboard).
|
||||||
|
- **Restrict the dashboard/API** (`:443`/`:55000`) to admin hosts / VPN — never the
|
||||||
|
boot LAN.
|
||||||
|
- **`allowed-ips` → /32** of the serving host.
|
||||||
|
- **Retention/archival**: indexer ISM for the ISM-mandated retention + cold archive.
|
||||||
|
- **SSP**: update the "Detect" section + ISM event-logging controls once
|
||||||
|
bench-verified, and record the retention design.
|
||||||
|
|
||||||
|
## Files here
|
||||||
|
|
||||||
|
| File | Where it's used |
|
||||||
|
|---|---|
|
||||||
|
| `config/fleet-remote-syslog.xml` | the `<remote>` block to add to the **manager** on wazuh1 |
|
||||||
|
| `docker-compose.override.yml` | reference overlay if wazuh1 uses the upstream single-node compose |
|
||||||
|
| `.env.example` | reference env for deploying the wazuh1 node |
|
||||||
|
|
||||||
|
(The actual fleet-side relay lives in `../audit-collector/rsyslog.conf`.)
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
<!--
|
||||||
|
Fleet syslog reception for the Wazuh manager — apply this ON THE SIEM NODE
|
||||||
|
(wazuh1.bitasylum.org), inside the <ossec_config> of the manager's ossec.conf
|
||||||
|
(upstream single-node: config/wazuh_cluster/wazuh_manager.conf), then restart
|
||||||
|
the manager.
|
||||||
|
|
||||||
|
It makes the manager accept the auditd stream RELAYED by the fleet's
|
||||||
|
serving-host audit-collector over TCP/514. The source the manager sees is the
|
||||||
|
SERVING HOST's IP (the collector is host-networked there), so set <allowed-ips>
|
||||||
|
to that address — confirm the exact source in `docker compose logs wazuh.manager`
|
||||||
|
(rejected sources are logged) and tighten to a /32.
|
||||||
|
|
||||||
|
The diskless hosts stay AGENTLESS (no per-host state, invariant #1); the secure
|
||||||
|
agent listener (1514) + enrollment (1515) are left as the manager default for
|
||||||
|
any future enrolment-registered ephemeral agents.
|
||||||
|
|
||||||
|
⚠ PLAINTEXT — pair with a TRUSTED serving→SIEM path, or switch to TLS (see
|
||||||
|
README): <protocol>tcp</protocol> on 6514 with the manager's cert + the fleet CA.
|
||||||
|
-->
|
||||||
|
<remote>
|
||||||
|
<connection>syslog</connection>
|
||||||
|
<port>514</port>
|
||||||
|
<protocol>tcp</protocol>
|
||||||
|
<allowed-ips>SET-TO-SERVING-HOST-IP/32</allowed-ips>
|
||||||
|
<!-- e.g. <allowed-ips>192.168.50.10/32</allowed-ips> (the serving host as seen
|
||||||
|
by wazuh1 — may be its management IP, not SERVER_IP, if a different route) -->
|
||||||
|
</remote>
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
<!--
|
||||||
|
Fleet auditd-over-syslog decoder — install on the SIEM node (wazuh.master) at
|
||||||
|
/var/ossec/etc/decoders/local_decoder.xml, then restart the manager.
|
||||||
|
|
||||||
|
WHY: the fleet ships auditd agentlessly via audisp-syslog. STIG hardening sets
|
||||||
|
auditd `name_format = hostname` (SSG auditd_name_format — keep it, it's
|
||||||
|
compliance), which prepends `node=<host>` to every record. Wazuh's BUILT-IN
|
||||||
|
auditd decoder expects the line to start with `type=`, so the node= prefix made
|
||||||
|
it match nothing (`"decoder":{}`). This decoder handles the node= variant.
|
||||||
|
|
||||||
|
Pre-decoding strips the syslog header + program (`... audispd[709]: `), so the
|
||||||
|
text these decoders see starts at `node=...`.
|
||||||
|
|
||||||
|
Verify with: docker exec -it <master> /var/ossec/bin/wazuh-logtest
|
||||||
|
(paste a full_log line from archives.json; confirm decoder.name = fleet-auditd
|
||||||
|
and audit.type is extracted, then adjust if your build reports the child name).
|
||||||
|
-->
|
||||||
|
<decoder name="fleet-auditd">
|
||||||
|
<program_name>audispd</program_name>
|
||||||
|
</decoder>
|
||||||
|
|
||||||
|
<decoder name="fleet-auditd">
|
||||||
|
<parent>fleet-auditd</parent>
|
||||||
|
<regex type="pcre2">^node=(\S+) type=(\w+) msg=audit\(([\d.]+):(\d+)\):</regex>
|
||||||
|
<order>audit.node,audit.type,audit.timestamp,audit.serial</order>
|
||||||
|
</decoder>
|
||||||
|
|
||||||
|
<!-- best-effort common fields (present depending on record type) -->
|
||||||
|
<decoder name="fleet-auditd">
|
||||||
|
<parent>fleet-auditd</parent>
|
||||||
|
<regex type="pcre2"> auid=(\d+)</regex>
|
||||||
|
<order>audit.auid</order>
|
||||||
|
</decoder>
|
||||||
|
|
||||||
|
<decoder name="fleet-auditd">
|
||||||
|
<parent>fleet-auditd</parent>
|
||||||
|
<regex type="pcre2"> (?:res|success)=(\S+)</regex>
|
||||||
|
<order>audit.res</order>
|
||||||
|
</decoder>
|
||||||
|
|
||||||
|
<decoder name="fleet-auditd">
|
||||||
|
<parent>fleet-auditd</parent>
|
||||||
|
<regex type="pcre2"> exe="([^"]+)"</regex>
|
||||||
|
<order>audit.exe</order>
|
||||||
|
</decoder>
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
<!--
|
||||||
|
Fleet auditd rules — install on the SIEM node (wazuh.master) at
|
||||||
|
/var/ossec/etc/rules/local_rules.xml, then restart the manager. Pairs with
|
||||||
|
local_decoder.xml.
|
||||||
|
|
||||||
|
Design: the BASE rule is level 0 — every decoded fleet auditd record is captured
|
||||||
|
(searchable, archived) but does NOT raise an alert, so the high-volume
|
||||||
|
SYSCALL/PATH/PROCTITLE/EOE stream (e.g. Chromium) doesn't flood alerts.json.
|
||||||
|
Security-relevant record TYPES are bumped to alerting levels below. Tune to your
|
||||||
|
detection needs. To see the FULL audit trail (not just alerts) in the dashboard,
|
||||||
|
enable archive indexing (wazuh-archives-*) — see README.
|
||||||
|
-->
|
||||||
|
<group name="fleet_audit,">
|
||||||
|
|
||||||
|
<!-- base: any decoded fleet auditd record (level 0 = logged, not alerted) -->
|
||||||
|
<rule id="100100" level="0">
|
||||||
|
<decoded_as>fleet-auditd</decoded_as>
|
||||||
|
<description>Fleet auditd: $(audit.type) on $(audit.node)</description>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<!-- authentication / credential events -->
|
||||||
|
<rule id="100110" level="5">
|
||||||
|
<if_sid>100100</if_sid>
|
||||||
|
<field name="audit.type">^USER_LOGIN$|^USER_AUTH$|^USER_ACCT$|^USER_ERR$|^CRED_</field>
|
||||||
|
<description>Fleet audit: authentication event $(audit.type) on $(audit.node)</description>
|
||||||
|
<group>authentication,</group>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<!-- failed auth (res/success = failed/no/0) -> higher -->
|
||||||
|
<rule id="100111" level="8">
|
||||||
|
<if_sid>100110</if_sid>
|
||||||
|
<field name="audit.res">^failed$|^no$|^0$</field>
|
||||||
|
<description>Fleet audit: FAILED authentication $(audit.type) on $(audit.node)</description>
|
||||||
|
<group>authentication_failed,</group>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<!-- SELinux denials / kernel anomaly records -->
|
||||||
|
<rule id="100120" level="7">
|
||||||
|
<if_sid>100100</if_sid>
|
||||||
|
<field name="audit.type">^AVC$|^SELINUX_ERR$|^ANOM_|^USER_AVC$</field>
|
||||||
|
<description>Fleet audit: SELinux/anomaly $(audit.type) on $(audit.node)</description>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<!-- privilege use / config changes worth surfacing -->
|
||||||
|
<rule id="100130" level="5">
|
||||||
|
<if_sid>100100</if_sid>
|
||||||
|
<field name="audit.type">^USER_CMD$|^USYS_CONFIG$|^ADD_USER$|^DEL_USER$|^ADD_GROUP$|^ROLE_</field>
|
||||||
|
<description>Fleet audit: privileged/config event $(audit.type) on $(audit.node)</description>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
</group>
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
# REFERENCE (applied ON the SIEM node, wazuh1.bitasylum.org, if you deploy it with
|
||||||
|
# the upstream Wazuh single-node compose). NOT used by the fleet serving stack —
|
||||||
|
# Wazuh runs on its own node, managed independently. The only fleet-specific bit
|
||||||
|
# is publishing the manager's TCP syslog listener so the serving-host
|
||||||
|
# audit-collector relay can reach it:
|
||||||
|
#
|
||||||
|
# cd upstream/single-node
|
||||||
|
# docker compose -f docker-compose.yml -f /path/to/docker-compose.override.yml up -d
|
||||||
|
#
|
||||||
|
# On a dedicated node the indexer gets full resources — no co-location memory caps.
|
||||||
|
#
|
||||||
|
# ⚠ SERVICE NAME depends on the upstream deployment you used:
|
||||||
|
# - single-node compose -> service is `wazuh.manager`
|
||||||
|
# - multi-node compose -> service is `wazuh.master` (the syslog receiver)
|
||||||
|
# Match your deployment. The upstream publishes 514/UDP only — the fleet relay is
|
||||||
|
# TCP, so the ONE required change is adding 514/tcp on whichever node runs the
|
||||||
|
# syslog `<remote>` block. (Recreate the container after a port change.)
|
||||||
|
services:
|
||||||
|
wazuh.master: # rename to wazuh.manager for a single-node deployment
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "514:514/tcp" # TCP syslog ingest for the fleet audit relay
|
||||||
|
volumes:
|
||||||
|
# Declarative custom decoder + rules via the image's /wazuh-config-mount
|
||||||
|
# mechanism (entrypoint copies the tree into /var/ossec at startup — correct
|
||||||
|
# ownership, survives --force-recreate, no docker cp). In a cluster, put them
|
||||||
|
# on the master only; Wazuh syncs etc/decoders + etc/rules to the workers.
|
||||||
|
# NOTE: relative bind paths resolve to the COMPOSE PROJECT DIR, so keep these
|
||||||
|
# files alongside the compose you run (or use an absolute path). A config
|
||||||
|
# change needs a recreate/restart (the copy happens at startup).
|
||||||
|
- ./config/local_decoder.xml:/wazuh-config-mount/etc/decoders/local_decoder.xml
|
||||||
|
- ./config/local_rules.xml:/wazuh-config-mount/etc/rules/local_rules.xml
|
||||||
Reference in New Issue
Block a user