Zeek Network Traffic Analysis: Open-Source NSM Deployment Guide
Hands-on Zeek network traffic analysis: install, interface listen, conn logs, DPD deep packet inspection, and script alerts. Full commands and config samples for building an open-source network security monitoring platform.
Applicable Scenarios
Zeek network traffic analysis fits security teams building passive NSM. Zeek (formerly Bro) ingests SPAN/TAP traffic, deep-parses it, and emits structured conn, DNS, HTTP, and certificate logs. Custom detection via Zeek scripts. Typical uses: side-channel Web-attack monitoring, anomalous internal-asset comms, malicious domains and TLS cert anomalies in encrypted traffic, long-horizon traffic metadata for threat hunting.
Prerequisites
- Dedicated monitor host (4C8G minimum; 500G+ storage recommended), isolated from production
- Switch SPAN / mirror port copying monitored traffic onto the monitor NIC
- OS: Ubuntu 20.04+ / Debian 11+ / CentOS 8+
- Monitor NIC has no IP (listen-only); avoids Zeek self-traffic pollution
How It Works
Zeek is event-driven: capture via libpcap, Event Engine parses packets into protocol events, Policy Scripts filter/aggregate/correlate those events, output structured *.log files. Unlike rule-match IDS (Suricata), Zeek focuses on recording and semantic analysis. DPD (Dynamic Protocol Detection) auto-identifies application protocols on non-standard ports (HTTP, FTP, SSH).
Procedure
Step 1: Install Zeek
`# Ubuntu / Debian (official OBS repo)
echo 'deb http://download.opensuse.org/repositories/security:/zeek/xUbuntu_22.04/ /' > /etc/apt/sources.list.d/zeek.list
curl -fsSL https://download.opensuse.org/repositories/security:/zeek/xUbuntu_22.04/Release.key | gpg --dearmor -o /etc/apt/trusted.gpg.d/zeek.gpg
apt-get update && apt-get install -y zeek
# CentOS 8
dnf install -y https://download.opensuse.org/repositories/security:/zeek/CentOS_8/x86_64/zeek-6.0.0-0.x86_64.rpm
# add zeek to PATH
echo 'export PATH=/opt/zeek/bin:$PATH' >> /etc/profile.d/zeek.sh
source /etc/profile.d/zeek.sh
zeek --version`
Step 2: Configure listen interface
Edit /opt/zeek/etc/node.cfg:
`[zeek]
type=standalone
host=127.0.0.1
interface=eth1`
`# deploy config and start
zeekctl deploy
# check node status
zeekctl status
# expected: zeek node running`
Step 3: Core logs
`# log dir (daily subdirs)
ls /opt/zeek/logs/current/
# common log files
# conn.log — all connections (src/dst IP, port, bytes, state)
# dns.log — DNS queries
# http.log — HTTP requests (URL, UA, status)
# ssl.log — TLS certs (SNI, cert hash)
# notice.log — events hitting notice policies
# live conn log
tail -f /opt/zeek/logs/current/conn.log | zeek-cut id.orig_h id.resp_h id.resp_p proto conn_state`
Step 4: DPD and script alerts
Create custom detection script /opt/zeek/share/zeek/site/local_zeek_test.zeek:
`# flag source IPs opening >100 connections (possible scan)
event new_connection(c: connection) {
if (c$id$resp_p == 80/tcp && c$conn_state == "S0") {
NOTICE([$note=Weird_Activity,
$msg=fmt("Possible port scan from %s", c$id$orig_h),
$conn=c]);
}
}`
`# load script from local.zeek
echo "@load local_zeek_test" >> /opt/zeek/share/zeek/site/local.zeek
# reload scripts
zeekctl deploy
sleep 60
# view notices
tail -f /opt/zeek/logs/current/notice.log`
Step 5: Visualization and alerting
`# Zeek logs are TSV; import into Elasticsearch / Splunk
# filebeat + elastic example: set /opt/zeek/logs/current/*.log as input
# or zeek-cut fields to CSV for offline analysis
zeek-cut -d id.orig_h id.resp_h id.resp_p proto < /opt/zeek/logs/current/conn.log > /tmp/conn.csv`
Config Verification
`# issue one HTTP request on the mirrored segment, then check http.log
zeek-cut ts host uri status_code < /opt/zeek/logs/current/http.log | tail -5
# expected: domain, URI, status for that request
# check DNS log
zeek-cut ts query answers < /opt/zeek/logs/current/dns.log | tail -5`
Matching records in http.log and dns.log mean Zeek is parsing mirrored traffic correctly.
FAQ
FAQ 1: Zeek captures no traffic?
Confirm mirror port and listen NIC match (ip link show — eth1 RX counters incrementing). Confirm listen NIC has no IP (an IP triggers Zeek address suppression). Verify mirrored frames actually arrive: tcpdump -i eth1 -c 100.
FAQ 2: Logs grow too fast; disk fills up?
In /opt/zeek/etc/zeekctl.cfg set LogRotationInterval=3600 (hourly rotate) and LogDir=/data/zeek (large disk). Cron-clean logs older than 30 days: find /opt/zeek/logs -type d -mtime +30 -exec rm -rf {} \;. Filter scripts can also keep only traffic for subnets you care about.
Summary
Zeek is an open-source network traffic analysis platform. Structured logs plus scripted detection give security teams network visibility. Plan mirror ingest, log retention, and alert handoff. Wire Zeek to SIEM and threat intel; that is where long-horizon hunting pays off.