Enterprise GitOps Modular Deployment for Wazuh 4.9.1
Wazuh Infrastructure es una implementación modular de Wazuh 4.9.1 sobre Docker Compose, diseñada bajo principios GitOps y validada en producción en un entorno de salud pública.
A diferencia del despliegue monolítico oficial, esta implementación desacopla cada componente en su propio archivo Compose, permitiendo ciclos de vida independientes, configuración declarativa en Git y reproductibilidad total desde cero.
El proyecto resuelve problemas reales documentados durante la implementación: incompatibilidades entre Filebeat 7.10.2 y OpenSearch 2.13, el gap de inicialización del Security Plugin en despliegues Docker, el comportamiento del IndexerConnector en arquitecturas modulares, y la gestión de certificados en contenedores sin entrypoint personalizado.
Internet
│
┌────┴────┐
│ Nginx │
└────┬────┘
│
┌──────────────┴──────────────┐
│ │
Wazuh Dashboard Wazuh Manager
(OpenSearch Dashboards) │
│ Filebeat (alerts)
│ IndexerConnector (states)
│ │
└──────────────┬──────────────┘
│
Wazuh Indexer
(OpenSearch 2.13)
Security Plugin
- Filebeat indexa alertas en
wazuh-alerts-4.x-*vía output Elasticsearch con compatibilidad OpenSearch activada. - IndexerConnector (módulo nativo C++ del manager) indexa estados de vulnerabilidades en
wazuh-states-vulnerabilities-*usando mTLS con certificados admin. - Security Plugin gestiona autenticación y autorización. Requiere bootstrap manual o por script en el primer despliegue.
wazuh-docker-modular/
├── compose/
│ ├── docker-compose.yml # Redes y volúmenes compartidos
│ └── core/
│ ├── wazuh-indexer.yml
│ ├── wazuh-manager.yml
│ └── wazuh-dashboard.yml
├── config/
│ ├── dashboard/
│ │ └── opensearch_dashboards.yml
│ ├── filebeat/
│ │ ├── filebeat.yml # Stub que satisface el init script
│ │ └── wazuh-template.json
│ ├── indexer/
│ │ └── opensearch.yml
│ └── wazuh/
│ └── ossec.conf
├── runtime/ # NO incluido en Git (.gitignore)
│ ├── certs/ # Certificados del indexer
│ └── manager-certs/ # Certificados del manager (renombrados)
├── scripts/
│ └── bootstrap/
│ ├── security-init.sh # Bootstrap del Security Plugin
│ └── README.md
├── docs/
│ ├── adr/ # Architecture Decision Records
│ ├── incidents/ # Incidentes documentados
│ ├── runbooks/ # Procedimientos operacionales
│ └── troubleshooting/ # Guías de resolución de problemas
├── .env.example
└── README.md
| Requisito | Versión mínima |
|---|---|
| Docker Engine | 27+ |
| Docker Compose | v2 |
| Git | cualquiera |
| OS | Linux (Debian 12 recomendado) |
| Recurso | Mínimo | Recomendado |
|---|---|---|
| CPU | 2 vCPU | 4 vCPU |
| Memoria | 6 GB | 8 GB |
| Disco | 40 GB | 60 GB SSD |
git clone https://github.com/luaminc/wazuh-docker-modular.git
cd wazuh-docker-modularcp .env.example .envEditar .env con los valores reales:
WAZUH_VERSION=4.9.1
INDEXER_PASSWORD=<password-segura>
WAZUH_API_PASSWORD=<password-segura>
WAZUH_DASHBOARD_PASSWORD=<password-segura>Importante: Todas las passwords deben ser idénticas entre sí en el primer despliegue. El Security Plugin se inicializa con una sola password compartida que luego puede diferenciarse por usuario.
Generar o copiar los certificados en runtime/:
runtime/certs/
├── root-ca.pem
├── admin.pem
├── admin-key.pem
├── esnode.pem
└── esnode-key.pem
runtime/manager-certs/
├── root-ca.pem
├── filebeat.pem # Copia de admin.pem
└── filebeat-key.pem # Copia de admin-key.pem
Ver docs/runbooks/RB-003-manager-certificates.md para el procedimiento completo de generación.
docker compose \
--env-file .env \
-f compose/docker-compose.yml \
-f compose/core/wazuh-indexer.yml \
-f compose/core/wazuh-manager.yml \
-f compose/core/wazuh-dashboard.yml \
up -dEsperar la inicialización completa del Indexer:
sleep 90
docker ps --filter name=wazuh --format "table {{.Names}}\t{{.Status}}"Los tres contenedores deben mostrar healthy.
Este paso es obligatorio en el primer despliegue y cada vez que se recree
wazuh_indexer_data.
export $(grep -v '^#' .env | xargs)
./scripts/bootstrap/security-init.sh
docker restart wazuh-dashboardEl script realiza automáticamente:
- Configura la password del usuario
adminen OpenSearch - Crea el usuario
wazuh-wuicon el rolwazuh_ui_user - Carga las credenciales en el keystore del manager
- Reinicia los módulos del manager para activar el IndexerConnector
# Estado de los contenedores
docker ps --filter name=wazuh --format "table {{.Names}}\t{{.Status}}"
# Índices creados
curl -sk -u admin:<password> \
--cacert runtime/certs/root-ca.pem \
"https://localhost:9201/_cat/indices/wazuh-*?v&h=index,health,docs.count"
# IndexerConnector inicializado
docker exec wazuh-manager \
grep "IndexerConnector initialized successfully" \
/var/ossec/logs/ossec.log | tail -3Índices esperados:
wazuh-alerts-4.x-YYYY.MM.DDwazuh-states-vulnerabilities-wazuh-managerwazuh-statistics-*wazuh-monitoring-*
http://<IP>:5601
Credenciales: admin / <WAZUH_DASHBOARD_PASSWORD>
docker ps --filter name=wazuh --format "table {{.Names}}\t{{.Status}}\t{{.Image}}"docker restart wazuh-manager
docker restart wazuh-dashboard
docker restart wazuh-indexerdocker logs -f wazuh-manager
docker logs -f wazuh-indexer
docker logs -f wazuh-dashboarddocker exec wazuh-manager \
grep "IndexerConnector" /var/ossec/logs/ossec.log | tail -10# En .env, actualizar WAZUH_VERSION=X.Y.Z
git pull
docker compose \
--env-file .env \
-f compose/docker-compose.yml \
-f compose/core/wazuh-indexer.yml \
-f compose/core/wazuh-manager.yml \
-f compose/core/wazuh-dashboard.yml \
pull
docker compose \
--env-file .env \
-f compose/docker-compose.yml \
-f compose/core/wazuh-indexer.yml \
-f compose/core/wazuh-manager.yml \
-f compose/core/wazuh-dashboard.yml \
up -dNo es necesario recrear volúmenes en actualizaciones de patch.
| Directorio | Contenido |
|---|---|
docs/adr/ |
Decisiones de arquitectura con contexto y justificación |
docs/incidents/ |
Incidentes ocurridos durante la implementación |
docs/runbooks/ |
Procedimientos operacionales paso a paso |
docs/troubleshooting/ |
Guías de diagnóstico y resolución |
- Integración con Vault para gestión de secretos
- Integración con Infisical como alternativa open source
- Pipeline CI/CD con Jenkins
- Observabilidad del stack Wazuh en Grafana/Prometheus
- Alta disponibilidad con múltiples nodos
- Generación automática de certificados
GPLv2 — respetando el modelo de distribución del proyecto Wazuh.
Este proyecto fue construido como parte de la implementación del SOC del Departamento de Salud Coquimbo, Chile. La arquitectura modular y los problemas documentados son el resultado de un proceso real de implementación en producción sobre infraestructura on-premise con restricciones de recursos y conectividad propias del sector público.