Configuración Avanzada de Reglas y SIEM con Wazuh
Wazuh es una plataforma SIEM de código abierto que proporciona detección de amenazas, monitorización de integridad de ficheros, detección de vulnerabilidades y cumplimiento normativo a través de agentes ligeros instalados en los sistemas monitorizados. Con reglas y decodificadores personalizables, respuesta activa automática y paneles de cumplimiento para PCI-DSS, HIPAA y GDPR, Wazuh es la solución de seguridad más completa disponible en el ecosistema open source.
Requisitos Previos
- Wazuh 4.x instalado (manager + dashboard)
- Agentes Wazuh desplegados en los sistemas a monitorizar
- Acceso al servidor Wazuh con permisos de administrador
- Conocimiento básico de XML y expresiones regulares
Reglas y Decodificadores Personalizados
Las reglas de Wazuh se almacenan en XML y definen cuándo generar alertas:
# Directorio de reglas personalizadas (no se sobrescriben en actualizaciones)
ls /var/ossec/etc/rules/
# Crear un fichero de reglas personalizadas
sudo nano /var/ossec/etc/rules/local_rules.xml
<!-- /var/ossec/etc/rules/local_rules.xml -->
<group name="local_rules,">
<!-- Regla: Detectar acceso a ficheros sensibles -->
<rule id="100001" level="10">
<if_sid>80700</if_sid> <!-- Padre: evento de acceso a fichero (FIM) -->
<field name="file">/etc/shadow|/etc/passwd|/root/.ssh</field>
<description>Acceso a fichero sensible del sistema detectado</description>
<group>fim,sensitive_files,</group>
<mitre>
<id>T1003</id> <!-- OS Credential Dumping -->
</mitre>
</rule>
<!-- Regla: Múltiples fallos de sudo en poco tiempo -->
<rule id="100002" level="12" frequency="5" timeframe="60">
<if_matched_sid>5503</if_matched_sid> <!-- sudo: authentication failure -->
<description>Múltiples fallos de autenticación sudo - posible fuerza bruta</description>
<group>authentication_failure,sudo,</group>
<mitre>
<id>T1078</id> <!-- Valid Accounts -->
</mitre>
</rule>
<!-- Regla: Detección de reverse shell común -->
<rule id="100003" level="15">
<if_sid>0</if_sid>
<match>bash -i >& /dev/tcp|/bin/bash -i|python3? -c.*socket.*connect|nc -e /bin</match>
<description>Posible reverse shell detectado en comando ejecutado</description>
<group>attack,reverse_shell,</group>
<mitre>
<id>T1059</id> <!-- Command and Scripting Interpreter -->
</mitre>
</rule>
<!-- Regla: Cambio de contraseña de root -->
<rule id="100004" level="12">
<if_sid>5905</if_sid> <!-- Cambio de contraseña -->
<field name="dstuser">root</field>
<description>Contraseña del usuario root modificada</description>
<group>authentication,</group>
</rule>
</group>
Crear decodificadores personalizados para aplicaciones internas:
sudo nano /var/ossec/etc/decoders/local_decoder.xml
<!-- /var/ossec/etc/decoders/local_decoder.xml -->
<!-- Decodificador para logs de aplicación personalizada -->
<!-- Ejemplo de log: 2024-01-15 10:30:45 [ERROR] User [email protected] failed login from 192.168.1.100 -->
<decoder name="mi-aplicacion">
<prematch>^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} \[</prematch>
</decoder>
<decoder name="mi-aplicacion-login-failed">
<parent>mi-aplicacion</parent>
<prematch>ERROR] User </prematch>
<regex>ERROR] User (\S+) failed login from (\d+\.\d+\.\d+\.\d+)</regex>
<order>srcuser, srcip</order>
</decoder>
<!-- Decodificador para logs de Nginx personalizados -->
<decoder name="nginx-custom">
<prematch>^{"time":</prematch>
<plugin_decoder>JSON_Decoder</plugin_decoder>
</decoder>
# Verificar que las reglas y decodificadores son válidos
sudo /var/ossec/bin/ossec-logtest -t
# Probar con un log de ejemplo
echo '2024-01-15 10:30:45 [ERROR] User [email protected] failed login from 192.168.1.100' \
| sudo /var/ossec/bin/ossec-logtest
# Recargar las reglas sin reiniciar el agente
sudo /var/ossec/bin/ossec-control reload
Respuesta Activa
La respuesta activa ejecuta acciones automáticas cuando se dispara una regla:
<!-- En /var/ossec/etc/ossec.conf del manager -->
<ossec_config>
<!-- Definir el comando de respuesta activa -->
<command>
<name>firewall-drop</name>
<executable>firewall-drop</executable>
<timeout_allowed>yes</timeout_allowed>
</command>
<!-- Respuesta activa: bloquear IPs con múltiples fallos de autenticación SSH -->
<active-response>
<command>firewall-drop</command>
<location>local</location> <!-- local = en el agente que detectó -->
<rules_id>5763,5764</rules_id> <!-- IDs de reglas de fuerza bruta SSH -->
<timeout>3600</timeout> <!-- Bloquear durante 1 hora -->
</active-response>
<!-- Respuesta activa: enviar alerta de Slack para alertas críticas -->
<active-response>
<command>custom-slack-alert</command>
<location>server</location> <!-- Ejecutar en el servidor Wazuh -->
<level>12</level> <!-- Solo para nivel 12 o superior -->
<timeout>no</timeout>
</active-response>
</ossec_config>
Crear un script de respuesta activa personalizado:
# Script para enviar alertas a Slack
sudo tee /var/ossec/active-response/bin/custom-slack-alert << 'EOF'
#!/bin/bash
# Wazuh Active Response Script - Alerta a Slack
# Leer los parámetros de la alerta
ACTION=$1
USER=$2
IP=$3
ALERT_ID=$4
RULE_ID=$5
AGENT_NAME=$6
FILENAME=$7
# Webhook de Slack (configurar como variable de entorno o fichero)
SLACK_WEBHOOK=$(cat /var/ossec/etc/slack_webhook.conf)
# Construir el mensaje de Slack
MESSAGE="*⚠️ Alerta de Seguridad Wazuh*\n\n"
MESSAGE+="*Agente:* ${AGENT_NAME}\n"
MESSAGE+="*IP del atacante:* ${IP}\n"
MESSAGE+="*Regla ID:* ${RULE_ID}\n"
MESSAGE+="*Fichero:* ${FILENAME}\n"
# Enviar a Slack
curl -s -X POST "$SLACK_WEBHOOK" \
-H 'Content-type: application/json' \
--data "{\"text\":\"$MESSAGE\"}"
exit 0
EOF
chmod 755 /var/ossec/active-response/bin/custom-slack-alert
Monitorización de Integridad de Ficheros (FIM)
<!-- En /var/ossec/etc/ossec.conf del agente - configuración FIM -->
<ossec_config>
<!-- Directorios a monitorizar con sus opciones -->
<syscheck>
<disabled>no</disabled>
<frequency>43200</frequency> <!-- Escaneo completo cada 12 horas -->
<!-- Directorios críticos del sistema -->
<directories check_all="yes" realtime="yes">/etc</directories>
<directories check_all="yes" realtime="yes">/usr/bin,/usr/sbin</directories>
<directories check_all="yes" report_changes="yes">/var/www/html</directories>
<!-- Ficheros individuales críticos -->
<directories check_all="yes" realtime="yes">/etc/passwd,/etc/shadow,/etc/sudoers</directories>
<!-- Ignorar directorios que cambian con frecuencia (reduce ruido) -->
<ignore>/etc/mtab</ignore>
<ignore>/etc/hosts.deny</ignore>
<ignore>/etc/random-seed</ignore>
<ignore>/etc/adjtime</ignore>
<ignore type="sregex">.log$|.tmp$|.pid$</ignore>
<!-- Monitorizar claves de registro en Windows -->
<!-- <windows_registry>HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion</windows_registry> -->
<!-- Escaneo en tiempo real para cambios críticos -->
<scan_on_start>yes</scan_on_start>
<alert_new_files>yes</alert_new_files>
</syscheck>
</ossec_config>
# Ver el estado del FIM
sudo /var/ossec/bin/agent_control -l
# Forzar un escaneo FIM inmediato en un agente específico
sudo /var/ossec/bin/agent_control -r -u AGENT_ID -a
# Ver los cambios detectados en un fichero
sudo /var/ossec/bin/syscheck_control -f /etc/passwd
# Exportar el baseline de integridad actual
sudo sqlite3 /var/ossec/queue/db/syscheck.db \
"SELECT filename, sha256, mtime FROM fim_entry WHERE inode != 0" \
> /root/fim_baseline_$(date +%Y%m%d).txt
Detección de Vulnerabilidades
<!-- Habilitar la detección de vulnerabilidades en ossec.conf del manager -->
<vulnerability-detector>
<enabled>yes</enabled>
<interval>12h</interval>
<min_full_scan_interval>6h</min_full_scan_interval>
<run_on_start>yes</run_on_start>
<!-- Proveedor de CVEs para Ubuntu/Debian -->
<provider name="canonical">
<enabled>yes</enabled>
<os>focal</os> <!-- Ubuntu 20.04 -->
<os>jammy</os> <!-- Ubuntu 22.04 -->
<update_interval>1h</update_interval>
</provider>
<!-- Proveedor de CVEs para Red Hat/CentOS/Rocky -->
<provider name="redhat">
<enabled>yes</enabled>
<os>8</os>
<os>9</os>
<update_interval>1h</update_interval>
</provider>
<!-- Base de datos NVD para mayor cobertura -->
<provider name="nvd">
<enabled>yes</enabled>
<update_interval>1h</update_interval>
</provider>
</vulnerability-detector>
# Ver las vulnerabilidades detectadas via API
curl -k -u admin:CONTRASEÑA_WAZUH \
"https://localhost:55000/vulnerability/AGENT_ID?pretty=true&limit=10&severity=critical"
# Ver resumen de vulnerabilidades por agente
curl -k -u admin:CONTRASEÑA_WAZUH \
"https://localhost:55000/vulnerability/AGENT_ID/summary/severity?pretty=true"
Paneles de Cumplimiento Normativo
Wazuh incluye reglas mapeadas a PCI-DSS, GDPR, HIPAA y CIS Benchmarks:
# Ver alertas relacionadas con PCI-DSS
# En el dashboard de Wazuh: Security Events > PCI DSS
# Via API - obtener alertas por cumplimiento
curl -k -u admin:CONTRASEÑA \
"https://localhost:55000/manager/api/v2/security/user/authenticate?raw=true" \
-d '{"user":"admin","password":"CONTRASEÑA"}' > token.txt
# Consultar alertas de PCI-DSS
curl -k -H "Authorization: Bearer $(cat token.txt)" \
"https://localhost:55000/alerts?q=rule.pci_dss=~PCI" \
| jq '.data.hits.hits[].fields'
# Ver los controles de CIS Benchmark
# El agente ejecuta auditorías automáticas de configuración
# Los resultados aparecen en: Wazuh Dashboard > Configuration Assessment
Ajuste de Alertas y Reducción de Ruido
<!-- Crear lista de IPs de confianza para reducir falsos positivos -->
<!-- /var/ossec/etc/lists/trusted-ips -->
<!-- Formato: IP:comentario -->
<!-- 10.0.0.0/8:Red interna de confianza -->
<!-- 192.168.1.100:Servidor de monitorización -->
<!-- En ossec.conf, referenciar la lista -->
<ruleset>
<list>etc/lists/trusted-ips</list>
</ruleset>
<!-- Regla para ignorar alertas de IPs de confianza -->
<!-- En local_rules.xml -->
<rule id="100100" level="0">
<if_sid>5710,5711,5712</if_sid> <!-- Alertas SSH -->
<list field="srcip" lookup="address_match_key">etc/lists/trusted-ips</list>
<description>Actividad SSH desde IP de confianza - ignorar</description>
</rule>
# Ajustar el nivel de alerta de una regla específica
# Sin modificar la regla original, crear una override en local_rules.xml
<!-- Sobreescribir el nivel de una regla -->
<group name="local_rules,">
<rule id="100200" level="3"> <!-- Reducir nivel de 7 a 3 -->
<if_sid>5501</if_sid> <!-- Regla original: login del usuario desconocido -->
<match>usuario_servicio_backup</match>
<description>Login del usuario de backup - nivel reducido</description>
</rule>
</group>
Solución de Problemas
El agente no se conecta al manager:
# Verificar el estado del agente
sudo /var/ossec/bin/agent_control -l
# Ver logs del agente
sudo tail -f /var/ossec/logs/ossec.log | grep -i error
# En el manager, ver conexiones de agentes
sudo /var/ossec/bin/agent_control -i AGENT_ID
# Comprobar conectividad de red (puerto 1514 UDP/TCP)
sudo ss -ulnp | grep 1514
telnet IP_MANAGER 1514
Reglas personalizadas no se disparan:
# Probar la regla con un log de ejemplo
echo "log de prueba" | sudo /var/ossec/bin/ossec-logtest
# Verificar que el XML de las reglas es válido
sudo xmllint --noout /var/ossec/etc/rules/local_rules.xml
# Ver el árbol de reglas completo
sudo /var/ossec/bin/ossec-logtest -v
Alta carga en el servidor Wazuh:
# Ver el proceso que más consume
top -b -n1 | grep ossec
# Reducir la frecuencia de FIM
# En ossec.conf: <frequency>86400</frequency> (una vez al día)
# Deshabilitar agentes inactivos
sudo /var/ossec/bin/agent_control -d -u AGENT_ID
Conclusión
Wazuh con reglas y decodificadores personalizados se convierte en una herramienta de seguridad adaptada exactamente a las necesidades y el contexto de cada infraestructura. La clave para un SIEM efectivo está en el equilibrio entre la sensibilidad de detección y la reducción del ruido de falsos positivos, algo que se logra iterativamente ajustando las reglas según la operación normal del entorno. Complementa las alertas automáticas con revisiones periódicas de los paneles de cumplimiento para mantener una postura de seguridad proactiva.


