Zurück zum Blog

SOC-2-Compliance-Stack: Fleet, Wazuh und Keycloak für kleine Teams

28. Februar 202610 Min.
Geräte & Daten

Security Engineering · Technischer Deep-Dive

Security-Compliance-Frameworks existieren, um eine unangenehme Frage zu beantworten: Können Sie beweisen, dass Ihre Systeme sicher sind? Nicht behaupten — beweisen, mit Logs, Alarmen und Audit-Trails, die einer Prüfung durch Dritte standhalten.

ToolRoleLicense
Keycloak
Keycloak
Identity Layer (0) — SSO, SAML, OIDC, MFA, and a full audit log of every auth eventOpen Source · Apache 2.0
Wazuh
Wazuh
SIEM & Compliance Engine — log ingestion, threat correlation, SOC 2 / HIPAA / PCI dashboardsOpen Source · GPL
Fleet
Fleet
Query & Inventory Layer — osquery across all endpoints, queryable compliance recordOpen Source · MIT
🔬
OpenEDR
Behavioral Detection Layer — process trees, credential access, lateral movement via MITRE ATT&CKOpen Source · Apache 2.0
🚫
Fail2ban
Active Response Layer — bans offending IPs via firewall rules, immutable response audit trailOpen Source · GPL
📧
MXToolbox
Email & Domain Security — continuous SPF, DKIM, DMARC, and blacklist monitoringFree monitoring tier
Falco
Falco
Runtime Detection Layer — eBPF syscall interception on Linux servers and containersOpen Source · Apache 2.0
Shuffle
Shuffle
SOAR & Automation Layer — connects Wazuh, Fleet, Keycloak, Fail2ban, and Rocket.Chat into response workflowsOpen Source · Apache 2.0

Der App-Stack

Keycloak — Identitätsschicht (Schicht 0)

  • Zentralisiert die Authentifizierung über alle Geräte und Server hinweg via SSO, SAML und OIDC
  • Erzeugt ein vollständiges Audit-Log jedes Logins, jeder Token-Ausstellung und jeder Admin-Aktion

Für ein vollständig verwaltetes Keycloak-Deployment auf PikaPods siehe Hosting ohne Kopfschmerzen: WordPress, Ghost & Keycloak auf PikaPods betreiben.

▶ show code
# Setup Steps
1. Deploy via Docker or dedicated 2 vCPU / 4 GB host
2. Create a dedicated realm — never use master for app logins
3. Create OIDC clients for Wazuh, Shuffle, Fleet, and Rocket.Chat
4. Enforce TOTP MFA via Required Actions
5. Set password policy: 12+ chars, special char, digit, history 5
6. Enable full event logging with 90+ day expiration
7. Wire Wazuh Dashboard SAML/OIDC via roles_mapping.yml
▶ show code
// Enable full event logging (realm settings)
// Keycloak realm settings — enable full event logging
{
  "eventsEnabled": true,
  "eventsExpiration": 7776000,
  "adminEventsEnabled": true,
  "adminEventsDetailsEnabled": true,
  "enabledEventTypes": [
    "LOGIN", "LOGIN_ERROR", "LOGOUT",
    "REGISTER", "REGISTER_ERROR",
    "UPDATE_PASSWORD", "UPDATE_PASSWORD_ERROR",
    "CLIENT_LOGIN", "CLIENT_LOGIN_ERROR"
  ]
}

<!-- Wazuh agent — read Keycloak log output -->
<!-- ossec.conf — on Keycloak host -->
<ossec_config>
  <localfile>
    <log_format>json</log_format>
    <location>/opt/keycloak/data/log/keycloak.log</location>
    <label key="source">keycloak</label>
  </localfile>
</ossec_config>

<!-- Wazuh rules — login failures and admin privilege changes -->
<!-- keycloak_rules.xml -->
<group name="keycloak,authentication,">
  <rule id="92001" level="8">
    <decoded_as>json</decoded_as>
    <field name="source">keycloak</field>
    <field name="type">LOGIN_ERROR</field>
    <description>Keycloak: Authentication failure</description>
    <group>pci_dss_10.2.4,hipaa_164.312.b,soc2_cc6.1,</group>
  </rule>
  <rule id="92002" level="12" frequency="5" timeframe="60">
    <if_matched_sid>92001</if_matched_sid>
    <description>Keycloak: Brute force attack — 5+ failures in 60 seconds</description>
    <group>pci_dss_10.6.1,hipaa_164.312.b,</group>
  </rule>
  <rule id="92003" level="10">
    <decoded_as>json</decoded_as>
    <field name="source">keycloak</field>
    <field name="operationType">CREATE|UPDATE|DELETE</field>
    <field name="resourceType">USER|ROLE_MAPPING|CLIENT_ROLE_MAPPING</field>
    <description>Keycloak: Admin privilege change detected</description>
    <group>pci_dss_8.5,soc2_cc6.1,</group>
  </rule>
</group>

Wazuh — SIEM & Compliance Engine

  • Nimmt Logs aus praktisch jeder Quelle auf und wendet Korrelationsregeln an, um Bedrohungen und Richtlinienverstöße zu erkennen
  • Compliance-Dashboards ordnen jedes Ereignis konkreten Control-Anforderungen zu — auditfähig, ohne wochenlange manuelle Arbeit
▶ show code
# Setup Steps
# Deploy Wazuh Manager + Indexer + Dashboard
1. Provision 4 vCPU, 8 GB RAM, 50+ GB SSD
2. Set hostname and configure /etc/hosts for local FQDN
3. Run the Wazuh all-in-one installer script
4. Confirm all three services are running
5. Log in and immediately change the default admin password
6. Lock firewall to ports 1514, 1515, and 443 only

# Install Wazuh Agents on all endpoints + Keycloak host
1. Linux: dpkg install with WAZUH_MANAGER env set
2. macOS: .pkg install + launchctl load
3. Windows: msiexec silent install
4. Verify each agent appears in dashboard within 60 seconds
5. Enable FIM on Keycloak config and log directories
6. Tag agents by group for policy segmentation

# Enable Wazuh Compliance Modules
1. Enable compliance dashboards in Wazuh → Modules
2. Verify ruleset includes compliance tags
3. Download and deploy NIST/CIS SCA policy files to agent groups
4. Run initial SCA scan and review compliance %
5. Document failing controls as tracked exceptions

# Configure Alert Routing
1. Email: configure SMTP in ossec.conf, set alert level >= 10
2. Phone/SMS: bridge via PagerDuty, OpsGenie, or Shuffle → Twilio
3. Rocket.Chat: configure incoming webhook in Wazuh or Shuffle
4. Test all channels with ossec-logtest

# Set ILM Retention Policies
1. Identify longest requirement (HIPAA = 6 years)
2. Create ILM policy: hot 7d → warm 30d → cold → delete at limit
3. Apply to wazuh-alerts-* and wazuh-archives-* templates
4. Size storage at ~1 GB/day per 100 agents
5. Configure S3 or NFS snapshot repo for cold storage
6. Document policy for audit evidence

Fleet — Query- & Inventarschicht

  • Verwaltet osquery über alle Endpunkte hinweg — Server, Workstations und Cloud-Instanzen
  • Gibt Auditoren einen abfragbaren Datensatz des Systemzustands über die Zeit, keine Momentaufnahme
  • WireGuard-Add-on — kombinieren Sie Fleet mit WireGuard, um die Präsenz eines VPN-Tunnels als Fleet-Policy durchzusetzen; osquery kann verifizieren, dass die WireGuard-Schnittstelle auf jedem eingebundenen Gerät aktiv ist, bevor Zugriff auf interne Ressourcen gewährt wird
▶ show code
# Setup Steps
# Stand up Fleet + osquery
1. Deploy Fleet with MySQL + Redis backend (or Docker preview)
2. Configure TLS with Let's Encrypt or internal CA
3. Generate and distribute enroll secret via MDM
4. Confirm all hosts appear in Fleet UI within 5 minutes
5. Set agent update channel to stable with auto-update enabled

# Configure Fleet → Filebeat → Wazuh pipeline
1. Install Filebeat on the Fleet host (not the Wazuh server)
2. Point Filebeat input at Fleet's log output directory
3. Enable and configure the Wazuh Filebeat module
4. Test output: filebeat test output
5. Verify Fleet events appear in Wazuh Discover

# Schedule Fleet Compliance Queries
1. SELECT * FROM disk_encryption; — every 24h
2. SELECT username, uid, shell FROM users WHERE uid >= 1000; — every 12h
3. SELECT name, version, source FROM software; — every 24h
4. SELECT * FROM authorized_keys; — every 6h on servers
5. Create pass/fail Fleet Policies for FileVault/BitLocker status
6. Route query results through Fleet log pipeline → Filebeat → Wazuh
▶ show code
# Fleet result log configuration
# fleet.yml — result log configuration
logging:
  result:
    plugin: filesystem
    config:
      result_log_file: /var/log/fleet/osquery_results.log
  status:
    plugin: filesystem
    config:
      status_log_file: /var/log/fleet/osquery_status.log

# Filebeat — forward Fleet logs to Wazuh
# filebeat.yml
filebeat.inputs:
  - type: log
    enabled: true
    paths:
      - /var/log/fleet/osquery_results.log
    fields:
      source: fleet-osquery
      compliance: true

output.logstash:
  hosts: ["wazuh-manager:5044"]
  ssl.certificate_authorities: ["/etc/filebeat/wazuh-ca.pem"]

OpenEDR — Verhaltensbasierte Erkennungsschicht

  • Kontinuierliches Verhaltensmonitoring für Prozessbäume, Muster beim Zugriff auf Anmeldedaten, laterale Bewegung und Dateisystem-Anomalien
  • Telemetrie, modelliert nach dem MITRE-ATT&CK-Framework

Stellen Sie den Wazuh-Agent zusammen mit OpenEDR auf jedem Endpunkt bereit. Konfigurieren Sie den Agent so, dass er die JSON-Telemetrie von OpenEDR direkt liest, und ordnen Sie dann MITRE-ATT&CK-Kategorien Compliance-Control-Gruppen zu.

▶ show code
<!-- Wazuh agent — read OpenEDR telemetry and Windows Security Event Log -->
<!-- ossec.conf — on each endpoint -->
<ossec_config>
  <localfile>
    <log_format>json</log_format>
    <location>C:\ProgramData\OpenEDR\Logs\*.json</location>
    <label key="source">openedr</label>
  </localfile>
  <!-- Windows Security Event Log for HIPAA audit trail -->
  <localfile>
    <log_format>eventchannel</log_format>
    <location>Security</location>
  </localfile>
</ossec_config>

<!-- Wazuh rules — MITRE ATT&CK credential access detection -->
<!-- openedr_rules.xml -->
<group name="openedr,mitre,">
  <rule id="91001" level="12">
    <decoded_as>json</decoded_as>
    <field name="source">openedr</field>
    <field name="threat.type">credential_access</field>
    <description>OpenEDR: Credential access attempt detected</description>
    <mitre><id>T1003</id></mitre>
    <group>pci_dss_10.6.1,hipaa_164.312.b,</group>
  </rule>
</group>

Fail2ban — Aktive Reaktionsschicht

  • Überwacht Log-Dateien auf wiederholte Authentifizierungsfehler und sperrt betroffene IPs automatisch über Firewall-Regeln
  • Erzeugt den unveränderlichen Audit-Trail automatisierter Reaktionen, den PCI DSS Req. 10 und SOC 2 CC7 verlangen
▶ show code
# Setup Steps
1. Install on all internet-facing servers
2. Copy jail.conf → jail.local; enable sshd and nginx-http-auth jails
3. Set bantime = 1h, findtime = 10m, maxretry = 5
4. Configure JSON log output for Wazuh ingestion
5. Add Wazuh FIM watch on /etc/fail2ban/
6. Add active-response block in ossec.conf on rule 30105
7. Test: 5 bad SSH attempts → confirm ban + Wazuh alert fires

Wazuh löst Fail2ban aus (aktive Reaktion): Wazuh erkennt Brute-Force-Muster über SSH, RDP, Webanwendungen und fehlgeschlagene Keycloak-Logins hinweg und ruft dann Fail2ban auf, um die Quell-IP zu sperren:

▶ show code
<!-- Wazuh active response configuration -->
<!-- ossec.conf — on Wazuh Manager -->
<ossec_config>
  <active-response>
    <command>fail2ban</command>
    <location>local</location>
    <rules_id>5763,5764,92002</rules_id>  <!-- SSH brute force + Keycloak brute force -->
    <timeout>3600</timeout>
  </active-response>
</ossec_config>

#!/bin/bash
# /var/ossec/active-response/bin/fail2ban.sh
ACTION=$1
USER=$2
IP=$3

if [ "$ACTION" = "add" ]; then
  fail2ban-client set wazuh-response banip "$IP"
elif [ "$ACTION" = "delete" ]; then
  fail2ban-client set wazuh-response unbanip "$IP"
fi

# /etc/fail2ban/jail.d/wazuh-response.conf
[wazuh-response]
enabled = true
banaction = iptables-multiport
port = all
filter =
logpath = /var/log/wazuh-response.log
maxretry = 1
bantime = 3600

Fail2ban-Logs fließen in Wazuh ein (Audit-Trail): Jede Sperrung und Entsperrung wird zu einem Wazuh-Ereignis — das einen unveränderlichen Datensatz automatisierter Reaktionen für PCI DSS Req. 10.2 und SOC 2 CC7 erzeugt:

▶ show code
<!-- Fail2ban log ingestion and audit rules -->
<!-- ossec.conf — Fail2ban log ingestion -->
<ossec_config>
  <localfile>
    <log_format>syslog</log_format>
    <location>/var/log/fail2ban.log</location>
    <label key="source">fail2ban</label>
  </localfile>
</ossec_config>

<!-- fail2ban_rules.xml -->
<group name="fail2ban,">
  <rule id="93001" level="8">
    <decoded_as>fail2ban</decoded_as>
    <match>Ban</match>
    <description>Fail2ban: IP banned after repeated failures</description>
    <group>pci_dss_10.2.4,pci_dss_10.6.1,soc2_cc7.2,</group>
  </rule>
  <rule id="93002" level="6">
    <decoded_as>fail2ban</decoded_as>
    <match>Unban</match>
    <description>Fail2ban: IP ban expired and lifted</description>
    <group>pci_dss_10.2.4,</group>
  </rule>
</group>

Das Ergebnis ist ein geschlossener Kreislauf: Wazuh erkennt → Fail2ban blockiert → Fail2ban protokolliert die Aktion → Wazuh erfasst sie als Compliance-Ereignis mit vollständigem Zeitstempel und IP.


MXToolbox — E-Mail- & Domain-Sicherheit

  • Passives Monitoring der E-Mail-Domain-Gesundheit — verifiziert SPF-, DKIM- und DMARC-Einträge fortlaufend
  • Ein falsch konfiguriertes DMARC oder eine geblacklistete IP kann Domain-Spoofing ermöglichen oder zu fehlgeschlagenen Breach-Benachrichtigungen führen
▶ show code
# Setup Steps
1. Add blacklist monitors for all outbound mail server IPs
2. Add DNS monitors for SPF, DKIM, DMARC health on all sending domains
3. Add MX record monitors to detect tampering
4. Route MXToolbox webhooks into Shuffle → Wazuh for centralized logging

Falco — Laufzeit-Verhaltenserkennungsschicht

  • eBPF-basiertes Abfangen von Syscalls — erkennt Bedrohungen auf Kernel-Ebene, ohne dass Agents den Endpunkt-Code verändern
  • Schließt die Lücke, die OpenEDR auf Linux-Servern und Containern lässt, wo Windows-EDR-Agents nicht greifen

Stellen Sie Falco auf jedem Linux-Endpunkt für eBPF-basierte Laufzeit-Verhaltenserkennung bereit. Falco fängt Systemaufrufe ab und ordnet Anomalien — von Web-Prozessen gestartete Shells, massenhafte Dateischreibvorgänge, Rechteausweitungen — MITRE-ATT&CK-Techniken zu und speist strukturierte JSON-Ereignisse direkt in Wazuh ein.

▶ show code
# Setup Steps
1.  Add the Falco apt repo and install: apt install -y falco
2.  Select eBPF driver at install — do not use kernel module on production hosts
3.  Install driver: falcoctl driver install --type ebpf
4.  Enable service: systemctl enable --now falco
5.  Set json_output: true in /etc/falco/falco.yaml
6.  Configure file output to /var/log/falco/falco.json
7.  Add custom rules to falco_rules.local.yaml (mass file writes, shells from web processes)
8.  Add Wazuh <localfile> block to tail /var/log/falco/falco.json
9.  Restart Wazuh agent and confirm Falco events appear in Wazuh Discover
10. Add custom Falco decoder and rules in local_rules.xml on the Wazuh manager

Shuffle — SOAR- & Automatisierungsschicht

  • Verbindet Wazuh, Fleet, Keycloak, Fail2ban und Rocket.Chat zu automatisierten Reaktions-Workflows
  • Jede automatisierte Aktion wird als zeitgestempelte Workflow-Ausführung protokolliert — und liefert damit den Reaktions-Audit-Trail, den Auditoren verlangen

Stellen Sie Shuffle SOAR bereit, um Triage, Anreicherung und Reaktion über den gesamten Stack hinweg zu automatisieren. Wazuh-Alarme lösen Shuffle-Workflows aus, die Fleet nach Host-Kontext abfragen, die aktive Reaktion von Wazuh aufrufen, um IPs zu blockieren, und Rocket.Chat mit angereicherten Incident-Details benachrichtigen.

▶ show code
# Setup Steps
1.  Provision dedicated host: 2 vCPU / 4 GB RAM / 20 GB disk
2.  Install Docker + Compose: curl -fsSL https://get.docker.com | sh
3.  Clone Shuffle repo, set OUTER_HOSTNAME in docker-compose.yml, run docker compose up -d
4.  Restrict login to Keycloak OIDC immediately after first launch
5.  Install the Wazuh and HTTP apps from the Shuffle app library
6.  Configure Wazuh app with manager URL and a least-privilege API user
7.  Create a Webhook trigger in Shuffle and copy the hook URL
8.  Add the Shuffle <integration> block to Wazuh ossec.conf with the webhook URL
9.  Restart Wazuh manager and confirm test alerts arrive in Shuffle → Executions
10. Build triage playbook: parse alert level → if >= 12, call Wazuh active response → notify Rocket.Chat
11. Build Falco playbook: filter on falco rule group → enrich via Fleet/osquery → alert with host + process context
12. Build FIM rollback playbook: filter on rule 550/554 → SSH to agent → trigger restic/VSS restore → notify
13. Test each playbook end-to-end with ossec-logtest synthetic alerts
14. Set execution history retention to 30 days in Shuffle Settings

Alarmierungs-Konfiguration

Leiten Sie Wazuh-Alarme nach Schweregrad weiter, damit das richtige Team zur richtigen Zeit benachrichtigt wird:

SchweregradZielAuslösebedingungen
Level 12+ (kritisch)E-Mail + TelefonAktive Bedrohungen, Zugriff auf Anmeldedaten, Richtlinienverstoß
Level 8–11 (hoch)Rocket.Chat #securityNeue Admin-Konten, Ausbrüche fehlgeschlagener Logins, Konfigurationsdrift
Wöchentliche ZusammenfassungE-MailCompliance-Erfolgs-/Fehlerquoten und Alarmtrends
Export vor dem AuditPDFWazuh-Compliance-Dashboards exportieren direkt für SOC-2-/PCI-Nachweispakete

Von diesem Stack abgedeckte Sicherheits-Frameworks

  • NIST Five FunctionsPriorität: Kritisch. Das strategische Framework, das den gesamten Lebenszyklus der Netzwerk- und Serververteidigung organisiert. Jedes Tool in diesem Stack ordnet sich direkt einer oder mehreren der fünf Funktionen zu: Identify (Fleet, Keycloak), Protect (Fail2ban, WireGuard), Detect (Wazuh, OpenEDR, Falco), Respond (Shuffle, Fail2ban) und Recover (Wazuh-Playbooks, Shuffle-Workflows).
  • CWE — Die Abdeckung der Common Weakness Enumeration wird durch die verhaltensbasierte Erkennung von OpenEDR und die Regelbibliothek von Wazuh adressiert, die bekannte Schwachstellenmuster (Injection, Rechteausweitung, unsachgemäße Authentifizierung) auf Prozess- und Log-Ebene aufdeckt.
  • CIS Docker BenchmarksPriorität: Hoch. Der Goldstandard zur Härtung der containerisierten Serverumgebungen, in denen moderne Apps laufen. Wazuh liefert CIS-Docker-Benchmark-Audit-Regeln von Haus aus mit; Fleet-osquery-Policies können die Benchmark-Konformität fortlaufend über jeden Host hinweg verifizieren, auf dem Container laufen.

Fragen von Auditoren beantworten

„Zeigen Sie mir Ihr Zugriffskontroll-Monitoring." Exportieren Sie das Wazuh-SOC-2-CC6-Dashboard. Die Fleet-Abfragehistorie zeigt den Nutzerkonto-Status jedes Hosts über den gesamten Audit-Zeitraum. Die Keycloak-Admin-Ereignisprotokolle zeigen jede Rechtevergabe und jeden Rechteentzug.

„Zeigen Sie mir Ihre Fähigkeit zur Incident-Erkennung." Die MITRE-ATT&CK-Abdeckungskarte von OpenEDR kombiniert mit den Wazuh-Regelstatistiken demonstriert aktive Erkennung über die gesamte Angriffsfläche hinweg. Die Fail2ban-Sperrprotokolle zeigen die automatisierte Reaktion auf aktive Brute-Force-Versuche.

„Gab es während des Audit-Zeitraums Sicherheitsvorfälle?" Die Alarmhistorie von Wazuh liefert einen vollständigen, zeitgestempelten, unveränderlichen Datensatz. Vorhandene Incidents bedeuten, dass Ihr Erkennungs- und Reaktionsprozess wie vorgesehen funktioniert hat.

„Wie erkennen Sie nicht autorisierte Software-Änderungen?" Die Software-Inventarabfragen von Fleet und das File Integrity Monitoring (FIM) von Wazuh liefern einen fortlaufenden Datensatz darüber, was wann auf welchem Host installiert wurde.

„Wie setzen Sie MFA durch und verwalten den Nutzerzugriff?" Keycloak erzwingt MFA auf der Identitätsschicht für alle internen Dienste. Seine Audit-Logs, von Wazuh aufgenommen, liefern einen zeitgestempelten Datensatz jedes Authentifizierungsereignisses und jeder Admin-Änderung.

Diese Architektur skaliert von einem Startup mit 50 Endpunkten, das SOC 2 Type I anstrebt, bis zu einem Unternehmen mit 10.000 Endpunkten, das eine PCI-DSS-Zertifizierung aufrechterhält. Das Open-Source-Fundament hält die Lizenzkosten nahe null, und das modulare Design erlaubt es, kommerzielle EDR-Feeds, Cloud-Sicherheitslogs oder Netzwerküberwachung hinzuzufügen, ohne die Kern-Pipeline zu ersetzen.

Kontakt aufnehmen

Interesse an einem Thema? Hinterlassen Sie eine Nachricht und wählen Sie eine Kategorie. Ich stehe auch für ein kostenloses Beratungsgespräch zur Verfügung — melden Sie sich und wir vereinbaren etwas.