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:
wget http://apt-stable.ntop.org/18.04/all/apt-ntop-stable.deb 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 https://github.com/ntop/nDPI.git
cd nDPI
git checkout 64929a75e0a7a60d864bd25a9fd97fdf9ac892a2 # 3.4 RELEASE
./autogen.sh
./configure
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 https://github.com/ntop/PF_RING.git
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 https://luajit.org/git/luajit-2.0.git 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
Get BPF
sudo apt-get install clang libelf-dev
sudo apt-get install libc6-dev-i386 --no-install-recommends
git clone https://github.com/libbpf/libbpf.git
cd libbpf/src/
make && sudo make install
sudo make install_headers
echo '/usr/lib64' | sudo tee -a /etc/ld.so.conf.d/libbpf > /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 https://github.com/OISF/libhtp.git
cd libhtp/
./autogen.sh
./configure
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/ld.so.conf.d/usrlocallib > /dev/null
sudo ldconfig
Continue with cloning and compiling Suricata:
git clone https://github.com/OISF/suricata cd suricata/
git checkout e860b9eee96cb112a45151237d4b23fd0a9efb22 # Suricata 6.0.1 RELEASE ./autogen.sh 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:
[Service] ... EnvironmentFile=-/etc/default/suricata
...
ExecStart=/usr/bin/suricata --pfring-int=eth1 --pfring-cluster-id=99 --pfring-cluster-type=cluster_flow -c /etc/suricata/suricata.yaml --pidfile /var/run/suricata.pid $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
LD_PRELOAD="/usr/lib/x86_64-linux-gnu/libtcmalloc_minimal.so.4"
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
#PF_RING_FT_CONF="/etc/pf_ring/ft-rules.conf"
You may need to fix rules location (it doesn’t seem $OPTIONS gets passed on the init):
Either:
sudo vim /etc/suricata/suricata.yaml
Edit as such (approx line number 1865):
default-rule-path: /var/lib/suricata/rules/
-or-
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:
min_num_slots=65536
PF_RING – Set interfaces:
sudo vim /etc/pf_ring/interfaces.conf
Enter as such:
MANAGEMENT_INTERFACES="eth0"
CAPTURE_INTERFACES="eth1"
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.
vlan:
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.
Thanks!
Hope this helps someone, and be well.