Docker deployment and management tool for Zeek
The Docker image comes with:
- Zeekctl cluster with AF_Packet
- Automatic process recovery if a worker crashes
- ja3 and ja4+ TLS fingerprinting
- zeek-open-connections for logging long-lived connections
Requires Docker to be installed.
Download the CLI for your architecture from the latest release, then:
tar xzf zeek-linux-amd64.tar.gz
sudo mv zeek /usr/local/bin/zeek
sudo zeek startOn first run, the CLI prompts you to pick a network interface. Zeek logs are written to /opt/zeek/logs/.
Note
On Rocky, RHEL, Alma, or CentOS, /usr/local/bin may not be in sudo's secure_path, which may cause sudo zeek start to fail. Use the full path (sudo /usr/local/bin/zeek start) or add /usr/local/bin to your sudo secure_path.
zeek start Start the Zeek container
zeek stop Stop the Zeek container
zeek restart Restart the Zeek container
zeek status Show container and process status
zeek readpcap Process a pcap file offline
sudo zeek readpcap /path/to/capture.pcap [output-dir]Logs default to /opt/zeek/manual-logs/.
To re-run the interface selection:
sudo rm /opt/zeek/etc/node.cfg
sudo zeek startThe image includes ja3, ja4, and zeek-open-connections, which other Active Countermeasures tools depend on. To try out additional packages, install them directly in the running container with zkg:
sudo docker exec zeek zkg install --skiptests <package>
sudo docker exec zeek zeekctl deployNote
Runtime installs are ephemeral. They don't survive zeek restart or zeek stop. Compiled-plugin packages (those with C++ code) also can't be installed this way because the final image doesn't include a compiler.
To keep a package permanently, build your own image on top of activecm/zeek. Create a Dockerfile:
FROM activecm/zeek:8.0.6
RUN zkg refresh && zkg install --force --skiptests <package>Build it:
sudo docker build -t my-zeek .The zeek CLI always launches the upstream activecm/zeek image, so to use your custom build you'll need to run it directly with docker. See Running without the CLI.
Note
Packages with compiled plugins need build tools, which aren't in the base image. Install them (e.g. RUN apk add --no-cache g++ make cmake bsd-compat-headers libpcap-dev openssl-dev zlib-dev) before the zkg install step, plus any package-specific dependencies.
In older versions of docker-zeek (v6 and prior), Zeek packages were managed using docker volumes. In v8, these volumes are unused.
To check whether you previously installed custom packages with zkg install, list the contents of the script volume:
sudo docker run --rm -v zeek-zkg-script:/check alpine ls /checkThe v6 defaults are bro-interface-setup, bro-doctor, ja3, and zeek-open-connections. Anything else is a package you added.
- To keep using a custom package, bake it into your own image. See Adding Custom Packages.
- Otherwise, remove the unused volumes:
sudo docker volume rm zeek-zkg-script zeek-zkg-plugin zeek-zkg-stateAdd custom scripts as .zeek files in /opt/zeek/share/zeek/site/autoload/. The container loads everything in that directory on each start, in filename order, so files are prefixed with a number to control load order.
The directory ships with three files we manage:
100-default.zeek- default policy, safe to edit200-inactivity_timeout.zeek- regenerated on each start, do not edit900-zkg.zeek- regenerated on each start, do not edit
Pick a filename that does not collide with these. A number between 200 and 900 keeps your script loading after the defaults:
sudo cp custom.zeek /opt/zeek/share/zeek/site/autoload/210-custom.zeek
sudo zeek restartZeek logs are written to /opt/zeek/logs/ (or $ZEEK_TOP_DIR/logs/ if customized).
Zeek files live in /opt/zeek/ by default. Change it with:
export ZEEK_TOP_DIR=/your/pathThe container can run without the docker-zeek CLI. The examples below use the upstream activecm/zeek:8.0.6 image; if you've built your own image (see Adding Custom Packages), substitute its name and tag wherever activecm/zeek:8.0.6 appears.
docker run -e ZEEK_INTERFACE=eth0 \
--net=host --cap-add=NET_RAW --cap-add=NET_ADMIN \
activecm/zeek:8.0.6This brings up Zeek and captures host traffic. The container runs and produces logs inside its own filesystem. Logs are NOT persisted: when the container is removed, all logs are lost.
A ready-to-use example is at docker-compose.example.yml.
services:
zeek:
image: activecm/zeek:8.0.6
container_name: zeek
restart: unless-stopped
network_mode: host
cap_add:
- NET_RAW
- NET_ADMIN
environment:
ZEEK_INTERFACE: eth0
volumes:
- /etc/localtime:/etc/localtime:ro
- /opt/zeek/logs:/usr/local/zeek/logs
- /opt/zeek/spool:/usr/local/zeek/spoolTo start it:
sudo docker compose up -dWhat the extra pieces do:
restart: unless-stoppedbrings the container back if it crashes or the host reboots.- The
/opt/zeek/logsand/opt/zeek/spoolmounts together persist logs to the host. Live log files are written to/usr/local/zeek/spool/<node>/, rotated.log.gzfiles are in/usr/local/zeek/logs/<date>/. Both mounts are needed to access both. - The
/etc/localtimemount makes log timestamps use the host timezone instead of UTC.
Multiple interfaces are specified by comma-separating: ZEEK_INTERFACE: eth0,eth1. To override the auto-detected worker count, add ZEEK_WORKERS: N. To use your own custom node.cfg instead of the env-var path, replace the ZEEK_INTERFACE env var with a bind mount: - /path/to/node.cfg:/usr/local/zeek/etc/node.cfg.
Only one Zeek container can run on the host at a time because of network_mode: host and Zeek's Prometheus telemetry binding to ports 9991 and 9992. If our CLI is already running a Zeek container, stop it first with zeek stop.
Stop the running container, replace the CLI binary, and start again:
zeek stop
tar xzf zeek-linux-amd64.tar.gz
sudo mv zeek /usr/local/bin/zeek
sudo zeek startYour node.cfg and networks.cfg are preserved. If you customized zeekctl.cfg or 100-default.zeek, your previous version is saved as .bak. Reapply your changes to the new file.
If the CLI warns about orphaned zkg volumes from an older version, see Migrating from older versions.
After confirming the new container is working, free up disk space by removing the old image:
sudo docker images activecm/zeek # show what's installed
sudo docker rmi activecm/zeek:6.2.1 # replace with the tag you hadmake build # build the CLI
make test # run unit tests
make test-integration # run integration tests
make lint # run linter
make docker-build # build the Docker image
make release # build release artifacts