Si tienes un servidor Linux con Docker, Wazuh puede monitorizar tanto el host como cada contenedor que corre en él. En esta guía verás exactamente qué configurar, qué alertas se generan y cómo detectar un acceso interactivo sospechoso a un contenedor.
¿Qué puede monitorizar Wazuh en un servidor con Docker?
Cuando instalas el agente Wazuh en el host Linux donde corre Docker, tienes cuatro capas de visibilidad:
- Eventos de la API Docker (inicio, parada, exec, pull de imágenes…) mediante el módulo
docker-listener - Logs de los contenedores recogidos desde el filesystem del host
- Integridad de archivos (FIM) sobre la configuración de Docker:
/etc/docker, socket, binarios - Vulnerabilidades en imágenes mediante integración con Trivy o Grype
Todo ello sin necesidad de instalar ningún agente dentro de los contenedores.
Requisitos previos
- Wazuh Manager 4.7 o superior
- Agente Wazuh instalado en el host Linux con Docker
- Docker Engine instalado
- Python 3.8–3.12 en el host
Paso 1: Instalar las dependencias Python del wodle
El módulo docker-listener es un script Python que usa la librería docker para conectarse a la API del daemon. Sin este paso el wodle no arranca. Las versiones exactas importan:
En Python 3.8–3.10:
pip3 install docker==7.1.0 urllib3==1.26.20 requests==2.32.2 En Python 3.11–3.12 (sistemas con entorno gestionado, como Ubuntu 23+):
pip3 install docker==7.1.0 urllib3==1.26.20 requests==2.32.2 --break-system-packages Verifica que la instalación funciona:
python3 -c "import docker; c = docker.from_env(); print(c.ping())"
# Debe devolver: True Paso 2: Dar acceso al socket Docker al usuario wazuh
El wodle corre con el usuario wazuh. Para que pueda acceder al socket de Docker:
sudo usermod -aG docker wazuh Aplica el cambio de grupo sin reiniciar:
sudo systemctl restart wazuh-agent Paso 3: Habilitar el Docker Listener (wodle)
El módulo docker-listener se conecta a la API de Docker y captura en tiempo real todos los eventos del daemon: creación de contenedores, arranques, paradas, ejecución de comandos, pulls de imágenes, conexiones de red, etc.
Añade esto en /var/ossec/etc/ossec.conf del agente:
<wodle name="docker-listener">
<interval>10m</interval>
<attempts>5</attempts>
<run_on_start>yes</run_on_start>
<disabled>no</disabled>
</wodle> Una vez activo, este módulo captura eventos como:
create,start,stop,die,destroy— ciclo de vida del contenedorexec_create,exec_start— comandos ejecutados dentro de un contenedorpull,push,tag,delete— operaciones sobre imágenesconnect,disconnect— cambios de redcommit,export— operaciones que generan nuevas imágenes
Las reglas de Wazuh para estos eventos están en /var/ossec/ruleset/rules/0560-docker_integration_rules.xml (IDs 87901–87920).
Paso 4: Recoger los logs de los contenedores
Docker, con el driver por defecto (json-file), almacena los logs de cada contenedor en:
/var/lib/docker/containers/<ID_CONTENEDOR>/<ID_CONTENEDOR>-json.log Añade este bloque en ossec.conf para que Wazuh los lea:
<localfile>
<log_format>syslog</log_format>
<location>/var/lib/docker/containers/*/*-json.log</location>
</localfile> Usa log_format syslog aunque los archivos sean JSON. Wazuh leerá cada línea completa y los decoders extraerán los campos. Si usas log_format json, el parser intentará interpretar el wrapper de Docker (que tiene campos log, stream y time) y puede fallar con el contenido real del log.
Si en tu entorno los contenedores usan el driver journald, la configuración cambia:
<localfile>
<log_format>journald</log_format>
<location>journald</location>
</localfile> Paso 5: FIM sobre la configuración de Docker
El módulo de integridad de archivos (syscheck) debe monitorizar los archivos de configuración de Docker, pero no el directorio /var/lib/docker completo: puede ocupar cientos de GB y cambia constantemente con las capas de overlay2, generando miles de alertas falsas.
Configuración recomendada en el agente:
<syscheck>
<!-- Configuración del daemon Docker -->
<directories realtime="yes" check_all="yes" report_changes="yes">/etc/docker</directories>
<!-- Socket Docker: detectar cambios de permisos -->
<directories realtime="yes" check_all="yes">/run/docker.sock</directories>
<!-- Binarios Docker -->
<directories check_all="yes">/usr/bin/docker</directories>
<directories check_all="yes">/lib/systemd/system/docker.service</directories>
<!-- Excluir directorios de datos (muy volátiles) -->
<ignore>/var/lib/docker/overlay2</ignore>
<ignore>/var/lib/docker/containers</ignore>
<ignore>/var/lib/docker/tmp</ignore>
</syscheck> Cualquier modificación a /etc/docker/daemon.json o cambio en los permisos del socket generará una alerta FIM en Wazuh.
Paso 6: Reiniciar el agente y verificar
# Reiniciar el agente
sudo systemctl restart wazuh-agent
# Ver que el wodle arranca sin errores
sudo tail -f /var/ossec/logs/ossec.log | grep docker Deberías ver algo como:
INFO: wazuh-modulesd:docker-listener: Module Docker Listener started.
INFO: wazuh-modulesd:docker-listener: Listening to Docker events. Alertas clave que verás en el dashboard
Con esta configuración, el dashboard de Wazuh mostrará alertas como estas:
| Rule ID | Nivel | Evento |
|---|---|---|
| 87901 | 3 | Contenedor creado |
| 87903 | 3 | Contenedor iniciado |
| 87904 | 3 | Contenedor detenido |
| 87907 | 5 | Comando ejecutado dentro de un contenedor |
| 87911 | 5 | Contenedor eliminado con kill |
| 87912 | 3 | Imagen Docker descargada (pull) |
| 87918 | 5 | Contenedor convertido en imagen (commit) |
Caso práctico: detectar un docker exec sospechoso
El evento más relevante para seguridad es cuando alguien ejecuta una shell interactiva dentro de un contenedor. Simúlalo así:
# Levantar un contenedor de prueba
docker run -d --name test_nginx nginx:latest
# Ejecutar una shell interactiva (esto es lo que queremos detectar)
docker exec -it test_nginx /bin/sh Wazuh captura dos eventos: exec_create y exec_start. El segundo dispara la regla 87907 con nivel 5. Para subirlo a nivel 12 y mapearlo a MITRE ATT&CK T1609, añade esta regla personalizada en /var/ossec/etc/rules/local_rules.xml del manager:
<group name="docker,shell_access">
<rule id="100110" level="12">
<if_sid>87907</if_sid>
<field name="docker.Action">exec_start: (/bin/sh|/bin/bash|/bin/zsh|sh|bash)</field>
<description>Docker: Shell interactiva lanzada en contenedor $(docker.Actor.Attributes.name)</description>
<options>no_full_log</options>
<group>docker_shell,attack,T1609</group>
</rule>
<!-- Contenedor privilegiado: riesgo de escape al host -->
<rule id="100111" level="14">
<if_sid>87901</if_sid>
<field name="docker.Actor.Attributes.privileged">true</field>
<description>Docker: Contenedor privilegiado creado - $(docker.Actor.Attributes.name)</description>
<group>docker_privileged,pci_dss_10.6.1</group>
</rule>
</group> Aplica los cambios en el manager:
sudo /var/ossec/bin/wazuh-logtest # verificar que la regla no tiene errores
sudo systemctl restart wazuh-manager Extra: SCA Docker CIS Benchmark
Wazuh no incluye por defecto la política Docker CIS en su instalación estándar (a diferencia de las políticas para Ubuntu o RHEL), pero puedes añadirla manualmente. El blog oficial de Wazuh publica un fichero YAML con los 98 controles del CIS Docker Benchmark v1.7.0.
Una vez tengas el fichero cis_docker_bench.yml, actívalo en ossec.conf del agente:
<sca>
<enabled>yes</enabled>
<scan_on_start>yes</scan_on_start>
<interval>12h</interval>
<skip_nfs>yes</skip_nfs>
<policies>
<policy>/var/ossec/etc/sca/cis_docker_bench.yml</policy>
</policies>
</sca> Esto comprobará cosas como: si los contenedores se ejecutan como root, si el rootfs es de solo lectura, si se montan volúmenes sensibles del host, o si el socket Docker está expuesto dentro de algún contenedor.
Extra: Escaneo de vulnerabilidades en imágenes con Trivy
El módulo vulnerability-detection de Wazuh analiza paquetes del SO del agente, pero no las capas internas de las imágenes Docker. Para eso se integra con Trivy:
# Instalar Trivy en el host
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | \
gpg --dearmor | sudo tee /usr/share/keyrings/trivy.gpg > /dev/null
echo "deb [signed-by=/usr/share/keyrings/trivy.gpg] \
https://aquasecurity.github.io/trivy-repo/deb generic main" | \
sudo tee /etc/apt/sources.list.d/trivy.list
sudo apt-get update && sudo apt-get install trivy
# Escanear una imagen manualmente
trivy image nginx:latest Luego puedes usar el wodle command para ejecutar Trivy periódicamente y enviar los resultados a Wazuh como eventos, donde reglas personalizadas los convertirán en alertas de nivel 7 (HIGH) o 12 (CRITICAL).
Configuración completa del agente
Resumen de todos los bloques que añades en /var/ossec/etc/ossec.conf del host Docker:
<!-- 1. Docker Listener -->
<wodle name="docker-listener">
<interval>10m</interval>
<attempts>5</attempts>
<run_on_start>yes</run_on_start>
<disabled>no</disabled>
</wodle>
<!-- 2. Logs de contenedores -->
<localfile>
<log_format>syslog</log_format>
<location>/var/lib/docker/containers/*/*-json.log</location>
</localfile>
<!-- 3. FIM -->
<syscheck>
<directories realtime="yes" check_all="yes" report_changes="yes">/etc/docker</directories>
<directories realtime="yes" check_all="yes">/run/docker.sock</directories>
<directories check_all="yes">/usr/bin/docker</directories>
<ignore>/var/lib/docker/overlay2</ignore>
<ignore>/var/lib/docker/containers</ignore>
<ignore>/var/lib/docker/tmp</ignore>
</syscheck> Conclusión
Con esta configuración tienes visibilidad completa sobre tu servidor Docker: eventos en tiempo real de la API, logs centralizados de todos los contenedores, alertas ante cualquier modificación de la configuración del daemon, y detección inmediata de accesos interactivos sospechosos. Sin ningún agente dentro de los contenedores.
Si además añades Trivy y la política SCA Docker CIS, cubres también las vulnerabilidades en imágenes y las malas configuraciones antes de que lleguen a producción.
¿Tienes Docker en producción y quieres revisar cómo está configurado Wazuh en tu entorno? Solicita una consulta gratuita y lo revisamos juntos.
¿Necesitas implementar esta solución? Solicita una consulta gratuita aquí.