Retour au blog

Pile de conformité SOC 2 : Fleet, Wazuh et Keycloak pour les petites équipes

28 février 202610 min
Appareils et données

Ingénierie de sécurité · Plongée technique approfondie

Les référentiels de conformité en matière de sécurité existent pour répondre à une question inconfortable : pouvez-vous prouver que vos systèmes sont sécurisés ? Pas l'affirmer — le prouver avec des journaux, des alertes et des pistes d'audit qui résistent à l'examen d'un tiers.

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

La pile applicative

Keycloak — couche d'identité (couche 0)

  • Centralise l'authentification sur tous les appareils et serveurs via SSO, SAML et OIDC
  • Produit un journal d'audit complet de chaque connexion, émission de jeton et action d'administration

Pour un déploiement Keycloak entièrement géré sur PikaPods, voir Hébergement sans les tracas : faites tourner WordPress, Ghost et Keycloak sur PikaPods.

▶ 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 — moteur SIEM et de conformité

  • Ingère les journaux de pratiquement n'importe quelle source et applique des règles de corrélation pour détecter les menaces et les violations de politique
  • Les tableaux de bord de conformité associent chaque événement à des exigences de contrôle spécifiques — prêt pour l'audit sans semaines de travail manuel
▶ 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 — couche de requêtes et d'inventaire

  • Gère osquery sur tous les endpoints — serveurs, postes de travail et instances cloud
  • Donne aux auditeurs un enregistrement interrogeable de l'état du système dans le temps, pas un instantané ponctuel
  • Module complémentaire WireGuard — associez Fleet à WireGuard pour imposer la présence d'un tunnel VPN comme politique Fleet ; osquery peut vérifier que l'interface WireGuard est active sur chaque appareil enrôlé avant d'accorder l'accès aux ressources internes
▶ 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 — couche de détection comportementale

  • Surveillance comportementale continue des arbres de processus, des schémas d'accès aux identifiants, des mouvements latéraux et des anomalies du système de fichiers
  • Télémétrie modélisée sur le cadre MITRE ATT&CK

Déployez l'agent Wazuh aux côtés d'OpenEDR sur chaque endpoint. Configurez l'agent pour lire directement la télémétrie JSON d'OpenEDR, puis associez les catégories MITRE ATT&CK aux groupes de contrôle de conformité.

▶ 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 — couche de réponse active

  • Surveille les fichiers journaux à la recherche d'échecs d'authentification répétés et bannit automatiquement les IP fautives via des règles de pare-feu
  • Produit la piste d'audit immuable de réponse automatisée exigée par PCI DSS Req. 10 et SOC 2 CC7
▶ 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 déclenche Fail2ban (réponse active) : Wazuh détecte des schémas de force brute sur SSH, RDP, les applications web et les échecs de connexion Keycloak, puis appelle Fail2ban pour bannir l'IP source :

▶ 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

Les journaux de Fail2ban alimentent Wazuh (piste d'audit) : chaque bannissement et levée de bannissement devient un événement Wazuh — créant un enregistrement immuable des réponses automatisées pour PCI DSS Req. 10.2 et SOC 2 CC7 :

▶ 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>

Le résultat est une boucle fermée : Wazuh détecte → Fail2ban bloque → Fail2ban journalise l'action → Wazuh l'enregistre comme un événement de conformité avec l'horodatage et l'IP complets.


MXToolbox — sécurité des e-mails et du domaine

  • Surveillance passive de la santé du domaine e-mail — vérifie en continu les enregistrements SPF, DKIM et DMARC
  • Un DMARC mal configuré ou une IP mise sur liste noire peut permettre l'usurpation de domaine ou provoquer des échecs de notification de violation
▶ 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 — couche de détection comportementale en temps réel

  • Interception d'appels système basée sur eBPF — détecte les menaces au niveau du noyau sans agents modifiant le code de l'endpoint
  • Comble le vide laissé par OpenEDR sur les serveurs Linux et les conteneurs, là où les agents EDR Windows ne s'appliquent pas

Déployez Falco sur chaque endpoint Linux pour une détection comportementale en temps réel basée sur eBPF. Falco intercepte les appels système et associe les anomalies — shells lancés depuis des processus web, écritures massives de fichiers, escalades de privilèges — à des techniques MITRE ATT&CK, en alimentant directement Wazuh avec des événements JSON structurés.

▶ 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 — couche SOAR et d'automatisation

  • Connecte Wazuh, Fleet, Keycloak, Fail2ban et Rocket.Chat en workflows de réponse automatisés
  • Chaque action automatisée est journalisée comme une exécution de workflow horodatée — fournissant la piste d'audit de réponse exigée par les auditeurs

Déployez Shuffle SOAR pour automatiser le triage, l'enrichissement et la réponse sur l'ensemble de la pile. Les alertes Wazuh déclenchent des workflows Shuffle qui interrogent Fleet pour le contexte de l'hôte, appellent la réponse active de Wazuh pour bloquer des IP, et notifient Rocket.Chat avec des détails d'incident enrichis.

▶ 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

Configuration des alertes

Acheminez les alertes Wazuh par gravité pour garantir que la bonne équipe est notifiée au bon moment :

GravitéDestinationConditions de déclenchement
Niveau 12+ (critique)E-mail + téléphoneMenaces actives, accès aux identifiants, violation de politique
Niveau 8–11 (élevé)Rocket.Chat #securityNouveaux comptes admin, rafales d'échecs de connexion, dérive de configuration
Résumé hebdomadaireE-mailTaux de réussite/échec de conformité et tendances des alertes
Export pré-auditPDFLes tableaux de bord de conformité Wazuh s'exportent directement pour les dossiers de preuves SOC 2 / PCI

Référentiels de sécurité couverts par cette pile

  • Les cinq fonctions du NISTPriorité : critique. Le cadre stratégique utilisé pour organiser l'ensemble du cycle de vie de défense réseau et serveur. Chaque outil de cette pile s'associe directement à une ou plusieurs des cinq fonctions : Identifier (Fleet, Keycloak), Protéger (Fail2ban, WireGuard), Détecter (Wazuh, OpenEDR, Falco), Répondre (Shuffle, Fail2ban), et Récupérer (playbooks Wazuh, workflows Shuffle).
  • CWE — La couverture Common Weakness Enumeration est assurée par la détection comportementale d'OpenEDR et la bibliothèque de règles de Wazuh, qui signale les schémas de faiblesse connus (injection, escalade de privilèges, authentification incorrecte) au niveau du processus et du journal.
  • CIS Docker BenchmarksPriorité : élevée. La référence en matière de durcissement des environnements serveur conteneurisés où vivent les applications modernes. Wazuh fournit des règles d'audit CIS Docker Benchmark prêtes à l'emploi ; les politiques Fleet osquery peuvent vérifier en continu la conformité au benchmark sur chaque hôte exécutant des conteneurs.

Répondre aux questions des auditeurs

« Montrez-moi votre surveillance du contrôle d'accès. » Exportez le tableau de bord Wazuh SOC 2 CC6. L'historique des requêtes Fleet montre l'état du compte utilisateur de chaque hôte sur toute la période d'audit. Les journaux d'événements admin de Keycloak montrent chaque octroi et révocation de privilège.

« Montrez-moi votre capacité de détection d'incidents. » La carte de couverture MITRE ATT&CK d'OpenEDR combinée aux statistiques de règles de Wazuh démontre une détection active sur toute la surface d'attaque. Les journaux de bannissement de Fail2ban montrent la réponse automatisée aux tentatives actives de force brute.

« Y a-t-il eu des incidents de sécurité pendant la période d'audit ? » L'historique des alertes de Wazuh fournit un enregistrement complet, horodaté et immuable. La présence d'incidents signifie que votre processus de détection et de réponse a fonctionné comme prévu.

« Comment détectez-vous les changements logiciels non autorisés ? » Les requêtes d'inventaire logiciel de Fleet et la surveillance de l'intégrité des fichiers (FIM) de Wazuh fournissent un enregistrement continu de ce qui a été installé, quand, et sur quel hôte.

« Comment appliquez-vous le MFA et gérez-vous l'accès des utilisateurs ? » Keycloak applique le MFA au niveau de la couche d'identité pour tous les services internes. Ses journaux d'audit, ingérés par Wazuh, fournissent un enregistrement horodaté de chaque événement d'authentification et changement admin.

Cette architecture s'adapte d'une startup à 50 endpoints visant SOC 2 Type I à une entreprise à 10 000 endpoints maintenant une certification PCI DSS. La base open source maintient les coûts de licence proches de zéro, et la conception modulaire permet d'ajouter des flux EDR commerciaux, des journaux de sécurité cloud, ou une surveillance réseau sans remplacer le pipeline central.

Contactez-moi

Un sujet vous intéresse ? Laissez un mot et choisissez une catégorie. Je suis aussi disponible pour une réunion de conseil gratuite — écrivez-moi et nous organiserons cela.