Skip to content

Install Suricata

Install a recorded Suricata package set and prove service health, capture, and configuration before loading detection content.

Machine: Ubuntu sensorUser: sudo administratorStarting point: isolated VM plus matching connected preparation VM

Use the official Suricata documentation as the authority for current packages, capture methods, configuration, and version-specific requirements.

Prepare a reproducible package bundle

Use connected and isolated machines with the same Ubuntu release and architecture. Record <SURICATA_VERSION>, package sources, filenames, checksums, and validation date. The detailed procedure below retains the exact Suricata 7.0.6 package list demonstrated in the PoC.

Avoid pinning individual base libraries such as libc6 unless you are reproducing a matching snapshot repository. Download dependencies into a dedicated APT cache and verify them before transfer:

mkdir -p "$HOME/suricata-bundle/apt-archives"
sudo apt-get update
sudo apt-get install --download-only \
  -o Dir::Cache::archives="$HOME/suricata-bundle/apt-archives" \
  suricata suricata-update jq ethtool tcpdump

cd "$HOME/suricata-bundle"
find apt-archives -type f -print0 | sort -z | xargs -0 sha256sum > SHA256SUMS
sha256sum --check SHA256SUMS
tar -czf suricata-package-bundle.tar.gz apt-archives SHA256SUMS
sha256sum suricata-package-bundle.tar.gz

Test the bundle on a clean matching VM. After approved transfer, verify the outer archive and manifest, then let APT order the local dependencies:

mkdir -p "$HOME/suricata-bundle"
tar -xzf suricata-package-bundle.tar.gz -C "$HOME/suricata-bundle"
cd "$HOME/suricata-bundle"
sha256sum --check SHA256SUMS
sudo apt install ./apt-archives/*.deb

If APT reports a missing dependency, stop and rebuild the connected bundle. Do not treat a partially successful dpkg -i * run as completion.

Detailed host installation

The demonstrated air-gapped workflow is retained in full below. Its explicit package list records the Suricata 7.0.6 environment; use the reproducible bundle workflow above for a new build so dependency versions come from one matching repository snapshot.

In this demonstration, we will be installing Suricata on the Ubuntu virtual machine. We will be simulating install in an air-gapped environment but note that some parts of the step requires internet connection.

On a Ubuntu machine with internet access Add the necessary repository for Suricata:

sudo apt-get install software-properties-common
sudo add-apt-repository ppa:oisf/suricata-stable
sudo apt-get update

Create a directory to store Suricata. Adjust the directory permissions:

sudo mkdir ~/suricata-offline
cd ~/suricata-offline
sudo chmod 755 ~/suricata-offline

Download the Suricata package and all its dependencies:

Download the Emerging Threats Open rule set:

sudo apt-get download suricata
sudo wget https://rules.emergingthreats.net/open/suricata-7.0.6/emerging.rules.tar.gz

Create a directory to store dependencies. Adjust the directory permissions:

sudo mkdir dependencies
cd dependencies
sudo chmod 755 ~/suricata-offline/dependencies

Download the required dependencies

sudo apt-get download autoconf automake build-essential cargo cbindgen \
    libjansson-dev libpcap-dev libpcre2-dev libtool libyaml-dev make \
    pkg-config rustc zlib1g-dev libc6-dev gcc g++ dpkg-dev binutils \
    libpcre2-16-0 libpcre2-posix3 libdpkg-perl libstd-rust-dev libssh2-1 \
    libpcap0.8-dev m4 autotools-dev binutils-common libbinutils \
    binutils-x86-64-linux-gnu g++-11 gcc-11 libc-dev-bin linux-libc-dev \
    libcrypt-dev rpcsvc-proto libtirpc-dev libnsl-dev libdbus-1-dev \
    libstd-rust-1.75 libctf-nobfd0 libctf0 lto-disabled-list libstdc++-11-dev \
    libcc1-0 libgcc-11-dev libsigsegv2 libc6=2.35-0ubuntu3.8 libitm1 \
    libasan6 liblsan0 libtsan0 libubsan1 libquadmath0 \
    libevent-pthreads-2.1-7 libhiredis0.14 libhtp2 libhyperscan5 \
    libluajit-5.1-2 libnet1 libnetfilter-queue1 libluajit-5.1-common \
    liblzma-dev libevent-core-2.1-7 curl jq libcurl4=7.81.0-1ubuntu1.17 libjq1=1.6-2.1ubuntu3 libonig5 libc6-dbg libc6 zlib1g

Transfer suricata-offline folder to /opt directory in Ubuntu machine without internet access.

Install dependencies and suricata

cd /opt/suricata-offline/dependencies
sudo dpkg -i *

Install Suricata

cd /opt/suricata-offline/
sudo dpkg -i suricata_1%3a7.0.6-0ubuntu2_amd64.deb

After installing Suricata, you can check which version of Suricata you have running and with what options, as well as the service state:

The demonstrated lab observed an exited service state. Do not treat that as a healthy long-running IDS service. A normally managed Suricata service should report active (running); inspect journalctl -u suricata and /var/log/suricata/suricata.log if it exits or fails.

sudo suricata --build-info
sudo systemctl status suricata

Configure capture

Identify the actual sensor interface and confirm that it receives the intended traffic:

ip -brief address
ip -s link show <SENSOR_INTERFACE>
sudo tcpdump -ni <SENSOR_INTERFACE> -c 20

Back up /etc/suricata/overview.yaml, set HOME_NET to the networks visible at this sensor, select the intended AF_PACKET interface, and enable Community ID. Do not copy the historical ens32 name or 10.0.0.0/24 value without checking your topology.

vars:
  address-groups:
    HOME_NET: "[<PROTECTED_CIDR>]"

community-id: true

af-packet:
  - interface: <SENSOR_INTERFACE>
    cluster-id: 99
    cluster-type: cluster_flow
    defrag: yes
    use-mmap: yes

Record receive-offload settings and change them only when required by the selected capture design:

sudo ethtool -k <SENSOR_INTERFACE> | grep receive-offload

Demonstrated interface configuration

The following configuration shows how the PoC identified ens32, defined HOME_NET, and enabled AF_PACKET, PCAP, memory-mapped capture, and Community ID. Replace the demonstrated interface and network with values from your lab.

First, determine the interface(s) and IP address(es) on which Suricata should be inspecting network packets:

ip a
...
2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:0c:29:51:ef:1b brd ff:ff:ff:ff:ff:ff
    altname enp2s0
    inet 10.0.0.25/24 brd 10.0.0.255 scope global noprefixroute ens32

Use that information to configure Suricata:

sudo nano /etc/suricata/suricata.yaml

Specify internal network in the HOME_NET

Specify network interface in af-packet and pcap.

Set use-mmap to yes.

Set community-id to true

vars:
  # more specific is better for alert accuracy and performance
  address-groups:
    HOME_NET: "[10.0.0.0/24]"
...
community-id: true
...
af-packet:
    - interface: ens32
      cluster-id: 99
      cluster-type: cluster_flow
      defrag: yes
      use-mmap: yes
...
# Cross platform libpcap capture support
pcap:
  - interface: ens32

 checksum-validation: no

Validate the installation

sudo suricata --build-info
sudo suricata -T -c /etc/suricata/overview.yaml -v
sudo systemctl restart suricata
sudo systemctl status suricata --no-pager
sudo journalctl -u suricata --since today --no-pager
sudo tail -n 30 /var/log/suricata/overview.log

Expected: configuration validation succeeds, the intended capture support is listed, and the service reports active (running). An exited, failed, or restart-looping service is not normal IDS operation; inspect the journal and Suricata log before continuing.

Check capture and drop counters after generating authorised traffic:

sudo tail -n 2 /var/log/suricata/stats.log
sudo jq 'select(.event_type=="stats") | .stats.capture' /var/log/suricata/eve.json | tail -n 20

Run and monitor Suricata

The demonstrated runtime procedure shows the service restart, engine-started message, and continuously updated stats.log evidence.

With the rules installed, Suricata can run properly and thus we restart it:

sudo systemctl restart suricata

To make sure Suricata is running check the Suricata log:

sudo tail /var/log/suricata/suricata.log

The last line will be similar to this:

5933 - Suricata-Main] 2024-09-12 13:26:11 Notice: threads: Threads created -> W: 2 FM: 1 FR: 1   Engine started.

The actual thread count will depend on the system and the configuration.

To see statistics, check the stats.log file:

sudo tail -f /var/log/suricata/stats.log

By default, it is updated every 8 seconds to show updated values with the current state, like how many packets have been processed and what type of traffic was decoded.

Completion criteriaThe installed versions and checksums are recorded, configuration validates, the service stays active, and capture counters increase without unexplained drops.