Wazuh ENS op.exp Dashboard Cumplimiento Normativo Ciberseguridad

Wazuh y op.exp.8 del ENS: dashboard, retención y solo lectura

Cómo cubrir los refuerzos R1 a R4 de op.exp.8 con Wazuh: dashboard de revisión, plantilla Word de retención y usuario de solo lectura. Descargables incluidos.

AI Security
12 min lectura

En op.exp.8 ENS: qué exige vimos qué pide la medida. Este artículo es la parte práctica, la que acompaña al vídeo del curso: cómo se enseña en Wazuh que se cumplen los refuerzos R1 a R4 del nivel medio. Hay dos descargables (el dashboard y la plantilla de retención) y una guía paso a paso para crear un usuario de solo lectura, que es lo que hace falta para R4.

¿Qué cubre Wazuh de op.exp.8 y qué no?

Wazuh recolecta y normaliza los registros; el contenido lo genera el sistema de origen. Si un servidor no registra el usuario o el resultado de una acción, Wazuh no lo inventa. Por eso la primera decisión es qué se activa en cada servidor: lo que llega al manager depende de los <localfile> del ossec.conf de cada agente (canales Security y System en Windows, auth.log o secure en Linux, auditd, Sysmon, syslog remoto para NAS y red). Y un agente desconectado es un servidor sin registro, así que la cobertura también se vigila.

Registro de auditoría (op.exp.8 base): un evento real

La medida base pide usuario, fecha y hora, sobre qué información, tipo de evento y resultado. En Discover, abre un evento de inicio de sesión fallido (Windows 4625 o SSH) y comprueba que aparecen:

  • timestamp: fecha y hora.
  • Usuario: data.win.eventdata.targetUserName en Windows o data.srcuser en Linux.
  • agent.name: sobre qué sistema.
  • rule.description: tipo de evento y resultado.

R1: revisión periódica con un dashboard

La norma habla de revisión informal periódica: basta con mirar un panel con una frecuencia definida (y dejar constancia de que se hace). El dashboard descargable agrupa lo que conviene mirar:

  • Agentes desconectados: cobertura, ¿falta algún sistema? (regla 504 de serie).
  • Logins correctos vs fallidos en el tiempo, y mapa por origen.
  • Top usuarios y top IP origen de fallos de autenticación.
  • Privilegios: altas en grupos privilegiados, sudo y cuentas.
  • Cambios de hora del sistema (relacionado con R2).
  • Manipulación de logs en origen: borrado de logs y cambios de política de auditoría. Complementa R4, pero no es R4 en sentido estricto.

Para importarlo: en el menú del dashboard, Dashboard management → Saved objects → Import, selecciona el fichero ens-opexp8-dashboard.ndjson. Es un ejemplo: cada organización lo adapta a su infraestructura y a los servidores de su alcance.

Un panel vacío no significa que no pase nada. Significa que falta una fuente. Antes de interpretar el dashboard, comprueba la lista de abajo.

Panel Qué necesita para tener datos
Logins en Windows Canal Security en el agente y política "Auditar inicio de sesión" (éxito y error). Se comprueba con auditpol /get /category:*.
Logins y sudo en Linux /var/log/auth.log (Debian/Ubuntu) o /var/log/secure (RHEL) como <localfile>.
Privilegios en Windows Auditoría de "Uso de privilegios" (4672) y "Administración de grupos de seguridad" (4728).
Borrado de logs y política de auditoría Windows: eventos 1102 y 4719. Linux: FIM (syscheck) sobre /var/log.
NAS y red Syslog remoto hacia el manager, puerto 514 abierto y, si el fabricante no está soportado, decodificadores propios.
Todos NTP correcto en todos los orígenes y en el manager. Sin hora fiable, el orden de los eventos tampoco lo es.

R2: la hora la sincroniza NTP, Wazuh vigila que nadie la cambie

Wazuh no sincroniza relojes: eso es trabajo de NTP en cada sistema. Lo que sí puede hacer es alertar de que alguien cambie la hora. En Windows se usa el evento 4616 (cambio de hora del sistema), que requiere auditar esa categoría en la política. En Linux se usa auditd con una regla sobre las llamadas que modifican el reloj, leyendo /var/log/audit/audit.log con log_format audit. Es el panel "Cambios de hora" del dashboard.

R3: la retención es un documento, y además hay que cumplirla

R3 no se activa con una opción: es un documento que dice qué eventos se auditan y cuánto tiempo se guardan. La plantilla Word tiene cuatro tablas (Windows, Linux, NAS y plataforma Wazuh) con las columnas: qué se guarda, de qué log sale, tipo, agente o sistema, retención online y retención total.

Los plazos de la plantilla son ejemplos: el ENS no fija un plazo, pide que esté escrito y que se cumpla. Un consejo práctico: empieza este documento al principio de la implantación de Wazuh, no cuando ya esté todo funcionando. Cada vez que añadas un equipo, lo apuntas en ese momento (qué logs recoge, de qué tipo y cuánto se guardan). Reconstruirlo al final, con decenas de agentes, es mucho más difícil y se olvidan cosas.

Para demostrar que se cumple, una política ISM en Index Management borra los índices wazuh-alerts-* al superar el plazo; hay que aplicarla a esos índices. El valor de 395d es solo un ejemplo; el tuyo sale de tu política de seguridad.

PUT _plugins/_ism/policies/wazuh_retencion_ens
{
  "policy": {
    "description": "Retención alertas op.exp.8 - ENS nivel medio",
    "default_state": "hot",
    "states": [
      { "name": "hot", "actions": [],
        "transitions": [{ "state_name": "delete", "conditions": { "min_index_age": "395d" } }] },
      { "name": "delete", "actions": [{ "delete": {} }] }
    ]
  }
}

R4: control de acceso a los registros

R4 pide que los registros y sus copias de seguridad solo los pueda acceder o eliminar personal autorizado. Es decir, hay que proteger el almacén de logs de Wazuh, no los logs de cada endpoint. Cuatro controles, cada uno con su evidencia:

  1. Roles en Wazuh: un analista de solo lectura frente al administrador. Es lo que se explica a continuación.
  2. Permisos en disco del manager: ls -l /var/ossec/logs/alerts /var/ossec/logs/archives debe mostrar propietario root:wazuh y sin acceso para otros.
  3. Copias de seguridad y snapshots: el repositorio solo accesible por la cuenta de administración, y saber quién puede borrarlo.
  4. Quién ha tocado Wazuh: auditoría del propio indexer, del dashboard y de la API.

Wazuh no es inmutable. Un log indexado se puede borrar o modificar con el rol admin del indexer o con root en el manager. Además, un administrador local puede parar el agente o manipular el log antes de que se envíe. El administrador de un servidor no puede reescribir lo que ese servidor ya envió a Wazuh; quien sí puede es quien tenga acceso de administración a Wazuh, y por eso R4 consiste en controlar ese acceso. Refuerzos reales: snapshots en almacenamiento WORM (por ejemplo S3 con Object Lock), reenvío de alertas a un segundo destino, roles separados y auditoría del indexer.

Cómo dar de alta un usuario de solo lectura en Wazuh 4.14

El objetivo es que quien consulta los registros (analista, auditor) pueda verlos pero no modificarlos ni borrarlos. Wazuh tiene dos sistemas de permisos y hay que configurar los dos:

Capa Qué protege Dónde se configura
Indexer + Dashboard Alertas indexadas, dashboards, objetos guardados Indexer management → Security
API de Wazuh (RBAC) Reglas, decodificadores, agentes, configuración, reinicio del manager Server management → Security

La trampa: por defecto el dashboard habla con la API siempre como wazuh-wui (administrador). Si no se activa run_as, un usuario "de solo lectura" del indexer sigue pudiendo cambiar cosas a través de la app de Wazuh. En nuestras pruebas, sin run_as el usuario pudo crear un grupo de agentes. Con run_as, la API aplica los permisos del usuario real.

En el ejemplo: usuario analista, rol del indexer ens_readonly, backend role analista_ro y regla de API wui_analista_ro asociada al rol readonly.

Desde la interfaz

Los pasos equivalentes por API (más abajo) están comprobados en Wazuh 4.14. Los nombres de menú de la interfaz pueden variar ligeramente entre versiones.

  1. Usuario. Menú ☰ → Indexer management → Security → Internal users → Create internal user. Usuario analista, una contraseña (no puede parecerse al nombre de usuario) y, en Backend roles, analista_ro.
  2. Rol. Security → Roles → Create role, con nombre ens_readonly:
    • Cluster permissions: cluster_composite_ops_ro.
    • Index permissions: patrones wazuh-alerts-*, wazuh-archives-*, wazuh-monitoring-*, wazuh-statistics-*, wazuh-states-* con acción read. Segunda fila: .kibana* con read (sin ella el usuario entra, pero no puede abrir ningún dashboard).
    • Tenant permissions: global_tenant con permiso de lectura.
  3. Mapeo. Security → Role mappings, abre ens_readonly → Map users: analista y el backend role analista_ro. No mapees kibana_read_only: aunque suena a lo que buscamos, oculta Discover y las apps de Wazuh ("Application Not Found"). El solo lectura ya lo dan los permisos de índice.
  4. Rol de la API. Menú ☰ → Server management → Security, pestaña de mapeo de roles: crea la regla wui_analista_ro con Find user_name = analista y asígnala al rol readonly.
  5. run_as. Es el paso que más se olvida. Actívalo en la conexión de la API del dashboard (Dashboard management → Server APIs → editar la conexión → Run as) o por fichero, y reinicia el dashboard: sin reinicio, la app siguió usando el administrador.

Desde la terminal

Los mismos pasos por API, útiles para repetirlos o automatizarlos. Exporta antes INDEXER_PASS con la clave del admin del indexer.

1. Rol del indexer

curl -sk -u admin:$INDEXER_PASS -H 'Content-Type: application/json' -X PUT \
  https://127.0.0.1:9200/_plugins/_security/api/roles/ens_readonly -d '{
  "cluster_permissions": ["cluster_composite_ops_ro"],
  "index_permissions": [
    {"index_patterns": ["wazuh-alerts-*","wazuh-archives-*","wazuh-monitoring-*","wazuh-statistics-*","wazuh-states-*"],
     "allowed_actions": ["read","indices:admin/mappings/get","indices:admin/resolve/index"]},
    {"index_patterns": [".kibana*",".opensearch_dashboards*"], "allowed_actions": ["read"]}],
  "tenant_permissions": [{"tenant_patterns": ["global_tenant"], "allowed_actions": ["kibana_all_read"]}]}'

2. Usuario

curl -sk -u admin:$INDEXER_PASS -H 'Content-Type: application/json' -X PUT \
  https://127.0.0.1:9200/_plugins/_security/api/internalusers/analista \
  -d '{"password":"<clave>","backend_roles":["analista_ro"]}'

3. Mapeo al rol (de nuevo, sin kibana_read_only)

curl -sk -u admin:$INDEXER_PASS -H 'Content-Type: application/json' -X PUT \
  https://127.0.0.1:9200/_plugins/_security/api/rolesmapping/ens_readonly \
  -d '{"users":["analista"],"backend_roles":["analista_ro"]}'

4. API de Wazuh: ligar el usuario al rol readonly

# token con el usuario wazuh-wui (su clave está en wazuh.yml)
TOKEN=$(curl -sk -u wazuh-wui:<clave de wazuh-wui> -X POST \
  'https://127.0.0.1:55000/security/user/authenticate?raw=true')

# regla de mapeo: el usuario analista recibe el rol readonly de la API
curl -sk -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' -X POST \
  https://127.0.0.1:55000/security/rules \
  -d '{"name":"wui_analista_ro","rule":{"FIND":{"user_name":"analista"}}}'

# unir la regla (id devuelto arriba) al rol readonly (id 2 por defecto)
curl -sk -H "Authorization: Bearer $TOKEN" -X POST \
  'https://127.0.0.1:55000/security/roles/2/rules?rule_ids=<id de la regla>'

La clave de wazuh-wui está en /usr/share/wazuh-dashboard/data/wazuh/config/wazuh.yml.

5. Activar run_as y reiniciar el dashboard

sudo sed -i 's/^\(\s*\)run_as: false/\1run_as: true/' /usr/share/wazuh-dashboard/data/wazuh/config/wazuh.yml
sudo systemctl restart wazuh-dashboard

Cómo comprobar que funciona

Entra como analista (elige el tenant Global si lo pregunta) y verifica. Estos fueron los resultados en nuestro laboratorio:

Prueba como analista Resultado
Leer alertas, abrir un dashboard guardado, usar DiscoverPermitido
Borrar un índice, escribir un documento, _delete_by_query403
Crear o modificar objetos guardados (visualizaciones, dashboards)403
Crear un grupo de agentes desde la appDenegado (Permission denied)
API directa: reiniciar el manager, editar local_rules.xml, borrar un agentePermission Denied

Para enseñarlo en una demo: con ese usuario, abre Dev Tools y lanza un DELETE sobre un índice wazuh-alerts-4.x-… (devuelve 403 security_exception), y comprueba que en Server management → Rules no se puede editar ni guardar. Si algo falla, la causa habitual es run_as sin activar o sin reiniciar el dashboard.

R5: nivel alto

En el nivel alto se exige correlación y respuesta automática. Es el núcleo de Wazuh (reglas que correlacionan eventos y active response), pero queda fuera de este artículo; se trabaja en otras lecciones del curso.

Qué decir (y qué no) en una auditoría

  • Esto no hace los logs inmutables. R4 pide controlar quién puede acceder o eliminar, y esto lo demuestra.
  • Deja el rol de administrador de Wazuh en pocas personas, distintas de quienes administran los servidores.
  • Los plazos de la plantilla son ejemplos. Documenta los tuyos y cúmplelos.
  • El rol own_index que aparece en el usuario es un rol por defecto del indexer y no da acceso a los índices de Wazuh.

Preguntas frecuentes

¿Hace Wazuh que los registros sean inmutables para el ENS?

No. Un log indexado en Wazuh se puede borrar o modificar con el rol de administrador del indexer o con root en el manager. R4 no exige inmutabilidad, exige que los registros y sus copias solo los acceda o elimine personal autorizado. Para inmutabilidad real hay que añadir snapshots en almacenamiento WORM, como S3 con Object Lock.

¿Por qué un usuario de solo lectura del indexer puede seguir cambiando cosas en Wazuh?

Porque Wazuh tiene dos sistemas de permisos: el plugin de seguridad del indexer y el RBAC de la API. Por defecto el dashboard habla con la API siempre como wazuh-wui (administrador). Si no se activa run_as, el usuario de solo lectura sigue pudiendo crear grupos de agentes o editar configuración a través de la app. Con run_as activado la API aplica los permisos del usuario real.

¿Qué plazo de retención de logs hay que poner en el ENS?

El ENS no fija un plazo universal: pide que el periodo esté definido y documentado, y que se cumpla. Los plazos de la plantilla Word (90 días online y 12 meses totales para autenticación, 180 días y 24 meses para cambios de cuentas y privilegios) son ejemplos que cada organización debe ajustar a su política de seguridad.

¿Un panel vacío en el dashboard significa que no pasa nada?

No: normalmente significa que falta una fuente de datos. Por ejemplo, sin el canal Security en el agente de Windows o sin la política de auditoría de inicio de sesión, no llegarán los eventos 4624 y 4625 y el panel de logins saldrá vacío. Revisa la lista de comprobación antes de interpretar el dashboard.


Artículos relacionados:


Curso de Wazuh

Esta lección, en vídeo y con el laboratorio

El curso incluye la lección de op.exp.8 grabada paso a paso, con la plantilla de retención y el dashboard listos para usar.