En op.exp.8 Registro de la actividad: cómo cumplir el ENS con Wazuh, el refuerzo R4 pide que los registros solo los acceda o elimine personal autorizado. Crear un usuario de solo lectura es una forma de reforzarlo: así no todos los que consultan Wazuh pueden modificar o borrar logs. No es obligatorio para cumplir el ENS; es una opción para cuando varias personas necesitan ver los registros.
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.
- 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. - 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ónread. Segunda fila:.kibana*conread(sin ella el usuario entra, pero no puede abrir ningún dashboard). - Tenant permissions:
global_tenantcon permiso de lectura.
- Cluster permissions:
- Mapeo. Security → Role mappings, abre
ens_readonly→ Map users:analistay el backend roleanalista_ro. No mapeeskibana_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. - Rol de la API. Menú ☰ → Server management → Security, pestaña de mapeo de roles: crea la regla
wui_analista_rocon Finduser_name=analistay asígnala al rol readonly. -
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 Discover | Permitido |
Borrar un índice, escribir un documento, _delete_by_query | 403 |
| Crear o modificar objetos guardados (visualizaciones, dashboards) | 403 |
| Crear un grupo de agentes desde la app | Denegado (Permission denied) |
API directa: reiniciar el manager, editar local_rules.xml, borrar un agente | Permission 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.
Qué decir (y qué no) en una auditoría
- Esto no hace los logs inmutables: sigue habiendo administradores de Wazuh que pueden borrar. R4 pide controlar quién puede, y esto lo demuestra.
- Deja el rol de administrador de Wazuh en pocas personas, distintas de quienes administran los servidores.
- El rol
own_indexque aparece en el usuario es un rol por defecto del indexer y no da acceso a los índices de Wazuh.
Preguntas frecuentes
¿Es obligatorio un usuario de solo lectura para cumplir el ENS?
No. R4 de op.exp.8 pide que los registros y sus copias solo los pueda acceder o eliminar personal autorizado. Un usuario de solo lectura es una forma de reforzarlo cuando varias personas consultan Wazuh, pero no es un requisito: también se cumple limitando quién tiene acceso de administración y documentándolo.
¿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.
Artículos relacionados:
- op.exp.8 Registro de la actividad: cómo cumplir el ENS con Wazuh
- op.exp.8 ENS: Registro de la Actividad, qué exige y cómo cumplirlo
- Curso de Wazuh en español, con módulo de ENS
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.