How to Set Up Zeek 9: Network Monitor in 13 Steps [2026]

A network sensor that only tells you “this looks bad” is half a security program. The other half is knowing exactly what happened before, during, and after the alert. That is the gap Zeek fills. On September 14, 2026, the Zeek Project shipped Zeek 9.0.0, a new long-term support release that swaps the cluster’s internal messaging layer for ZeroMQ and tightens up encapsulated-traffic handling. If you run a home lab sensor, a small business network, or a SOC that wants protocol-level visibility instead of just rule hits, this walkthrough gets Zeek 9 installed, configured, and producing usable logs in about 90 minutes.

This guide covers a standalone Ubuntu install, a look at ZeekControl’s core config files, integrating Zeek with Suricata 8.0.7 for combined detection coverage, forwarding logs into a SIEM, and standing up a small ZeroMQ-based cluster once a single sensor stops keeping up. It closes with a troubleshooting section built from the errors people actually hit, plus a complete working project you can copy for a home lab.

Google · Preferred Sources

Don't miss new tech stories on Google

Add Tech Insider once in the Google app and our stories appear in your news suggestions.

Add Now

Why Network Visibility Still Matters When Most Traffic Is Encrypted

The usual objection to network monitoring in 2026 is that TLS encrypts almost everything, so what’s left for a sensor to actually see. Plenty, it turns out. Zeek does not need to decrypt a session to extract value from it: TLS handshake metadata, negotiated cipher suites, certificate chains, and JA3/JA4 fingerprints all travel in the clear before encryption kicks in, and that metadata alone is enough to spot a command-and-control channel dressed up as ordinary HTTPS traffic. Combine that with DNS query patterns, connection timing, and byte-count ratios, and a network sensor can flag behavior a purely signature-based tool would miss entirely because there’s no packet payload left to match against.

This is also why network monitoring hasn’t been replaced by endpoint tools. Endpoint agents see what a specific host is doing, but they can’t see traffic between two devices neither of which runs your agent, an IoT camera talking to a printer, a contractor’s unmanaged laptop, or a compromised router. A tap-based sensor like Zeek sees every device on the wire, managed or not, which is precisely the blind spot most endpoint-only security programs carry into an incident.

What Zeek Actually Does (and Why It’s Not Suricata)

Zeek, known as Bro until a 2018 rename, is a network security monitor, not a signature-based intrusion detection system. It sits passively on mirrored or tapped traffic, parses dozens of application-layer protocols, and turns that traffic into structured, scriptable events. Instead of matching packets against a rule like “alert if this byte pattern appears,” Zeek generates an event every time something protocol-relevant happens, a DNS query resolves, a TLS handshake completes, an HTTP request goes out, and lets you write logic against those events in the Zeek scripting language.

That distinction matters operationally. Suricata, covered in our Suricata IDS/IPS setup guide, is built to match traffic against signature sets and can drop packets inline when running in IPS mode. Zeek does not block anything by design, it observes and records. Most production security teams run both side by side: Suricata catches known-bad traffic fast, Zeek gives you the connection-level record to answer “what else did that host talk to” six months later when an incident response team needs the history.

ToolDetection MechanismBest ForBlocks TrafficLatest Version (Sept 2026)
ZeekEvent-driven protocol analysisBehavioral visibility, threat hunting, forensicsNo, passive by design9.0.0 (Sept 14, 2026)
SuricataSignature/rule matchingHigh-speed IDS/IPS detectionYes, in inline IPS mode8.0.7 (Sept 15, 2026)
WiresharkManual packet inspectionDeep single-session forensic reviewNo4.6.9 (Sept 23, 2026)
Security OnionBundled platform (Zeek + Suricata + Elastic)Turnkey NSM stack for small SOCsOptional, via bundled SuricataShips current Zeek and Suricata builds

If you already run Wireshark for packet-level review or you deployed Security Onion 3 as a bundled NSM platform, Zeek is the engine doing most of the protocol parsing underneath. This tutorial builds it standalone, so you understand exactly what each config file does before you hand it to a bundled distro.

A short history: from Bro to Zeek

The project started life at Lawrence Berkeley National Laboratory in the 1990s under the name Bro, a reference to George Orwell’s “Big Brother.” The community renamed it Zeek in 2018 to shed a name that carried baggage and didn’t describe the project, the underlying engine and scripting model carried forward unchanged. Anyone who learned the tool as Bro will recognize every config file and command in a 2026 install, the syntax and architecture are the same lineage, just under a name that search engines and new users find easier to work with.

Where Zeek sits in a defense-in-depth stack

A mature security stack layers several tools that each see a different slice of activity: a firewall controls what’s allowed on the wire, Suricata or a commercial IPS blocks known-bad traffic inline, endpoint detection watches process behavior on each host, and a SIEM correlates all of it into one timeline. Zeek’s job in that stack is the network’s memory, the connection-level record that lets an analyst reconstruct exactly what a compromised host talked to, when, and how much data moved, regardless of whether any single alert fired at the time. That reconstruction is often the difference between a two-hour incident review and a two-week one.

Prerequisites: What You Need Before Installing Zeek 9.0.0

Get these in place before Step 1. Skipping the network tap or mirror step is the single most common reason people finish an install and see empty logs.

  • Operating system: Ubuntu 24.04 LTS or 22.04 LTS (Debian 12 also works with the equivalent APT repo).
  • Zeek version: 9.0.0, the current LTS release as of September 28, 2026. The prior 8.0.x line, most recently patched to 8.0.10 on August 19, 2026, will stop receiving fixes once 9.1 ships.
  • Access: root or sudo privileges on the sensor host.
  • Traffic source: a SPAN/mirror port on your switch, a network TAP, or a virtual mirror interface if you’re testing inside a VM (promiscuous mode enabled on the vSwitch).
  • Sizing: the Zeek project does not publish one universal hardware minimum, sizing depends on mirrored throughput, enabled analyzers, and log retention. As a practical starting point for a home lab or small-office sensor watching under 1 Gbps of mirrored traffic, 4 vCPUs, 8 GB RAM, and 100 GB of disk for 30 days of logs is a comfortable baseline; scale CPU and RAM up before disk if the sensor starts dropping packets.
  • Optional companions: Suricata 8.0.7 if you want combined IDS coverage, and a log destination such as Wazuh or an Elastic stack if you plan to centralize alerts.

Step 1: Update the System and Install Build Dependencies

Start with a clean, updated base. Even if you plan to install from packages rather than source, these libraries cover Zeek’s runtime dependencies and the Zeek Package Manager you’ll use later.

sudo apt update && sudo apt upgrade -y
sudo apt install -y curl gnupg2 lsb-release ca-certificates \
  python3 python3-pip python3-venv cmake make gcc g++ \
  libpcap-dev libssl-dev zlib1g-dev

Reboot if the kernel was patched during the upgrade, then confirm the network interface you plan to monitor is visible with ip link show. Note its name (commonly eth1 or ens224 on a dedicated monitor NIC), you’ll need it in Step 5.

Step 2: Choose an Installation Method

Zeek 9.0.0 ships three practical install paths from the official download page. Packages are fastest and are what this guide uses; source builds give you a custom prefix and compiler flags; a container image is useful for quick lab testing but is not the recommended pattern for a production sensor tapping live traffic.

MethodBest ForTime to Working Install
APT/YUM package repoProduction sensors on supported distros10-15 minutes
Source buildCustom prefixes, unsupported platforms, patched builds45-90 minutes
Docker containerLab testing, CI pipelines, script development5 minutes, not recommended for live taps

Step 3: Install Zeek 9.0.0 via the Official APT Repository

Add the Zeek-provided repository for your Ubuntu release, import the signing key, and install the metapackage. The package names below track the LTS 9.0 line, check zeek.org/get-zeek if you’re on a distro version not listed here, since the exact repo path is tied to the OS release.

echo 'deb http://download.opensuse.org/repositories/security:/zeek/xUbuntu_24.04/ /' | \
  sudo tee /etc/apt/sources.list.d/security:zeek.list

curl -fsSL https://download.opensuse.org/repositories/security:zeek/xUbuntu_24.04/Release.key | \
  gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/security_zeek.gpg > /dev/null

sudo apt update
sudo apt install -y zeek-lts

Package installs typically land under /opt/zeek. Add it to your PATH so ZeekControl and zkg are reachable without a full path every time:

echo 'export PATH=/opt/zeek/bin:$PATH' >> ~/.bashrc
source ~/.bashrc

Step 4: Verify the Installation

Confirm the binary is on your path and reporting the version you expect before touching any config file. This single check catches the most common early mistake: a partial install where the package manager pulled 8.0.10 from a cached repo entry instead of the new 9.0 line.

zeek --version

Expected output:

zeek version 9.0.0
Zeek::pcap version 9.0.0

If it prints 8.0.x, clear the APT cache and re-check your repo line, the previous LTS package is likely still pinned. If it prints 9.0.0, you’re ready for configuration.

Step 5: Configure node.cfg for Standalone Mode

node.cfg defines what Zeek processes run and which network interface each one watches. For a single sensor, standalone mode runs manager, logger, proxy, and worker in one process on one box. Edit the file at /opt/zeek/etc/node.cfg:

[zeek]
type=standalone
host=localhost
interface=ens224

Replace ens224 with the mirror interface name you noted in Step 1. This is the line people get wrong most often, pointing Zeek at the management NIC instead of the tap, which produces an install that runs but sees no interesting traffic.

Step 6: Configure zeekctl.cfg

zeekctl.cfg, at /opt/zeek/etc/zeekctl.cfg, controls operational settings: where logs and spool files land, mail alerting, and log rotation behavior. The defaults are workable for a lab, but for a production sensor, set explicit log and spool paths so you can monitor disk usage separately from the OS partition:

LogDir = /data/zeek/logs
SpoolDir = /data/zeek/spool
LogRotationInterval = 3600
MailTo = [email protected]

Mount /data on its own volume if you’re running this in a VM. Log volume from a busy sensor fills a root partition fast, and a full disk is one of the quietest ways Zeek stops writing without an obvious error on the console.

Step 7: Customize local.zeek Site Policy

local.zeek, found under /opt/zeek/share/zeek/site/local.zeek, is where you load scripts, tune notices, and add site-specific logic. A minimal starting point that enables JSON-formatted logs (easier to ship to a SIEM) and turns on SSL/JA4 fingerprint logging looks like this:

@load policy/tuning/json-logs
@load protocols/ssl/log-hostcerts-only
@load frameworks/notice/extend-email/hostnames

redef Notice::emailed_types += {
    SSL::Invalid_Server_Cert
};

Everything Zeek does beyond the default protocol logs lives here. Adding detection logic as small, well-commented blocks in local.zeek keeps a clean upgrade path, since you never edit Zeek’s own shipped scripts directly.

Step 8: Deploy and Start Zeek with ZeekControl

ZeekControl reads your three config files, validates them, and starts the processes. Run a syntax check first, then deploy:

sudo zeekctl check
sudo zeekctl deploy
sudo zeekctl status

A healthy standalone deployment reports a single node in RUNNING state:

Name    Type       Host        Status    Pid    Peers   Started
zeek    standalone  localhost   running   18422  0       28 Sep 09:14:07

If zeekctl check reports a config error, fix it before deploying, ZeekControl will not start a broken configuration, and that’s a feature, not a bug, it prevents a silently half-running sensor.

Step 9: Install zkg and Add Community Packages

zkg, Zeek’s package manager, is bundled with the LTS install. Run zkg autoconfig once to point it at your Zeek prefix, then pull in packages from the Zeek Package Index. A common first install is a Community ID connection-fingerprinting package that makes correlating Zeek and Suricata logs much easier:

zkg autoconfig
zkg refresh
zkg install zeek/corelight/zeek-community-id
zkg list

After installing a package, load it from local.zeek with an @load packages line, then redeploy with zeekctl deploy so the change takes effect.

Step 10: Read Zeek’s Default Logs

This is where Zeek earns its keep. Every log lands in your configured LogDir, one file per protocol, tab-separated by default or JSON if you loaded the json-logs script in Step 7.

Log FileContentsTypical Use
conn.logEvery connection’s 5-tuple, duration, and byte countsBaseline traffic analysis, beaconing detection
dns.logDNS queries and responsesDNS tunneling and exfiltration hunting
http.logHTTP requests and responsesWeb traffic auditing, user-agent tracking
ssl.logTLS handshake metadata, JA3/JA4 when enabledEncrypted traffic fingerprinting
x509.logCertificate chain detailsRogue or expired certificate hunting
notice.logZeek’s own generated alertsFirst place to triage during an investigation
weird.logProtocol anomalies and malformed trafficDetecting evasion attempts and broken clients
files.logExtracted file transfer metadataMalware delivery and file exfil tracking

Tail conn.log to watch live traffic come in:

tail -f /data/zeek/logs/current/conn.log

For anything beyond a quick tail, pull the logs into Wireshark for a packet-level replay of a specific session, or run captured payloads through CyberChef to decode obfuscated content flagged in files.log.

Zeek Scripting Basics: Writing Your First Detection

Reading logs is passive. The real value of Zeek shows up once you write a script that reacts to events as they happen, flagging something specific to your environment rather than waiting to grep through conn.log after the fact. Zeek scripts are event handlers, blocks of code that run every time a named event fires, such as a new connection starting or an HTTP request completing.

Anatomy of a Zeek event handler

Here’s a small script that raises a notice whenever a host inside your network makes a DNS query for a domain on a short, locally maintained watchlist, a pattern useful for catching known command-and-control domains before a full threat-intel feed integration is in place. Save it as /opt/zeek/share/zeek/site/watchlist-dns.zeek:

module WatchlistDNS;

export {
    redef enum Notice::Type += {
        Watchlist_Domain_Query
    };
}

const watched_domains: set[string] = {
    "known-bad-c2.example",
    "suspicious-exfil.example"
} &redef;

event dns_request(c: connection, msg: dns_msg, query: string, qtype: count, qclass: count)
{
    if ( query in watched_domains )
        NOTICE([$note=Watchlist_Domain_Query,
                $msg=fmt("Watchlisted domain queried: %s", query),
                $conn=c]);
}

Add @load watchlist-dns to local.zeek, then redeploy with zeekctl deploy. Every future query for a domain in that set now writes a distinct entry to notice.log instead of blending into the general dns.log noise.

Testing a script before deploying it

Never push an untested script straight to a live sensor. Zeek can replay a saved pcap file through any script exactly as if it were live traffic, which is the safe way to confirm your logic actually fires before it touches production:

zeek -r sample-capture.pcap /opt/zeek/share/zeek/site/watchlist-dns.zeek

Check the resulting notice.log in the current directory for your test notice before loading the script into local.zeek. This one habit, testing against a pcap first, catches the majority of syntax and logic errors that would otherwise only surface after a live redeploy.

Step 11: Integrate Zeek with Suricata for Combined Coverage

Zeek and Suricata read the same mirrored traffic without conflicting, since both operate in read-only capture mode by default. The straightforward integration point is feeding Suricata’s alert stream into Zeek’s input framework so both data sets land in one place for correlation, or the reverse: use Zeek’s file extraction to hand suspicious binaries to Suricata’s file-hash detection.

A simpler starting integration is running both against the same interface and unifying their logs downstream in your SIEM, rather than chaining them together on the sensor itself:

# Suricata runs on the same mirror interface, separate process
sudo suricata -c /etc/suricata/suricata.yaml -i ens224 -D

# Confirm both are capturing independently
sudo zeekctl status
sudo suricatasc -c uptime

Full Suricata rule tuning and IPS-mode configuration is covered step by step in our Suricata IDS/IPS setup guide, worth reading before you run the two tools in production together, since a misconfigured Suricata in inline mode can drop traffic Zeek never sees.

Step 12: Scale Up with Cluster Mode via ZeroMQ

A standalone node runs fine until mirrored throughput climbs past what one worker process can parse without dropping packets. Zeek 9.0.0 defaults cluster communication to ZeroMQ, a change from earlier releases, so cluster deployments built on this version behave differently under the hood than an 8.x cluster even though the config file layout is familiar.

Node RoleFunctionTypical Count
ManagerCoordinates the cluster, runs the notice framework1
LoggerAggregates and writes logs from all workers1, sometimes 2 for redundancy
ProxyShares state between workers (e.g. tracked connections)1-2, scales with worker count
WorkerReads packets from a load-balanced interface slice and generates events1 per CPU core dedicated to capture

A three-worker cluster’s node.cfg looks like this instead of the standalone block from Step 5:

[manager]
type=manager
host=10.0.10.10

[logger]
type=logger
host=10.0.10.10

[proxy-1]
type=proxy
host=10.0.10.10

[worker-1]
type=worker
host=10.0.10.11
interface=ens224

[worker-2]
type=worker
host=10.0.10.12
interface=ens224

[worker-3]
type=worker
host=10.0.10.13
interface=ens224

Deploy the same way as standalone, zeekctl deploy, but expect the initial ZeroMQ handshake between nodes to take a few seconds longer than the legacy broker-based communication older Zeek clusters used. Confirm every node shows up in zeekctl status before trusting the cluster’s logs.

Zeek in Cloud and Virtualized Environments

Everything in this guide assumes a physical mirror port or a tap, which is straightforward on-premises but gets more complicated once workloads move to cloud VPCs or a SASE architecture where you don’t control the underlying switch fabric. AWS, Azure, and Google Cloud all support traffic mirroring at the virtual network level, AWS Traffic Mirroring and its equivalents on the other two platforms let you clone a VPC subnet’s packets to a monitoring ENI that a Zeek sensor reads exactly like a physical SPAN port. The setup differs by provider, but once a mirrored feed reaches the sensor’s interface, every step from Step 5 onward is identical.

Container and Kubernetes environments are a harder case, since east-west pod traffic often never crosses a mirrorable interface at all. Teams running Zeek in Kubernetes typically deploy it as a sidecar or a DaemonSet reading from a CNI plugin’s mirror capability, rather than trying to tap a single node-level interface and hope it catches everything. If your workloads are mostly containerized, plan the traffic-capture strategy before you install Zeek itself, since that decision shapes the whole deployment topology more than any Zeek-specific config file does.

Self-Managed Zeek vs a Commercial NDR Platform

Running Zeek yourself costs nothing in licensing, but it’s not free in the way a SaaS trial is free, someone has to size the sensor, tune the scripts, and keep the cluster patched every time a new LTS ships. Corelight, founded by Zeek’s original creators, sells hardware and cloud appliances that ship with the same Zeek engine pre-tuned, pre-packaged with detection content, and backed by vendor support. Whether that trade makes sense depends on team size and how much time you can dedicate to sensor care and feeding.

FactorSelf-Managed ZeekCommercial NDR (e.g. Corelight)
Licensing costNone, open sourceSubscription or appliance cost, varies by vendor and throughput tier
Setup timeHours to a few days for a single sensor, this guideFaster initial deployment, vendor-managed onboarding
Ongoing maintenanceYour team patches, tunes, and monitors capacityVendor handles updates and hardware refresh
CustomizationFull control over scripts, packages, and log pipelineBounded by the vendor’s supported configuration options
Best fitTeams with in-house Linux and scripting skills, labs, budget-constrained SOCsTeams that want a supported appliance and don’t want to own sensor operations

Step 13: Forward Zeek Logs to a SIEM

Raw log files on a sensor disk are only useful until that disk fills or the sensor reboots. Ship them to a central SIEM for retention, correlation, and alerting. If you’re already running Wazuh, its Filebeat-based log shipper reads Zeek’s JSON logs directly once you point it at your LogDir:

# On the Zeek sensor, add a Filebeat input for Zeek's current log dir
sudo tee /etc/filebeat/inputs.d/zeek.yml > /dev/null <<'EOF'
- type: log
  enabled: true
  paths:
    - /data/zeek/logs/current/*.log
  fields:
    log_source: zeek
  json.keys_under_root: true
EOF

sudo systemctl restart filebeat

Confirm the ingestion pipeline separately: an endpoint agent like osquery gives you host-level context to correlate against Zeek's network-level view, so a beaconing pattern in conn.log can be matched against the process that actually opened the connection.

5 Common Pitfalls When Deploying Zeek

These account for most of the "I installed it but it's not working" reports in the Zeek community forum.

  • Monitoring the wrong interface. Pointing node.cfg at the management NIC instead of a SPAN or tap interface. The sensor runs, shows RUNNING status, and produces near-empty logs because it only sees its own management traffic.
  • Promiscuous mode disabled. On a virtual sensor, the vSwitch port group must explicitly allow promiscuous mode and forged transmits, otherwise mirrored traffic never reaches the guest NIC even though the physical mirror is configured correctly.
  • Mixing Zeek 8.x and 9.x packages in a cluster. Because Zeek 9 changed the default cluster transport to ZeroMQ, a cluster with some nodes on 8.0.10 and others on 9.0.0 will fail to form properly. Upgrade every node in a cluster together.
  • Undersized proxy nodes. Proxies hold shared state, like which connections are already being tracked. Under-provisioning proxy CPU on a busy cluster causes worker events to queue and log timestamps to drift from real time.
  • Disk fills silently. ZeekControl does not stop and loudly alert when LogDir runs out of space, logs simply stop writing or truncate. Monitor disk usage on the log volume as its own metric, not as part of general host monitoring.

Troubleshooting Zeek: 8 Issues and Fixes

Work through these in order when a deployment isn't behaving.

  • "zeekctl check" reports a syntax error in local.zeek. Run zeek -a /opt/zeek/share/zeek/site/local.zeek directly to get a more specific line number than ZeekControl's summary shows.
  • conn.log exists but is empty. Confirm the interface in node.cfg matches an interface that actually shows traffic with tcpdump -i <interface> -c 10. If tcpdump sees nothing, the problem is upstream of Zeek, check the mirror/tap configuration.
  • zeekctl status shows a node as "crashed." Check /data/zeek/spool/<node>/stderr.log for the actual crash reason, most often a bad script load order or a package incompatible with the installed Zeek version.
  • High packet drop percentage in capture_loss.log. The worker can't keep up with the interface's traffic rate. Add more workers in cluster mode, or reduce enabled analyzers for protocols you don't need logged.
  • zkg install fails with a dependency error. Run zkg autoconfig again after any Zeek upgrade, the package manager caches the build environment and it goes stale across version bumps.
  • Logs are in TSV format when you expected JSON. Confirm @load policy/tuning/json-logs is actually present in local.zeek and that you redeployed after adding it, editing the file alone does not restart the processes.
  • Cluster nodes can't see each other. With Zeek 9's ZeroMQ default, check that the ports ZeroMQ uses are open between cluster hosts in your firewall or security group rules, this is a new failure mode compared to the previous broker-based transport.
  • Time drift between sensor and SIEM. Zeek timestamps events using the sensor's system clock. Run NTP or chrony on every sensor and cluster node, since even a few seconds of drift makes correlating conn.log against firewall or endpoint logs unreliable.

Advanced Tips: Tuning Zeek for Production Traffic

Trim analyzers you don't need

Every enabled protocol analyzer costs CPU. If your network has no SMB traffic crossing the monitored segment, disabling the SMB analyzer in local.zeek frees capacity for the protocols that actually matter to your environment. Audit which log files stay empty after a week of running and consider trimming the analyzers behind them.

Use Community ID for cross-tool correlation

The community-id package installed in Step 9 tags every connection with a hash that Suricata, Wireshark, and most commercial NDR tools also compute the same way. That shared identifier is what actually lets you pivot from a Zeek conn.log entry to the matching Suricata alert without manually correlating on IP and port, which gets unreliable once NAT or connection reuse enters the picture.

Write narrow detections, not broad ones

Zeek's scripting language makes it tempting to write sweeping detection logic in local.zeek. Start narrow, a script that flags a specific known-bad JA4 fingerprint or a specific DNS query pattern, and expand only after confirming it doesn't flood notice.log with false positives on your actual traffic mix.

Plan log retention before compliance asks for it

Zeek's conn.log alone can run into gigabytes per day on a moderately busy network, and that volume multiplies fast once http.log, dns.log, and ssl.log are all writing at once. Decide retention policy up front rather than reacting to a full disk: many teams keep 30 to 90 days of raw Zeek logs on the sensor itself for quick lookups, then archive compressed logs to cheaper object storage for the longer retention window that a compliance framework or cyber-insurance policy typically requires. Setting that pipeline up during initial deployment is far less painful than retrofitting it after an auditor asks for six months of network history you never kept.

Complete Working Project: A Home Lab NSM Sensor

Here's the full sequence for a single-VM home lab sensor that mirrors a home router's WAN port, runs Zeek 9.0.0 and Suricata 8.0.7 together, and ships JSON logs to a local Wazuh instance. This assumes a VM with 4 vCPUs, 8 GB RAM, and a second NIC set to promiscuous mode receiving the mirrored traffic.

# 1. Base packages and Zeek repo
sudo apt update && sudo apt upgrade -y
sudo apt install -y curl gnupg2 python3-pip
echo 'deb http://download.opensuse.org/repositories/security:/zeek/xUbuntu_24.04/ /' | \
  sudo tee /etc/apt/sources.list.d/security:zeek.list
curl -fsSL https://download.opensuse.org/repositories/security:zeek/xUbuntu_24.04/Release.key | \
  gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/security_zeek.gpg > /dev/null
sudo apt update && sudo apt install -y zeek-lts suricata

# 2. Point Zeek at the mirror NIC (edit node.cfg first, then deploy)
echo -e "[zeek]\ntype=standalone\nhost=localhost\ninterface=ens224" | \
  sudo tee /opt/zeek/etc/node.cfg

# 3. Enable JSON logging
echo '@load policy/tuning/json-logs' | sudo tee -a /opt/zeek/share/zeek/site/local.zeek

# 4. Deploy Zeek
sudo /opt/zeek/bin/zeekctl deploy

# 5. Start Suricata on the same interface
sudo suricata-update
sudo suricata -c /etc/suricata/suricata.yaml -i ens224 -D

# 6. Confirm both are producing logs
tail -n 5 /data/zeek/logs/current/conn.log
tail -n 5 /var/log/suricata/eve.json

Once both tools are confirmed running, point Filebeat or your SIEM's log shipper at /data/zeek/logs/current/*.log and /var/log/suricata/eve.json. That single VM now gives you protocol-level context from Zeek and signature-based alerts from Suricata on the same traffic, which is the same architecture behind bundled platforms like Security Onion 3, just built by hand so you understand every moving part.

Zeek 9.0.0: What Actually Changed

For anyone upgrading from the 8.x line rather than installing fresh, the September 14, 2026 release is a long-term support release built on the 8.1 and 8.2 feature work. It defaults cluster communication to ZeroMQ, improves handling of encapsulated traffic, and reworks cluster process orchestration. Zeek's own release notes describe the update as carrying an unusually large number of bug fixes driven by security scanning and fuzzing work done ahead of the release, rather than being a feature-heavy cycle. The 8.0.x line, last patched to 8.0.10 on August 19, 2026, is expected to stop receiving backports once 9.1 ships, roughly four months after the 9.0 announcement.

Spicy, Zeek's parser-generator framework used to build custom protocol analyzers, also moved to version 1.17 alongside this release. If you maintain custom Spicy analyzers, test them against 9.0.0 in a lab before rolling the upgrade to production sensors, parser-generator version bumps occasionally change generated code output in ways that affect custom builds even when the documented API stays stable.

Frequently Asked Questions

Is Zeek free to use?

Yes. Zeek is open source under a BSD-style license, and there's no paid tier for the core software. Corelight sells a commercial appliance and cloud platform built around Zeek for teams that want a supported, hardware-optimized deployment instead of a self-managed install.

Do I need both Zeek and Suricata, or just one?

They solve different problems. Suricata is built to catch known-bad traffic fast and can block it inline, Zeek gives you the connection-level record to investigate anything, known or unknown, after the fact. Most production SOCs run both. A home lab or small team just starting out can run Zeek alone for visibility and add Suricata once alerting on specific known threats becomes a priority.

Does Zeek run on Windows?

Zeek's official downloads target Linux, macOS, and FreeBSD. There is no officially supported native Windows build, Windows users typically run Zeek inside a Linux VM or a container with the monitored interface passed through.

How much traffic can one Zeek sensor handle?

It depends heavily on enabled analyzers, packet size distribution, and hardware, so there's no single published ceiling. Watch capture_loss.log after deployment, a rising drop percentage is the clearest signal that a single standalone node needs to move to cluster mode with additional workers.

Why was Zeek called Bro, and does that matter for this install?

The project renamed from Bro to Zeek in 2018. It's purely a naming change, current documentation, packages, and community resources all use the Zeek name, and you won't encounter the old name anywhere in a fresh 9.0.0 install.

Can Zeek block malicious traffic like an IPS?

Not natively. Zeek is a passive monitor by design. Some deployments pair Zeek's detection logic with an external enforcement point, feeding a flagged IP to a firewall or to Suricata running in inline mode, but Zeek itself does not sit in the traffic path or drop packets.

What's the safest way to upgrade an existing Zeek cluster to 9.0.0?

Upgrade every node in the cluster in the same maintenance window rather than rolling it node by node. Because 9.0 changes the default cluster transport to ZeroMQ, a mixed cluster running both 8.x and 9.x nodes at once is likely to fail to form correctly.

Where do I find community Zeek scripts and packages?

The Zeek Package Manager, zkg, pulls from the community-maintained Zeek Package Index. Run zkg refresh followed by zkg search <keyword> to browse available packages before installing one, rather than pulling scripts from unofficial sources.

How long should I keep Zeek logs before archiving them?

There's no single right answer, it depends on your compliance obligations and incident response needs. A common pattern is 30 to 90 days of hot storage on the sensor for fast lookups, with older logs compressed and shipped to object storage for the longer retention window many cyber-insurance policies and compliance frameworks require. Set this up during initial deployment rather than after a disk fills or an auditor asks for history you didn't keep.

Related Coverage

Sofia Lindström

Sofia Lindström

Editor-in-Chief

Sofia Lindström is the Editor-in-Chief at Tech Insider, where she leads editorial strategy and oversees coverage across AI, cybersecurity, and enterprise technology. With over a decade in Swedish tech journalism, she previously served as technology editor at Dagens Industri and covered the Nordic startup ecosystem for Breakit. Sofia holds an MSc in Media Technology from KTH Royal Institute of Technology and is a frequent speaker at Web Summit and Slush. She is passionate about making complex technology accessible to business leaders.

View all articles