Files
lxc-enroll/docker-security/README.md
T

199 lines
11 KiB
Markdown

# Docker Security fuer Wazuh
Ein eigenstaendiges Skript fuer **Debian-/Ubuntu-Docker-Hosts mit systemd**:
LXC, VM oder physischer Server. Die Dialogoberflaeche fragt nach Docker Listener,
regelmaessigen Image-Scans, Scanabstand und Einbeziehung gestoppter Container.
Ohne whiptail/dialog wird die Texteingabe verwendet. Vor Aenderungen ist `INSTALL`
erforderlich. Im Gegensatz zum LXC-Enrollment wird es direkt auf dem Docker-Host
ausgefuehrt und braucht keinen Proxmox-Host.
## Voraussetzungen
- Root, Python >= 3.9, Debian oder Ubuntu mit APT/systemd.
- Im Host-Modus: **Docker bereits installiert und lokal erreichbar** ueber
`/var/run/docker.sock`; nativer Wazuh-Agent bereits installiert und verbunden.
- Im Manager-Modus: nativer Wazuh-Manager. Kein Docker erforderlich.
- Zugriff auf offizielle APT-/PyPI-Quellen, Trivy-Datenbanken und CISA KEV.
Docker und Wazuh werden weder neu installiert noch registriert. Falls der Agent
fehlt, zuerst das vorhandene Enrollment-Skript verwenden. Rootless Docker,
Remote-Docker, Podman, Windows und Container mit einem darin laufenden Wazuh-Agent
sind nicht enthalten. Keine Container-Neustarts, Image-Pulls oder automatischen
Container-Updates. Der Agent bzw. Manager wird fuer seine neue Konfiguration
neu gestartet.
## 1. Einmal auf dem Wazuh-Manager
Direkt in dessen Konsole als root:
```bash
curl -fsSL https://code.faboi.cloud/fabio/lxc-enroll/raw/branch/main/docker-security.sh \
-o /run/docker-security.sh && bash /run/docker-security.sh --manager-rules
```
Das Skript ergaenzt `/var/ossec/etc/rules/docker_security_rules.xml`. Der vorhandene
JSON-Decoder wird genutzt. Keine neuen Decoder oder Discord-Webhook-Daten erforderlich.
Regel-ID-Kollisionen werden erkannt; vorhandene fremde Dateien werden nicht
ueberschrieben. `wazuh-analysisd -t` muss bestehen, bevor der Manager neu startet.
Bei Validierungs-/Neustartfehlern wird die vorherige Regeldatei wiederhergestellt.
## 2. Auf jedem Docker-Host
Direkt im LXC / in der VM / auf dem Server, der Docker betreibt:
```bash
curl -fsSL https://code.faboi.cloud/fabio/lxc-enroll/raw/branch/main/docker-security.sh \
-o /run/docker-security.sh && bash /run/docker-security.sh
```
Nur Voraussetzungen pruefen:
```bash
bash /run/docker-security.sh --check
```
Der offizielle Wazuh Docker Listener bekommt eine eigene Python-Umgebung unter
`/opt/wazuh-docker-security/listener-venv`. System-Python bleibt unveraendert.
Die offizielle Listener-Datei bekommt einen passenden Python-Interpreter in
der ersten Zeile. Ein unerwarteter Wrapper wird zur manuellen Pruefung abgelehnt.
Bei einem Wazuh-Paketupgrade kann diese Anpassung ueberschrieben werden;
anschliessend die Einrichtung erneut ausfuehren. Fuer Docker-Ereignisse gelten
weiterhin die eingebauten Wazuh-Docker-Regeln. Sie beweisen fuer sich allein
keinen erfolgreichen Angriff.
Fehlendes Trivy wird in Version **0.75.0** aus dem signierten offiziellen
APT-Repository installiert. Ein bereits installiertes APT-Paket ab Version
0.70.0 bleibt erhalten; aeltere Pakete werden vor Ausfuehrung abgelehnt und
muessen separat aktualisiert werden. Die im Maerz 2026 betroffenen Versionen
0.69.4-0.69.6 werden dadurch nicht verwendet. Es wird kein fremdes Installations-
Shellskript aus dem Netz ausgefuehrt. Python-Abhaengigkeiten kommen von PyPI;
Docker SDK 7.1.0, Requests >= 2.32.4 und urllib3 >= 2.2.3 werden im Venv genutzt.
Die bestehenden Agent-Einstellungen werden erhalten. XML mit mehreren
`ossec_config`-Bloecken und Kommentare wird unterstuetzt. Docker Listener und
eine JSON-Logquelle werden gezielt ergaenzt; ein erneuter Lauf erzeugt keine
doppelten Bloecke. Vor dem Agent-Neustart werden Agent-, Logcollector- und
Modules-Konfigurationen geprueft. Sicherungen liegen privat unter
`/var/backups/wazuh-docker-security/`. Bei Fehlern vor erfolgreichem Agent-
Neustart werden die Agent-Konfiguration und der angepasste Listener zurueckgesetzt.
Pakete und neu angelegte Scanner-Dateien werden nicht automatisch deinstalliert.
## Scans und Meldungen
Standard: Images **laufender Container**, alle **24 Stunden**, ein Image pro
Scan auch bei mehreren Containern mit diesem Image. Gestoppte Container koennen
zusaetzlich ausgewaehlt werden. Ungenutzte Images werden nicht gescannt.
Die erste Pruefung kann sofort im Hintergrund starten. Nach einem Neustart
startet der Timer wieder im gewaehlten Stundenabstand. Ein unmittelbarer erster
Scan startet nur bei Zustimmung; der Timer streut die Termine um bis zu zehn
Minuten. Datenbank-Downloads beim ersten Scan koennen dauern.
Gescannt werden die **tatsaechlichen lokalen Image-IDs**, ohne Registry-Fallback
oder Image-Pull. Ergebnisse enthalten erkannte High-/Critical-Schwachstellen
**auch ohne verfuegbaren Fix** sowie niedrigere Schweregrade, wenn die CVE im
CISA-KEV-Katalog steht. Das ist keine automatische Aussage ueber Ausnutzbarkeit
in der konkreten Anwendung. CISA KEV belegt bekannte Ausnutzung andernorts;
es belegt keinen Angriff auf diesen Host. Eine fehlende KEV-Zuordnung ist
keine Entwarnung und der Katalog ist keine vollstaendige Liste aller Exploits.
Unveraenderte Befunde werden bei regulaeren Folgescans nicht erneut in das
Event-Log geschrieben. Aenderungen an Schweregrad, Fix-Verfuegbarkeit, installierter
Version oder KEV-Status erzeugen ein neues Ereignis. Ein reiner Wechsel des
Image-Digests fuer denselben Containernamen wiederholt keine unveraenderte CVE.
Fehlgeschlagene Scans behalten bisherige Funde bei. Aus dem Scanumfang entfernte
Container werden als `out_of_scope` behandelt, nicht als behoben. Ein Scanner-
Problem wird beim Auftreten bzw. bei einer Aenderung gemeldet, statt jeden Lauf
erneut. Die komplette aktuelle relevante Inventarliste bleibt lokal verfuegbar.
| Gruppe / ID | Bedeutung | Level |
|---|---|---|
| `docker_security_review` / 110801 | Neuer/geaenderter High-/Critical-Fund zur Pruefung | 4 |
| `docker_security_kev` / 110802 | Erkannter Fund einer CVE in CISA KEV; priorisiert pruefen/mitigieren | 12 |
| `docker_security_health` / 110803 | Neue/geaenderte Scanner-Probleme | 7 |
| 110804 / 110805 | Fund verschwunden/ausserhalb Umfang oder Scanner erholt; nur Inventarstatus | 3 |
| 110806 | Status jedes abgeschlossenen Scans; nur Inventarstatus | 3 |
**Discord wird nicht neu eingerichtet.** Bestehende Wazuh-Integrationen koennen
je nach ihren Filtern bereits passende Level/Gruppen weiterleiten. Fuer Fabios
Ziel „nur wenn ich handeln muss“ muessen die Discord-Regeln anschliessend gezielt
auf relevante Sicherheitsereignisse zugeschnitten werden. Eine hohe CVSS-
Einstufung allein reicht nicht als Nachweis konkreter Ausnutzbarkeit. Fuer
Angriffserkennung sind zusaetzlich passende Anwendungslogs und ggf. Runtime-
Erkennung erforderlich; der Image-Scanner ersetzt diese nicht.
## Ergebnis pruefen
Auf dem Docker-Host:
```bash
systemctl status wazuh-docker-security.service --no-pager -l
journalctl -u wazuh-docker-security.service -n 30 --no-pager
systemctl list-timers wazuh-docker-security.timer
python3 -m json.tool /var/lib/wazuh-docker-security/inventory.json
```
Ein beendeter erfolgreicher `oneshot`-Dienst ist normalerweise **inactive (dead)**;
entscheidend ist der letzte Exitstatus und der naechste Timer-Termin.
Bei einem Fehler zeigt die Inventardatei `problems` bzw. `complete: false`.
In Wazuh **Explore / Discover**, Index `wazuh-alerts-*`:
```text
rule.groups:docker_security
```
Review-Hinweise stehen im Alert-Index, **nicht automatisch im nativen
Vulnerability-Detection-Inventar**. Behoebene/out-of-scope Ereignisse Level 0
erscheinen nicht als normale Alerts. Docker-Ereignisse des Listeners sind
unter `rule.groups:docker` sichtbar. End-to-end-Empfang muss nach der ersten
Einrichtung dort geprueft werden; ein aktiver Agent allein beweist ihn nicht.
Dateien: `/opt/wazuh-docker-security/scan.py`,
`/etc/wazuh-docker-security/config.json`,
`/var/lib/wazuh-docker-security/{inventory,state,kev}.json`,
`/var/log/wazuh-docker-security/events.jsonl`. Lokale Einzelreports werden
nach 30 Tagen ohne Aktualisierung entfernt, Event-Logs per Logrotate rotiert.
Caches koennen Speicher belegen; bei Bedarf nach einem Scan
`trivy clean --cache-dir /var/lib/wazuh-docker-security/cache --all` nutzen.
Timer deaktivieren: `systemctl disable --now wazuh-docker-security.timer`.
Fuer spaetere Aenderungen das Skript erneut ausfuehren. Die Wahl „Nein“ laesst
bereits eingerichtete Komponenten unveraendert; sie deinstalliert/deaktiviert
sie nicht. Ein laufender Scan wird durch den Timer-Stopp nicht beendet.
## Grenzen
- Image-Inhalt, nicht schreibbare Container-Layer, gemountete Anwendungen/Volumes
oder dynamisch nachinstallierte Pakete. Keine vollstaendige Exploit-Erkennung.
- OS-/Bibliotheksabdeckung haengt von Trivy und den verfuegbaren Advisories ab.
- KEV wird taeglich aktualisiert; bei Netzfehlern wird der Cache genutzt. Ist er
aelter als sieben Tage, werden negative Zuordnungen als unbekannt behandelt.
- Transport ist nicht exactly-once: nach einem harten Abbruch oder Log-Wieder-
einlesen durch Wazuh koennen Ereignisse erneut erscheinen. Normale Scan-
Wiederholungen sind lokal dedupliziert.
- Ein sehr grosser Docker-Host kann das Dienstlimit von vier Stunden erreichen.
- Ein echter Docker-/Wazuh-Lauf ist noch ausstehend. Lokal geprueft sind Syntax,
Konfigurationserhalt, Rule-ID-Kollisionen, Scan-Ausgabe und Fehler-/Dedup-Faelle.
## Offizielle Quellen
- [Wazuh Docker Listener](https://documentation.wazuh.com/current/user-manual/capabilities/container-security/monitoring-docker.html)
- [Wazuh und Trivy](https://wazuh.com/blog/container-image-security-with-wazuh-and-trivy/)
- [Wazuh JSON-Decoder](https://documentation.wazuh.com/current/user-manual/ruleset/decoders/json-decoder.html)
- [Trivy-Installation](https://trivy.dev/docs/latest/getting-started/installation/)
- [Trivy Image-Quellen](https://trivy.dev/docs/latest/guide/target/container_image/)
- [Aqua: Trivy-Vorfall Maerz 2026](https://www.aquasec.com/blog/trivy-supply-chain-attack-what-you-need-to-know/)
- [CISA KEV](https://www.cisa.gov/known-exploited-vulnerabilities-catalog)
## Katalogabruf und gezielte Benachrichtigungen
Wenn die CISA-Webseite mit 403 antwortet, wird der offizielle Spiegel unter
`github.com/cisagov/kev-data` genutzt. Anzahl, CVE-IDs und Veröffentlichungsdatum
werden geprüft; ein über 14 Tage alter Spiegel wird abgelehnt. Der Cache gilt
maximal sieben Tage als frisch. Ein fehlender Katalog bedeutet weiterhin
„unbekannt“, nicht „keine Ausnutzung“.
Scanner-Status, Behebungen und Erholungen werden als Level-3-Inventarereignisse
indexiert. Diese Ereignisse sind keine Discord-Benachrichtigungen. Eine separat und privat eingerichtete Benachrichtigungslogik kann aktuelle
OS-Schwachstellen sowie Image-Ereignisse und positive Malware-Erkennungen verarbeiten.