--- title: "Cómo instalar Zeek en Ubuntu 24.04 para monitorizar la red" description: "Instala Zeek desde el repositorio oficial en Ubuntu 24.04, gestiónalo con zeekctl, analiza sus logs con zeek-cut y crea un script de detección e indicadores." category: "Seguridad de Red Avanzada" language: es source: https://cubepath.com/es/docs/seguridad-de-red-avanzada/monitor-de-seguridad-de-red-zeek updated: 2026-09-25 --- # Cómo instalar Zeek en Ubuntu 24.04 para monitorizar la red Zeek (antes conocido como Bro) es un monitor de seguridad de red de código abierto. En lugar de buscar firmas como un IDS clásico, Zeek analiza los protocolos y escribe registros estructurados de cada conexión, consulta DNS, petición HTTP o handshake TLS que ve pasar por una interfaz. En este tutorial instalarás Zeek en Ubuntu 24.04 desde el repositorio oficial del proyecto, lo pondrás en marcha en modo standalone con `zeekctl`, aprenderás a consultar sus logs y crearás un script de detección propio y una lista de indicadores con el framework Intel. ## Requisitos previos Para seguir esta guía necesitas: - Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath. - Un usuario no root con privilegios `sudo`. - Al menos 2 vCPU y 4 GB de RAM. Zeek procesa cada paquete en espacio de usuario, así que en enlaces con mucho tráfico necesitará más CPU. - Espacio en disco para los logs: calcula varios GB al día en un servidor con tráfico moderado. Zeek solo ve el tráfico que llega a la interfaz que monitoriza. En un VPS eso es el tráfico del propio servidor; para vigilar una red completa necesitas un puerto espejo (SPAN) o un TAP conectado a esa interfaz. ## Paso 1: Añadir el repositorio oficial de Zeek El proyecto Zeek publica paquetes para Ubuntu en el servicio openSUSE Build Service. Instala primero las herramientas para descargar la clave: ```bash sudo apt update sudo apt install -y curl gpg ``` Descarga la clave de firma del repositorio y guárdala en `/etc/apt/keyrings`: ```bash sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.opensuse.org/repositories/security:zeek/xUbuntu_24.04/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/zeek.gpg ``` Añade el repositorio indicando esa clave con `signed-by`: ```bash echo "deb [signed-by=/etc/apt/keyrings/zeek.gpg] https://download.opensuse.org/repositories/security:/zeek/xUbuntu_24.04/ /" | sudo tee /etc/apt/sources.list.d/zeek.list ``` Actualiza el índice y comprueba que apt ve el paquete: ```bash sudo apt update apt-cache policy zeek ``` ```output zeek: Installed: (none) Candidate: 8.0.1-0 Version table: 8.0.1-0 500 500 https://download.opensuse.org/repositories/security:/zeek/xUbuntu_24.04 Packages ``` El número de versión que veas será el más reciente publicado. Si prefieres una rama con soporte largo, el repositorio también ofrece el paquete `zeek-lts`. ## Paso 2: Instalar Zeek Instala el paquete `zeek`, que incluye el motor, `zeekctl` y utilidades como `zeek-cut`: ```bash sudo apt install -y zeek ``` Es posible que apt instale un servidor de correo (Postfix) como dependencia para que `zeekctl` pueda enviar informes. Si te pregunta por su configuración y no vas a enviar correo desde este servidor, elige **Local only**. Zeek se instala en `/opt/zeek`, que no está en el `PATH`. Añádelo para todos los usuarios: ```bash echo 'export PATH=/opt/zeek/bin:$PATH' | sudo tee /etc/profile.d/zeek.sh source /etc/profile.d/zeek.sh ``` Comprueba la instalación: ```bash zeek --version ``` ```output zeek version 8.0.1 ``` ## Paso 3: Configurar la interfaz y las redes locales Averigua el nombre de la interfaz de red pública del servidor: ```bash ip -br addr ``` ```output lo UNKNOWN 127.0.0.1/8 ::1/128 eth0 UP 203.0.113.10/24 2001:db8::10/64 ``` En este ejemplo es `eth0`; en tu servidor puede llamarse `ens3`, `ens18` o similar. Abre el fichero de nodos de `zeekctl`: ```bash sudo nano /opt/zeek/etc/node.cfg ``` Deja la configuración standalone con tu interfaz: ```ini [zeek] type=standalone host=localhost interface=eth0 ``` Después indica qué direcciones consideras locales. Zeek usa esta lista para saber qué lado de cada conexión es el tuyo: ```bash sudo nano /opt/zeek/etc/networks.cfg ``` Sustituye el contenido de ejemplo por las redes de tu servidor, una por línea, con una descripción opcional: ```text 203.0.113.10/32 Servidor principal 2001:db8::/64 Red IPv6 del servidor ``` Por último, ajusta la retención de logs en `zeekctl.cfg`: ```bash sudo nano /opt/zeek/etc/zeekctl.cfg ``` Busca estas opciones y déjalas así: ```ini MailTo = root@localhost LogRotationInterval = 3600 LogExpireInterval = 30day ``` Con esto Zeek rota los logs cada hora y `zeekctl cron` borra los archivados con más de 30 días. ## Paso 4: Desplegar y arrancar Zeek `zeekctl deploy` comprueba los scripts, instala la configuración y arranca Zeek en un solo paso: ```bash sudo /opt/zeek/bin/zeekctl deploy ``` Comprueba que el proceso está en marcha: ```bash sudo /opt/zeek/bin/zeekctl status ``` ```output Name Type Host Status Pid Started zeek standalone localhost running 24817 25 Sep 10:12:03 ``` `zeekctl` no crea un servicio de systemd. Para que rote y archive los logs, borre los antiguos y vuelva a arrancar Zeek si se cae o tras un reinicio, ejecuta `zeekctl cron` cada cinco minutos: ```bash echo '*/5 * * * * root /opt/zeek/bin/zeekctl cron' | sudo tee /etc/cron.d/zeek ``` ## Paso 5: Leer los logs de Zeek Los logs de la hora en curso están en `/opt/zeek/logs/current/` y los archivados, comprimidos por día, en `/opt/zeek/logs/AAAA-MM-DD/`. Genera algo de tráfico y lista los ficheros: ```bash curl -s https://example.com > /dev/null ls /opt/zeek/logs/current/ ``` ```output capture_loss.log conn.log dns.log http.log notice.log ssl.log stats.log stderr.log stdout.log weird.log ``` Los más útiles son: | Log | Contenido | |-----|-----------| | `conn.log` | Cada conexión TCP, UDP e ICMP: origen, destino, duración y bytes | | `dns.log` | Consultas y respuestas DNS | | `http.log` | Peticiones HTTP sin cifrar: host, URI, user agent y código | | `ssl.log` | Handshakes TLS: versión, SNI y resultado de validación | | `ssh.log` | Sesiones SSH y si la autenticación tuvo éxito | | `notice.log` | Avisos generados por los scripts de detección | | `weird.log` | Anomalías de protocolo | Los logs son TSV con una cabecera `#fields`. `zeek-cut` extrae columnas por nombre; con `-d` convierte las marcas de tiempo a formato legible. Estas son las últimas conexiones: ```bash zeek-cut -d ts id.orig_h id.resp_h id.resp_p proto service < /opt/zeek/logs/current/conn.log | tail -5 ``` ```output 2026-09-25T10:20:14+0000 203.0.113.10 93.184.215.14 443 tcp ssl 2026-09-25T10:20:14+0000 203.0.113.10 1.1.1.1 53 udp dns 2026-09-25T10:20:31+0000 198.51.100.7 203.0.113.10 22 tcp ssh ``` Los dominios más consultados: ```bash zeek-cut query < /opt/zeek/logs/current/dns.log | sort | uniq -c | sort -rn | head ``` Los nombres de servidor (SNI) de las conexiones TLS: ```bash zeek-cut -d ts id.orig_h server_name version < /opt/zeek/logs/current/ssl.log | tail ``` Para leer un log ya archivado, descomprímelo al vuelo: ```bash zcat /opt/zeek/logs/2026-09-24/conn.*.log.gz | zeek-cut id.orig_h | sort | uniq -c | sort -rn | head ``` > Consejo: si vas a enviar los logs a un SIEM, puedes escribirlos en JSON añadiendo `@load policy/tuning/json-logs.zeek` al final de `/opt/zeek/share/zeek/site/local.zeek`. Ten en cuenta que entonces `zeek-cut` deja de servir y tendrás que usar `jq`. ## Paso 6: Escribir un script de detección propio Los scripts de Zeek reaccionan a eventos (una conexión establecida, una petición HTTP, una respuesta DNS) y pueden generar avisos en `notice.log`. Como ejemplo, este script avisa cuando se establece una conexión TCP hacia puertos que suelen usar shells remotas o botnets. Crea el fichero en el directorio `site`: ```bash sudo nano /opt/zeek/share/zeek/site/local-detect.zeek ``` ```zeek module LocalDetect; export { redef enum Notice::Type += { Suspicious_Port }; ## Puertos de destino que se consideran sospechosos. const suspicious_ports: set[port] = { 4444/tcp, 6667/tcp, 31337/tcp } &redef; } event connection_established(c: connection) { if ( c$id$resp_p !in suspicious_ports ) return; NOTICE([$note=Suspicious_Port, $conn=c, $msg=fmt("Conexión de %s a %s en el puerto %s", c$id$orig_h, c$id$resp_h, c$id$resp_p), $identifier=cat(c$id$orig_h, c$id$resp_h, c$id$resp_p)]); } ``` El campo `$identifier` hace que el framework de avisos no repita el mismo aviso para el mismo par de hosts y puerto durante un tiempo. Carga el script desde `local.zeek`, que es el punto de entrada de la configuración del sitio: ```bash echo '@load local-detect' | sudo tee -a /opt/zeek/share/zeek/site/local.zeek ``` Valida los scripts antes de desplegarlos: ```bash sudo /opt/zeek/bin/zeekctl check ``` ```output zeek scripts are ok. ``` Aplica los cambios: ```bash sudo /opt/zeek/bin/zeekctl deploy ``` Para probarlo, abre una conexión hacia un servicio que acepte conexiones en cualquier puerto, como `portquiz.net`: ```bash curl -s --max-time 5 http://portquiz.net:4444/ > /dev/null zeek-cut note msg < /opt/zeek/logs/current/notice.log ``` ```output LocalDetect::Suspicious_Port Conexión de 203.0.113.10 a 35.180.139.74 en el puerto 4444/tcp ``` Zeek ya carga por defecto otros scripts de detección desde `local.zeek`, como `policy/protocols/ssh/detect-bruteforcing`, que genera avisos `SSH::Password_Guessing` cuando una IP falla repetidamente al autenticarse por SSH. ## Paso 7: Cargar indicadores con el framework Intel El framework Intel compara lo que Zeek ve (direcciones IP, dominios, URLs, hashes de ficheros) con una lista de indicadores y registra cada coincidencia en `intel.log`. El fichero de indicadores debe estar separado por tabuladores, así que créalo con `printf` para no depender del editor. Este ejemplo usa `example.org` como indicador de prueba: ```bash printf '#fields\tindicator\tindicator_type\tmeta.source\tmeta.desc\nexample.org\tIntel::DOMAIN\tprueba\tDominio de prueba\n198.51.100.66\tIntel::ADDR\tprueba\tIP de prueba\n' | sudo tee /opt/zeek/share/zeek/site/intel.dat ``` Añade al final de `local.zeek` la carga del framework y la ruta del fichero: ```bash sudo nano /opt/zeek/share/zeek/site/local.zeek ``` ```zeek @load frameworks/intel/seen redef Intel::read_files += { "/opt/zeek/share/zeek/site/intel.dat" }; ``` El script `frameworks/intel/seen` es el que alimenta al framework con lo que aparece en DNS, HTTP, TLS y conexiones. Valida y despliega: ```bash sudo /opt/zeek/bin/zeekctl check sudo /opt/zeek/bin/zeekctl deploy ``` Provoca una coincidencia resolviendo el dominio de prueba y revisa `intel.log`: ```bash curl -s https://example.org > /dev/null zeek-cut seen.indicator seen.where sources < /opt/zeek/logs/current/intel.log ``` ```output example.org DNS::IN_REQUEST prueba example.org SSL::IN_SERVER_NAME prueba ``` Zeek vuelve a leer `intel.dat` automáticamente cuando cambia, así que puedes actualizar la lista (por ejemplo, con un feed de amenazas descargado por cron) sin reiniciar. Cuando termines la prueba, elimina las líneas de ejemplo. ## Solución de problemas - **`zeekctl status` muestra `crashed`**: revisa la salida con `sudo /opt/zeek/bin/zeekctl diag`. La causa más habitual es un nombre de interfaz incorrecto en `node.cfg`. - **Muchas entradas `bad_TCP_checksum` en `weird.log` y conexiones incompletas**: la tarjeta de red calcula los checksums por hardware y Zeek ve los paquetes salientes antes de que se rellenen. Añade `redef ignore_checksums = T;` a `local.zeek` y vuelve a desplegar. - **`capture_loss.log` muestra pérdidas altas**: Zeek no da abasto con el tráfico. Revisa el uso de CPU con `top`; si el proceso está al 100 %, necesitas más vCPU o un despliegue en clúster con varios workers. - **Los logs dejan de rotarse**: comprueba que existe `/etc/cron.d/zeek` y que `sudo /opt/zeek/bin/zeekctl cron` se ejecuta sin errores. ## Conclusión Ahora tienes Zeek analizando el tráfico de tu servidor, con logs estructurados por protocolo, rotación automática, un script de detección propio y una lista de indicadores Intel. A partir de aquí puedes enviar los logs en JSON a un SIEM como Wazuh o Elasticsearch, suscribirte a feeds de amenazas para alimentar `intel.dat` o instalar paquetes de la comunidad con `zkg`, el gestor de paquetes de Zeek.