Updated October 2026: rewritten for Suricata 8.0 on Ubuntu 24.04 LTS. The April 2023 version built Suricata 6.0, which reached end of life in August 2024. The package now lists every library it needs, builds with the same compiler hardening as the official package, adds AF_XDP capture and Suricata’s eBPF programs, and keeps apt from replacing it with Ubuntu’s own Suricata.
Suricata is published as source code and as ready-built packages, such as the RPM and DEB packages from Linux distributions and the OISF Ubuntu PPA. Those packages are the easy way to install and upgrade Suricata. They are built for the most common setups, though, so some features you may want are left out, and to get them you have to compile Suricata yourself.
One of IDSTower’s users needed Suricata to capture with Napatech NICs, a feature the standard packages don’t enable, and compiling Suricata by hand on every host of the cluster was too much work. They needed to compile it once and deploy it to the whole cluster with IDSTower’s User-Custom Packages Repository.
In this post we’ll build a Suricata .deb package that keeps every feature of the official Ubuntu package and adds what it leaves out for high-speed capture: eBPF and XDP support, and AF_XDP capture. For Rocky Linux, AlmaLinux and RHEL, see Building a Custom Suricata RPM Package.
The build setup
We used:
- Ubuntu 24.04 LTS (Noble Numbat), x86_64
- Suricata 8.0.7, the current stable release
Two things to know before you start:
- Build on the same OS release as your sensors. A .deb package depends on the library versions of the release it was built on, so a package built on Ubuntu 24.04 is for Ubuntu 24.04 hosts. For sensors on another release, run the same steps on that release. Suricata 8 needs Rust 1.75 or newer: Ubuntu 24.04 ships 1.75, while Debian 12 ships 1.63, so there you need a newer Rust from rustup. Check with
rustc --version. - Build on a build machine, not on a sensor. checkinstall packages Suricata by running
make installfor real and recording what it installs, so the machine that builds the package ends up with Suricata installed too. A VM or a container works well.
Building the Suricata .deb package
A .deb package is an archive of a program’s files, plus a description of the package: its name, its version, and the other packages it depends on. To build one, we download the Suricata source code, configure it with the features we want, compile it, and package the result. Run all the steps in the same shell, because later steps use variables that earlier ones set.
Compiling the source code
First, install the tools and libraries needed to build Suricata from source. This is the official Ubuntu package’s list of build dependencies, plus libelf-dev, libbpf-dev, clang and llvm for eBPF, and libxdp-dev for AF_XDP:
sudo apt update
sudo apt -y install build-essential pkg-config rustc cargo wget checkinstall \
libpcre2-dev libyaml-dev libjansson-dev libpcap-dev libcap-ng-dev \
libmagic-dev libnet1-dev libnetfilter-queue-dev libnss3-dev libnspr4-dev \
libmaxminddb-dev libhiredis-dev libevent-dev libhyperscan-dev \
liblz4-dev liblzma-dev zlib1g-dev libunwind-dev python3 python3-yaml \
libelf-dev libbpf-dev clang llvm libxdp-dev
Then create a directory for the build, and download and extract the source code into it:
SURICATA_VERSION=8.0.7
mkdir suricata_build
cd suricata_build/
wget https://www.openinfosecfoundation.org/download/suricata-$SURICATA_VERSION.tar.gz
tar xzf suricata-$SURICATA_VERSION.tar.gz
cd suricata-$SURICATA_VERSION/
Next, set the same compiler hardening flags the official package uses, such as stack protection and full RELRO. dpkg-buildflags prints Ubuntu’s standard set, and the official package adds bindnow and pie and turns off link-time optimization:
export DEB_BUILD_MAINT_OPTIONS="hardening=+pie,+bindnow optimize=-lto"
eval "$(dpkg-buildflags --export=sh)"
Now configure the build. These are the options the official Ubuntu package is built with, plus two for eBPF at the end: --enable-ebpf adds eBPF and XDP support, and --enable-ebpf-build uses clang to compile the eBPF programs that come with Suricata, for load balancing, flow bypass and XDP filtering. AF_XDP needs no option: configure turns it on when it finds libxdp.
./configure --prefix=/usr/ --sysconfdir=/etc/ --localstatedir=/var/ \
--enable-nfqueue --disable-gccmarch-native --enable-hiredis --enable-geoip \
--enable-gccprotect --enable-pie \
--enable-ebpf --enable-ebpf-build
The summary that configure prints at the end should show AF_XDP, eBPF and XDP support enabled:
Suricata Configuration:
AF_PACKET support: yes
AF_XDP support: yes
DPDK support: no
eBPF support: yes
XDP support: yes
Now compile Suricata, on every CPU core:
make -j"$(nproc)"
It takes a few minutes, depending on the machine. You’ll see many "_FORTIFY_SOURCE" redefined warnings: the hardening flags and --enable-gccprotect both set it, as they do when the official package is built. They are harmless.
Creating the DEB package
To create the package, we’ll use checkinstall, one of the easiest ways to turn compiled source code into a .deb or .rpm package.
Suricata’s make install doesn’t install the eBPF programs, so copy them to /usr/libexec/suricata/ebpf/, where Suricata’s eBPF guide puts them. Then list the directories for checkinstall to include in the package, along with the configuration and log directories:
sudo mkdir -p /usr/libexec/suricata/ebpf
sudo cp ebpf/*.bpf /usr/libexec/suricata/ebpf/
echo "/etc/suricata" > suricata_extra_files
echo "/var/log/suricata" >> suricata_extra_files
echo "/usr/libexec/suricata/ebpf" >> suricata_extra_files
The package also has to name the libraries Suricata needs, so that apt installs them along with it on every host. Rather than typing the list in, let dpkg-shlibdeps work it out from the compiled program, which is how the official package gets its list. It needs an empty debian/control file to run. Suricata’s rule updater, suricata-update, is written in Python, so it also needs python3 and python3-yaml:
mkdir -p debian && touch debian/control
SURICATA_DEPENDS="$(dpkg-shlibdeps -O src/suricata | sed -e 's/^shlibs:Depends=//' -e 's/ ([^)]*)//g'), python3, python3-yaml"
echo "$SURICATA_DEPENDS"
dpkg-shlibdeps prints a few warnings about diversions and about the program not being installed yet, which are expected here. The sed removes the version constraints, such as (>= 2.38), because checkinstall drops a dependency list that contains them: it prints a shell syntax error, carries on, and builds a package with no dependencies. The library package names already include each library’s version, so the package still matches this release. You should see:
libbpf1, libc6, libcap-ng0, libevent-2.1-7t64, libevent-pthreads-2.1-7t64, libhiredis1.1.0, libhyperscan5, libjansson4, liblz4-1, libmagic1t64, libmaxminddb0, libnet1, libnetfilter-queue1, libnfnetlink0, libpcap0.8t64, libpcre2-8-0, libunwind8, libxdp1, libyaml-0-2, zlib1g, python3, python3-yaml
Now build the package:
sudo checkinstall -y -D --install=no --fstrans=no --backup=no \
--pkgname=suricata --pkgversion=1:$SURICATA_VERSION --pkgrelease=1 \
--exclude=/home,/root --include=./suricata_extra_files \
--requires="$SURICATA_DEPENDS" \
make install install-conf
The 1: at the start of the version is an epoch. Ubuntu’s own Suricata package is version 1:7.0.3, and apt ranks any version with epoch 1 above every version without an epoch. Without it, apt would treat Ubuntu’s older Suricata as an upgrade and replace your build the next time you run apt upgrade. The official PPA versions its packages the same way.
checkinstall writes the package to the source directory, as suricata_8.0.7-1_amd64.deb; the epoch isn’t part of the file name.
Installing and checking the package
Copy the package to a host running the same release, and install it. apt installs the libraries it depends on from the host’s repositories:
sudo apt install -y ./suricata_8.0.7-1_amd64.deb
Then check that AF_XDP, eBPF and XDP support are enabled:
$ suricata --build-info
This is Suricata version 8.0.7 RELEASE
Features: NFQ PCAP_SET_BUFF AF_PACKET HAVE_PACKET_FANOUT LIBCAP_NG LIBNET1.1 HAVE_HTP_URI_NORMALIZE_HOOK PCRE_JIT HAVE_NSS HTTP2_DECOMPRESSION HAVE_LUA HAVE_JA3 HAVE_JA4 HAVE_LIBJANSSON TLS TLS_C11 MAGIC RUST POPCNT64
...
Suricata Configuration:
AF_PACKET support: yes
AF_XDP support: yes
DPDK support: no
eBPF support: yes
XDP support: yes
PF_RING support: no
NFQueue support: yes
...
The eBPF programs are in /usr/libexec/suricata/ebpf/. To use one, point the af-packet section of suricata.yaml at it, for example ebpf-lb-file: /usr/libexec/suricata/ebpf/lb.bpf with cluster-type: cluster_ebpf. Suricata’s eBPF and XDP guide covers each program.
AF_XDP is a capture method of its own, next to AF_PACKET: start Suricata with --af-xdp=<interface>, or set it up in the af-xdp section of suricata.yaml, as Suricata’s AF_XDP guide explains. Suricata starts one AF_XDP capture thread per receive queue that the network card reports, up to the number of CPU cores, so it needs a card whose driver reports its queues. A container’s virtual interface reports none: Suricata logs af-xdp: 0 queues, so using 0 threads and captures nothing.
Building with other features
The same steps enable other features that the official packages leave out, such as Napatech and PF_RING support: install the vendor’s driver and libraries on the build machine, and add the option to the ./configure line (--enable-napatech or --enable-pfring). The vendor’s libraries don’t come from an Ubuntu package, so the package won’t install them: install the vendor’s driver on every sensor as well.
How IDSTower can help
IDSTower deploys your package to every host of a cluster with its User-Custom Packages Repository:
- Copy the package and its dependencies once. Put them on the IDSTower server, in a folder named after the Suricata version and the hosts’ OS release and architecture:
/opt/idstower/custom/Suricata/packages/8.0.7/Ubuntu24/x86_64/. Version 8.0.7 then shows up in the cluster setup wizard. - IDSTower installs them on every host, including hosts without internet access, and checks that each host reports the version you picked. It then runs Suricata under its own configuration and services, alongside health monitoring and rule life-cycle management, from one web interface.
To collect the dependency packages, run this on a host set up like your sensors, with the same release and without Suricata, then copy the .deb files from /var/cache/apt/archives/ into the folder, next to your package:
sudo apt-get clean
sudo apt-get install --download-only -y ./suricata_8.0.7-1_amd64.deb
Try it in the live demo (no signup), or get a free license.
