Installing Suricata 6.0.1 Release with pf_ring on Ubuntu 18.04 with customization, I will update this post with the specific set we are enabling, but so far IPS is not on the list.

Features: nDPI 3.4, PF_Ring 7.8, Luijit, Redis, GeoIP, eBPF, Profiling, Debug

In using pf_ring, we get access to a feature set that lowers the hit to CPU, in a variety of ways (pre-process, post-process, aligning threads to rings/buffers from/to the NIC and its buffers). It can do this in other ways too, with more or less, two additional feature sets, Flow Table and Zero Copy. Both of these cost money. While I walk you through installing and setting up features that enable FT, I will be staying away from a ZC build here. The FT allows you to skip over large bandwidth traffic flows, ZC uses unique features of our different methods of transmitting network traffic, and optimizes the path around the Kernel to reduce the impact of some seriously heavy data (10G+). As ZC requires very specific NICs and even though one of them is available on ESXi 6.7u3 (e1000e)

Let’s Get Started!! We need a VM or Baremetal Ubuntu 18.04 host

Install the latest Ubuntu 18.04 (non-HWE) from ISO…

Likely unnecessary prerequisites:

sudo apt-get install software-properties-common wget
sudo add-apt-repository universe

Turn on and enable the sniff interface:

sudo vim /etc/netplan/<distroconfname>.yaml

Set the appropriate IP on your “management” interface, then, and I’m still re-figuring this out, but, you will at least want to disable DHCP4 and DHCP6…

Get the “sniff” interface up and set each time:

sudo vim /etc/network/if-up.d/suricata

ISSUE: This appears to make the host take very long to restart, considering not using netplan as it has limitations… that said… Enter appropriate options for your network, promisc will be important as it is going to operate transparently and should just accept all traffic:

ip link set ens192 promisc on
ip link set ens192 mtu 9000

Now to get PF_RING and other dependencies installed!

Get ntop package management:

sudo apt install ./apt-ntop-stable.deb
sudo apt-get update

Install PFRing-DKMS:

sudo apt-get install pfring-dkms pfring

Note the GIT version and/or release specified, we will need to build those libraries. You can also find the git branch using this command:

sudo apt-cache search pfring-dkms

Example reply:

pfring-dkms - PF_RING driver in DKMS format. GIT info: 7.8.0-stable:63c0c90a830d14c1050950dedb44e5d0a6c46ad6

Install nDPI via Git (this wasn’t necessary previously, it seems Ntop has done interesting things with version and it can make things incompatible)

sudo apt-get install build-essential git bison flex libpcap-dev libtool libtool-bin autoconf pkg-config automake autogen libjson-c-dev libnuma-dev libgcrypt20-dev libpcre2-dev
mkdir git && cd git/
git clone
cd nDPI
git checkout 64929a75e0a7a60d864bd25a9fd97fdf9ac892a2 # 3.4 RELEASE
make && sudo make install

Install dependencies:

sudo apt-get install build-essential bison flex linux-headers-$(uname -r)
sudo apt-get install libtool automake autoconf

Setup pf_ring libs:

git clone

Remember the part earlier where I said we would need to note the git/RELEASE version? Enter that version after the “git checkout “, currently it is “7.8.0-stable”

cd PF_RING && git checkout 7.8.0-stable
cd userland/lib
./configure && make && sudo make install
cd ~/git/

Install dependencies:

sudo apt-get install libpcre3 libpcre3-dbg libpcre3-dev build-essential libpcap-dev libnet1-dev libyaml-0-2 libyaml-dev pkg-config zlib1g zlib1g-dev libcap-ng-dev libcap-ng0 make libmagic-dev libjansson-dev libnss3-dev libgeoip-dev liblua5.1-dev libhiredis-dev libevent-dev python-yaml rustc cargo autoconf
sudo apt-get install python3-distutils
sudo apt-get install liblz4-dev
sudo apt-get install libmaxminddb-dev
sudo apt-get install libc6-dev-i386
sudo apt-get install libtcmalloc-minimal4 cargo install cbindgen

Add “~/.cargo/bin” to $PATH:

export PATH="/home/$(whoami)/.cargo/bin:$PATH"

Get luajit installed:

git clone
cd luajit-2.0/
make && sudo make install
cd ~/git/

Ensure Redis Support:

sudo apt-get install libhiredis-dev libevent-dev libevent-pthreads-2.1-6


sudo apt-get install clang libelf-dev
sudo apt-get install libc6-dev-i386 --no-install-recommends
git clone
cd libbpf/src/
make && sudo make install
sudo make install_headers
echo '/usr/lib64' | sudo tee -a /etc/ > /dev/null
sudo ldconfig
cd ~/git/

Adding extra details about manually building libhtp (this may not be necessary, I’ll update in the future if not)

sudo apt-get install doxygen
sudo apt-get install lcov
git clone
cd libhtp/
make && sudo make-install
cd ~/git/

Get suricata-update installed:

sudo apt-get install python3-pip
sudo python3 -m pip install suricata-update
sudo ln -s /usr/local/bin/suricata-update /usr/bin/suricata-update

You may have to:

echo '/usr/local/lib' | sudo tee -a /etc/ > /dev/null
sudo ldconfig

Continue with cloning and compiling Suricata:

git clone
cd suricata/
git checkout e860b9eee96cb112a45151237d4b23fd0a9efb22 # Suricata 6.0.1 RELEASE ./ LIBS="-lrt" ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var --enable-profiling --enable-debug --enable-hiredis --enable-non-bundled-htp --enable-luajit --enable-geoip --enable-ebpf --enable-ebpf-build --enable-rust --with-clang=/usr/bin/clang --enable-pfring --with-libpfring-includes=/usr/local/include --with-libpfring-libraries=/usr/local/lib --with-libluajit-includes=/usr/local/include/luajit-2.0/ --with-libluajit-libraries=/usr/lib/ CFLAGS="-ggdb -O0" make && sudo make install sudo make install-conf
sudo suricata-update

Create Service and set environment options!!

Create Service File:

sudo cp ~/git/suricata/etc/suricata.service /etc/systemd/system/
sudo chown root: /etc/systemd/system/suricata.service

Edit Service File to Uncomment platform specific defaults location:

sudo vim /etc/systemd/system/suricata.service

Now we use some of the features we’ve built into our binary. In the future I will hopefully write something about redis.

Edit as such (for Ubuntu/Debian, otherwise uncomment other “EnvironmentFile” line) and mind your options when starting the binary, and path, some environments have likely shifted your contents:

ExecStart=/usr/bin/suricata --pfring-int=eth1 --pfring-cluster-id=99 --pfring-cluster-type=cluster_flow -c /etc/suricata/suricata.yaml --pidfile /var/run/ $OPTIONS

Note: To use PF_RING, you will need to edit the interface of the PF_RING element in /etc/suricata/suricata.yaml to the proper interface name, here I’ve used “eth1”.

Create Suricata Defaults File:

sudo touch /etc/default/suricata
sudo vim /etc/default/suricata

Edit as such:

# Configuration file for the suricata service.
#from /etc/sysconfig
OPTIONS="-S /var/lib/suricata/rules/suricata.rules --init-errors-fatal"
# If you have a PF_RING FT license then un-comment the next line

You may need to fix rules location (it doesn’t seem $OPTIONS gets passed on the init):

sudo vim /etc/suricata/suricata.yaml

Edit as such (approx line number 1865):

default-rule-path: /var/lib/suricata/rules/


sudo ln -s /var/lib/suricata/rules/suricata.rules /etc/suricata/rules/suricata.rules

PF_RING – Create slots:

sudo vim /etc/pf_ring/pf_ring.conf

Enter as such:


PF_RING – Set interfaces:

sudo vim /etc/pf_ring/interfaces.conf

Enter as such:


You should be able to test your config now:

sudo suricata -v -T -c /etc/suricata/suricata.yaml

sudo /usr/bin/suricata --pfring-int=eth1 --pfring-cluster-id=99 --pfring-cluster-type=cluster_flow -c /etc/suricata/suricata.yaml --dump-config

sudo /usr/bin/suricata --pfring-int=eth1 --pfring-cluster-id=99 --pfring-cluster-type=cluster_flow -c /etc/suricata/suricata.yaml --dump-features

sudo suricata --list-runmodes

sudo suricata --build-info

If you are running this in an ESXi and/or your doing this via port mirror on your switch, then you might have some VLAN oddities. In ESXi 6.7 there’s a little known trick with setting the VLAN for your Sniff Switch/Ports to 4095. This, plus not making the VLAN a significant flow feature (it is a suricata.yaml option…) in Suricata is vital.

use-for-tracking: false

One of the only things I’m not detailing here is the actual suricata.yaml file and that is because I’m still learning it and there are other blog posts specifically about that, even one I saw about going from snort -> suricata.


Hope this helps someone, and be well.

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.