This is part of the Zeekurity Zen Zeries on building a Zeek (formerly Bro) network sensor.
Overview
This guide assumes you’ll be installing Zeek on Ubuntu 22.04 LTS. However, the guide should work for any reasonably recent versions of Ubuntu.
Kicking things off, we’ll optimize Ubuntu to efficiently capture packets and then compile Zeek from source to start monitoring network traffic.
To do this, we’ll walkthrough these steps:
- Minimize packet loss and ensure Zeek sees full packet data by applying network sniffing optimizations: settings max ring parameters, disabling NIC offloading, and enabling promiscuous mode.
- Build Zeek from source with optimizations.
- Create a non-root Zeek user to minimize impact in the event that Zeek is compromised.
- Deploy and run Zeek to start analyzing traffic.
- Create a cron job to perform Zeek maintenance tasks.
Set max ring parameters
- Use ethtool to determine the maximum ring parameters for your sniffing interfaces. The example below assumes an interface named enp2s0.
sudo ethtool -g enp2s0 Ring parameters for enp2s0: Pre-set maximums: RX: 4096 RX Mini: 0 RX Jumbo: 0 TX: 4096 Current hardware settings: RX: 256 RX Mini: 0 RX Jumbo: 0 TX: 256
- As root/sudo, create a new file in /etc/networkd-dispatcher/routable.d/10-set-max-ring and add the following lines for each sniffing interface.
#!/bin/sh # Set ring rx parameters for all sniffing interfaces ethtool -G enp2s0 rx 4096
- Save the file and set its permissions to 755.
sudo chmod 755 /etc/networkd-dispatcher/routable.d/10-set-max-ring
Disable NIC offloading functions
- As root/sudo, create a new file in /etc/networkd-dispatcher/routable.d/20-disable-checksum-offload and add the following lines for each sniffing interface.
#!/bin/sh # Disable checksum offloading for all sniffing interfaces ethtool -K enp2s0 rx off tx off sg off tso off ufo off gso off gro off lro off
- Save the file and set its permissions to 755.
sudo chmod 755 /etc/networkd-dispatcher/routable.d/20-disable-checksum-offload
Set sniffing network interfaces to promiscuous mode
- As root/sudo, create a new file in /etc/networkd-dispatcher/routable.d/30-enable-promisc-mode and add the following lines for each sniffing interface.
#!/bin/sh # Enable promiscuous mode for all sniffing interfaces ip link set enp2s0 arp off multicast off allmulticast off promisc on
- Save the file and set its permissions to 755.
sudo chmod 755 /etc/networkd-dispatcher/routable.d/30-enable-promisc-mode
Confirm changes are persistent
- Reboot your system and verify all the changes made thus far have persisted.Verify max ring parameters under Current hardware settings RX matches the configured maximum.
sudo ethtool -g enp2s0 Ring parameters for enp2s0: Pre-set maximums: RX: 4096 RX Mini: 0 RX Jumbo: 0 TX: 4096 Current hardware settings: RX: 4096 RX Mini: 0 RX Jumbo: 0 TX: 256
Verify NIC offloading features are turned off (this list is likely much longer on your system).
sudo ethtool -k enp2s0 Features for enp2s0: rx-checksumming: off tx-checksumming: off
Verify that PROMISC is listed in the network interface status.
ip a show enp2s0 | grep -i promisc 3: enp2s0: <BROADCAST,NOARP,PROMISC,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
Install Zeek Dependencies
- Run the following apt command to download the required dependencies.
sudo apt-get install cmake make gcc g++ flex bison libpcap-dev libssl-dev python3 python3-dev python3-git python3-semantic-version swig zlib1g-dev libjemalloc-dev
- Ensure all your packages are up to date and reboot your system.
sudo apt-get update sudo apt-get dist-upgrade sudo reboot
Create the zeek user and directory to install and run Zeek
- Create the zeek user and add it to the zeek group.
sudo groupadd zeek sudo adduser zeek sudo usermod -aG zeek zeek
- As root/sudo, set a password for the zeek user.
sudo passwd zeek
- As root/sudo, create the /opt/zeek directory and set ownership to the zeek user.
sudo mkdir /opt/zeek sudo chown -R zeek:zeek /opt/zeek sudo chmod 750 /opt/zeek
Download, Compile, and Install Zeek
- Switch to the zeek user.
su zeek
- We will download zeek to the /home/zeek directory. Then we will configure Zeek to install in the /opt/zeek directory and enable jemalloc to improve memory and CPU usage. As of this writing, the latest feature release is version 6.0.1. If the download URL referenced in the wget command below no longer works, you can download the latest stable release directly from the Get Zeek download page.
cd wget https://download.zeek.org/zeek-6.0.1.tar.gz tar -xzvf zeek-6.0.1.tar.gz cd zeek-6.0.1 ./configure --prefix=/opt/zeek --enable-jemalloc --build-type=release make make install
Note: This will take *a while* to compile.
- Switch back to your normal user by closing the zeek session.
exit
- Since the zeek user is not root, give the Zeek binaries permissions to capture packets.
sudo setcap cap_net_raw=eip /opt/zeek/bin/zeek sudo setcap cap_net_raw=eip /opt/zeek/bin/capstats
Add Zeek to PATH
- Switch back to the zeek user.
su zeek
- As the zeek user, create ~/.bashrc and add the following lines.
# Add Zeek to PATH export PATH="/opt/zeek/bin:$PATH"
- Save the file and apply the new path to the zeek user.
source ~/.bashrc
Configure Zeek
- Edit /opt/zeek/etc/node.cfg to configure the number of nodes. It is recommended to use a maximum of one or two less workers than the total number of CPU cores available on your sensor. In the example configuration below we are configuring a total of two workers, analyzing one sniffing interface.
Note: The following node configuration does not use Zeek’s out of the box support for AF_PACKET (as of version 5.2). It is recommended to configure Zeek to use AF_PACKET for optimal packet capture and the configuration is covered in Part II.# Example ZeekControl node configuration. # Below is an example clustered configuration on a single host. [logger] type=logger host=localhost [manager] type=manager host=localhost [proxy-1] type=proxy host=localhost [worker-1] type=worker host=localhost interface=enp2s0 [worker-2] type=worker host=localhost interface=enp2s0
In the event you have two or more sniffing interfaces (e.g. enp2s0 and enp3s0), see the example configuration below which assigns each interface its own worker.
# Example ZeekControl node configuration. # Below is an example clustered configuration on a single host. [logger] type=logger host=localhost [manager] type=manager host=localhost [proxy-1] type=proxy host=localhost [worker-1] type=worker host=localhost interface=enp2s0 [worker-2] type=worker host=localhost interface=enp3s0
- Edit /opt/zeek/share/zeek/site/local.zeek to enable or disable scripts as needed.
Start Zeek
- As the zeek user, run zeekctl deploy to apply configurations and run Zeek.
zeekctl deploy checking configurations ... installing ... removing old policies in /opt/zeek/spool/installed-scripts-do-not-touch/site ... removing old policies in /opt/zeek/spool/installed-scripts-do-not-touch/auto ... creating policy directories ... installing site policies ... generating cluster-layout.zeek ... generating local-networks.zeek ... generating zeekctl-config.zeek ... generating zeekctl-config.sh ... stopping ... stopping workers ... stopping proxy ... stopping manager ... stopping logger ... starting ... starting logger ... starting manager ... starting proxy ... starting workers ...
- If your output looks similar to what’s shown above, you should be good to go. To verify Zeek is running successfully, you can run zeekctl status.
zeekctl status Name Type Host Status Pid Started logger logger localhost running 1774 10 Oct 23:15:31 manager manager localhost running 1820 10 Oct 23:15:32 proxy-1 proxy localhost running 1865 10 Oct 23:15:33 worker-1-1 worker localhost running 1950 10 Oct 23:15:35 worker-1-2 worker localhost running 1951 10 Oct 23:15:35 worker-2-1 worker localhost running 1955 10 Oct 23:15:35 worker-2-2 worker localhost running 1954 10 Oct 23:15:35
If you see the following errors:
zeekctl deploy Error: worker-1-1 terminated immediately after starting; check output with "diag" Error: worker-1-2 terminated immediately after starting; check output with "diag" Error: worker-2-1 terminated immediately after starting; check output with "diag" Error: worker-2-2 terminated immediately after starting; check output with "diag"
Then try re-running the sudo setcap commands from earlier.
sudo setcap cap_net_raw=eip /opt/zeek/bin/zeek sudo setcap cap_net_raw=eip /opt/zeek/bin/capstats
- You should now see logs being generated in /opt/zeek/logs/current.
ls -l total 2276 -rw-rw-r--. 1 zeek zeek 1573 Oct 10 23:15 broker.log -rw-rw-r--. 1 zeek zeek 593 Oct 10 23:45 capture_loss.log -rw-rw-r--. 1 zeek zeek 1970 Oct 10 23:15 cluster.log -rw-rw-r--. 1 zeek zeek 673435 Oct 10 23:52 conn.log -rw-rw-r--. 1 zeek zeek 580865 Oct 10 23:52 dns.log -rw-rw-r--. 1 zeek zeek 3830 Oct 10 23:49 dpd.log -rw-rw-r--. 1 zeek zeek 1406 Oct 10 23:47 files.log -rw-rw-r--. 1 zeek zeek 26108 Oct 10 23:48 http.log -rw-rw-r--. 1 zeek zeek 24646 Oct 10 23:15 loaded_scripts.log -rw-rw-r--. 1 zeek zeek 753 Oct 10 23:18 notice.log -rw-rw-r--. 1 zeek zeek 187 Oct 10 23:15 packet_filter.log -rw-rw-r--. 1 zeek zeek 743 Oct 10 23:46 software.log -rw-rw-r--. 1 zeek zeek 86512 Oct 10 23:51 ssl.log -rw-rw-r--. 1 zeek zeek 5446 Oct 10 23:50 stats.log -rw-rw-r--. 1 zeek zeek 0 Oct 10 23:15 stderr.log -rw-rw-r--. 1 zeek zeek 188 Oct 10 23:15 stdout.log -rw-rw-r--. 1 zeek zeek 240866 Oct 10 23:51 weird.log
- If you’re running into issues, zeekctl diag can provide more detailed output for troubleshooting purposes.
zeekctl diag
ZeekControl Cron
ZeekControl features a cron command to check for and restart crashed nodes and to perform other maintenance tasks. To take advantage of this, let’s set up a cron job.
- Edit the crontab of the non-root zeek user.
crontab -e
- Add the following to set up a cron job that runs every five minutes. You can adjust the frequency to your liking.
*/5 * * * * /opt/zeek/bin/zeekctl cron
Up Next
In Part II of this series, we will install the Zeek Package Manager to extend Zeek’s functionality.
References
Zeek official documentation: https://www.zeek.org/documentation/index.html
NIC offloading on Ubuntu with systemd-networkd: https://michael.mulqueen.me.uk/2018/08/disable-offloading-netplan-ubuntu/
NIC offloading: https://blog.securityonion.net/2011/10/when-is-full-packet-capture-not-full.html