Quick Start Guide

Zeek is a network traffic analyzer. Zeek works on most modern Unix-based systems and does not require custom hardware. See Installing Zeek in order to install from pre-built binary packages, or Building from Source in order to build Zeek from source.

We will first analyze previously captured network traffic from a pcap file - quickstart.pcap. Later, we will use Zeek to monitor live traffic. Each section builds on the previous section.

Running Zeek

Open a terminal, navigate to a clean directory, and run zeek on the quickstart.pcap file:

zeek -r quickstart.pcap LogAscii::use_json=T

Zeek should not produce any output, but it will create a few log files:

  • conn.log

  • http.log

  • weird.log

The connection log, or conn.log, records each connection that Zeek detects. The created conn.log has two entries. Here are those entries (some fields are cut for brevity with “…”):

{
   "ts": 1747147647.668533,
   "uid": "CmgO6f3ddanrRjiCoc",
   ...
},
{
   "ts": 1747147654.27566,
   "uid": "CQuwSY2FD0NsLn9CJj",
   ...
}

Now to find out more about both of these connections. Looking at the HTTP log, it also has two entries. Take note of the uid field, short for unique identifier. You can use that field to pivot from conn.log to http.log - the UIDs in one should correlate to entries in the other. The abbreviated logs for these two requests are:

{
    "ts": 1747147647.702181,
    "uid": "CmgO6f3ddanrRjiCoc",
    "method": "GET",
    "host": "zeek.org",
    "uri": "/",
    ...
},
{
    "ts": 1747147654.311012,
    "uid": "CQuwSY2FD0NsLn9CJj",
    "method": "WEIRD",
    "host": "zeek.org",
    "uri": "/",
    ...
}

The first entry is a simple GET request to zeek.org. The second entry used a non-standard HTTP method: WEIRD. Zeek also records unusual or unexpected behavior in weird.log, such as this invalid HTTP method. Now, pivot from http.log to weird.log, where there will be a “weird” for the second entry’s UID:

{
  "ts": 1747147654.311012,
  "uid": "CQuwSY2FD0NsLn9CJj",
  "name": "unknown_HTTP_method",
  "addl": "WEIRD",
  ...
}

The UID for this entry is the same as the second entry in conn.log and http.log. Therefore, there were two HTTP requests, one with a GET request and one with a WEIRD request. The WEIRD request was rightfully classified as a “weird” by Zeek.

More information on the various logs and what they report can be found in the Zeek Logs section. More information on working with logs can be found in the Zeek Log Formats and Inspection section.

Note

This section used LogAscii::use_json=T in the Zeek invocation, which outputs JSON format logs. The remaining invocations in this guide will not provide that argument, so Zeek will output tab-separated (TSV) logs. You may add LogAscii::use_json=T to future Zeek invocations if you want JSON format logs.

Live Traffic

Zeek is often used to monitor live network traffic, not just previously captured traffic. You can provide Zeek with a network interface to monitor traffic. Any traffic on that interface will be analyzed in order to create logs. For example, you may run Zeek on the en0 network device (change en0 to the device you want to monitor traffic on):

$ zeek -i en0 -C

Root access is typically required to run commands which monitor a network device.

In another terminal, create the same two HTTP requests we saw earlier via curl:

$ curl -X GET http://zeek.org
$ curl -X WEIRD http://zeek.org

Return to the terminal running Zeek and use Ctrl+C to exit. The logs may have more than just the two entries found before since Zeek will analyze all traffic on that network device. Entries should still appear in conn.log, http.log, and weird.log for these commands.

Note

The zeek invocation above adds a -C flag. By default, Zeek discards network packets with checksum errors. This flag tells Zeek to ignore checksums. Modern operating systems and network devices use checksum offloading, which leaves the checksums uninitialized. Since Zeek discards packets with checksum errors, checksum offloading necessitates the -C flag for local network monitoring via Zeek.

Scripting

You can also use Zeek’s own scripting language in order to modify and extend its behavior:

# example.zeek
event http_request(c: connection, method: string, original_URI: string,
    unescaped_URI: string, version: string)
    {
    print fmt("HTTP request: %s %s (%s->%s)", method, original_URI, c$id$orig_h,
        c$id$resp_h);
    }

This script defines an event handler that will run whenever Zeek sees an HTTP request. You can run it through Zeek with the data from the pcap you used earlier:

$ zeek example.zeek -r quickstart.pcap
HTTP request: GET / (192.168.1.8->192.0.78.212)
HTTP request: WEIRD / (192.168.1.8->192.0.78.212)

Or on live traffic:

$ zeek example.zeek -i en0 -C

In another terminal, run the two curl commands from before:

$ curl -X GET http://zeek.org
$ curl -X WEIRD http://zeek.org

The terminal running Zeek will print each command as it gets processed.

More information on how to use Zeek’s scripting language can be found in the Introduction to Scripting section. Experiment with Zeek scripting at try.zeek.org.

Managing Zeek

Zeek comes packaged with ZeekControl (zeekctl) to manage more complex deployments.

The same network device used in the Zeek command line can be used with zeekctl. This will go in a configuration file. For the following example, $PREFIX will refer to the installation directory. This is likely /usr/local/zeek if built from source or /opt/zeek if installed from a pre-built package.

First, update the configuration’s network interface in $PREFIX/etc/node.cfg. If the device is en0, that would look like:

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

You can further configure the local.zeek script found in $PREFIX/share/zeek/site/local.zeek. zeekctl loads this script by default. It is not overwritten by Zeek upgrades.

Run zeekctl in order to start an interactive prompt and manage your Zeek deployment:

$ zeekctl
Hint: Run the zeekctl "deploy" command to get started.

Welcome to ZeekControl 2.5.0-76

Type "help" for help.

[ZeekControl] >

Then run deploy to get started:

[ZeekControl] > deploy

In another terminal, run the same two curl commands from before:

$ curl -X GET http://zeek.org
$ curl -X WEIRD http://zeek.org

Then return to the ZeekControl prompt and stop it:

[ZeekControl] > stop
stopping zeek ...

And exit from zeekctl:

[ZeekControl] > exit

The logs from ZeekControl will not appear in your current directory. Instead, they will appear in $PREFIX/logs/current when running. Since the process was stopped, they will appear in a directory with the current date within $PREFIX/logs/ - such as $PREFIX/logs/2025-01-01/.

These logs are compressed as .log.gz files from gzip. You may decompress these via gunzip then read them, or use gzip’s packaged zcat command. On Mac, this looks like:

$ zcat < $PREFIX/logs/2025-01-08/weird.11:03:38-11:03:43.log.gz
<...>
1736352218.157077       CFvENWVlkwVHhLL35       2603:6081:18f0:99e0:7da2:6b81:9a83:cb4e 57823   2606:2800:21f:cb07:6820:80da:af6b:8b2c   80      unknown_HTTP_method     WEIRD   F       zeek    -

The logs contain the WEIRD HTTP request.

More information on using ZeekControl can be found in the ZeekControl documentation. More information on setting up a cluster can be found in the Zeek Cluster Setup section.

Clusters

ZeekControl is also used to manage a cluster of Zeek processes. A cluster contains many processes which analyze traffic together. For this example, all nodes will be local, but they may also be split among multiple hosts.

First, return to the $PREFIX/etc/node.cfg configuration file. It currently contains one “standalone” node:

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

A standalone node is not in a cluster. Instead, this will change to multiple nodes which work together. The following configuration is commented out in the node.cfg file by default. Remove the [zeek] node from above and paste this into the file:

[logger]
type=logger
host=localhost

[manager]
type=manager
host=localhost

[proxy]
type=proxy
host=localhost

[worker]
type=worker
host=localhost
interface=en0

Now start zeekctl again with the zeekctl console command and run it with deploy:

$ zeekctl
Hint: Run the zeekctl "deploy" command to get started.

Welcome to ZeekControl 2.5.0-76

Type "help" for help.

[ZeekControl] > deploy

Now check the status of the cluster with the top command:

[ZeekControl] > top

Name         Type    Host             Pid     VSize  Rss  Cpu   Cmd
logger       logger  localhost        XXXX     83M    83M   0%  zeek
manager      manager localhost        XXXX     82M    82M   0%  zeek
proxy        proxy   localhost        XXXX     82M    82M   0%  zeek
worker       worker  localhost        XXXX     84M    84M   0%  zeek

This is how you can easily check the status of the running cluster. As before, run the two curl commands in another terminal:

$ curl -X GET http://zeek.org
$ curl -X WEIRD http://zeek.org

Then interrupt the top command with Ctrl+C and stop the cluster:

[ZeekControl] > stop
stopping workers ...
stopping proxy ...
stopping manager ...
stopping logger ...
[ZeekControl] > exit

As before, the logs will be in the $PREFIX/logs/ directory. Check for the weird the same way as before:

$ zcat < $PREFIX/logs/2025-05-14/weird.08:58:26-08:58:31.log.gz
<...>
1747227503.828889       C3aXMM2AC3jzZbKl6i      192.168.1.8     60818   192.0.78.150    80 unknown_HTTP_method      WEIRD   F       worker  -

Users can distribute work across multiple processes or machines with clusters. See the ZeekControl documentation for more information on managing clusters and Zeek Cluster Setup for more information on cluster setup.

Next Steps

By this point, we’ve built up from Zeek’s simplest use case to clusters. Each section has links to guide further discovery. Here are some extra considerations:

  • Follow the interactive Zeek tutorial at try.zeek.org.

  • Read more of the documentation: the documentation can be read sequentially. Documentation for Zeek’s out-of-the-box logs can be found in the Zeek Logs section.

  • Browse scripts from $PREFIX/share/zeek/policy that may be useful to load. Their documentation is found in the overview of script packages.

  • Review the FAQ.

  • Join the Zeek community Slack workspace or forum to interact with fellow Zeekers and Zeek core developers.

  • Track Zeek code releases on the Get Zeek page. Find the release notes under each release. These release notes reference the NEWS file found in the Zeek source code. The CHANGES file gives a more granular view of each change.