Docker contenedores Wazuh seguridad monitoring FIM logs Ciberseguridad

Cómo monitorizar un servidor con Docker y sus contenedores con Wazuh

Guía técnica paso a paso: configura Wazuh para monitorizar el host Docker y sus contenedores. Docker Listener, logs de contenedores, FIM, alertas reales y detección de docker exec sospechoso.

AI Security
12 min lectura
Background

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 contenedor
  • exec_create, exec_start — comandos ejecutados dentro de un contenedor
  • pull, push, tag, delete — operaciones sobre imágenes
  • connect, disconnect — cambios de red
  • commit, 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 IDNivelEvento
879013Contenedor creado
879033Contenedor iniciado
879043Contenedor detenido
879075Comando ejecutado dentro de un contenedor
879115Contenedor eliminado con kill
879123Imagen Docker descargada (pull)
879185Contenedor 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í.

Background