Skip to content

Install Snort 3

Build a reproducible Snort 3 sensor and verify the engine, configuration and capture modules before loading detection content.

Machine: Ubuntu sensorUser: sudo administratorStarting point: isolated VM with temporary package-preparation access

Before you begin

Use the official Snort installation guide and official downloads as the authority for current dependencies and compatibility. Do not substitute the historical PoC versions without revalidating them.

Create a build record containing <SNORT_VERSION>, <LIBDAQ_VERSION>, OS, architecture, source URLs, checksums and validation date. On an internet-connected preparation machine, verify downloads before transfer:

sha256sum <SNORT_ARCHIVE> <LIBDAQ_ARCHIVE> > snort-transfer.sha256
sha256sum --check snort-transfer.sha256

Keep build and runtime privileges separate

Compile as an unprivileged user. Use sudo only for package installation, the final install step and narrowly scoped system configuration. Do not run Snort permanently as the interactive build user.

Historical PoC build

The original lab used Ubuntu 22.04 LTS, Snort 3.3.5.0, LibDAQ 3.0.16, Hyperscan 5.4.2, PCRE2 10.44, FlatBuffers 2.0.0, gperftools 2.15, Ragel 6.10 and Boost 1.86.0. These versions are retained for reproducibility, not as a recommendation for new deployments. Retain snort -V output because it proves which libraries the engine actually loaded.

Prepare a connected build bundle

Use a connected Ubuntu machine with the same release and architecture as the offline sensor. Mixing packages collected on a different release commonly causes unsatisfied versions during installation.

mkdir -p "$HOME/snort-build/apt-archives" "$HOME/snort-build/sources"
sudo apt-get update
sudo apt-get install --download-only \
  -o Dir::Cache::archives="$HOME/snort-build/apt-archives" \
  build-essential autotools-dev libdumbnet-dev libluajit-5.1-dev \
  libpcap-dev zlib1g-dev pkg-config libhwloc-dev cmake liblzma-dev \
  openssl libssl-dev cpputest libsqlite3-dev libtool uuid-dev git \
  autoconf bison flex libcmocka-dev libnetfilter-queue-dev \
  libunwind-dev libmnl-dev ethtool libjemalloc-dev

For the historical PoC, the source bundle contained:

pcre2-10.44.tar.gz
gperftools-2.15.tar.gz
ragel-6.10.tar.gz
boost_1_86_0.tar.gz
hyperscan-v5.4.2.tar.gz
flatbuffers-v2.0.0.tar.gz
libdaq-v3.0.16.tar.gz
snort3-3.3.5.0.tar.gz

Record the original source URL for each archive. Verify and package the bundle:

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

Test the bundle on a clean matching VM before declaring it air-gap ready. After approved transfer, verify both the outer archive and SHA256SUMS. Install packages with APT so it can order the local dependency set:

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

If APT reports a missing dependency, stop and add it to the connected bundle. Do not accept a partially successful dpkg -i *.deb run as completion.

Build LibDAQ and Snort

Install the dependencies required by the selected release, then build the exact LibDAQ archive recorded in the build record. The canonical sequence is:

tar -xf <LIBDAQ_ARCHIVE>
cd <LIBDAQ_SOURCE_DIRECTORY>
./bootstrap
./configure --prefix=/usr/local
make -j"$(nproc)"
sudo make install
sudo ldconfig

Build Snort from its recorded archive:

tar -xf <SNORT_ARCHIVE>
cd <SNORT_SOURCE_DIRECTORY>
./configure_cmake.sh --prefix=/usr/local
cd build
make -j"$(nproc)"
sudo make install
sudo ldconfig

If LibDAQ uses a non-standard prefix, supply the matching DAQ include and library paths described by the official installation guide. Do not solve a missing module by copying libraries between unrelated releases.

Build the historical optional dependencies

The earlier PoC built several dependencies from source. Use separate build directories, run available tests, and stop on the first failure:

cd "$HOME/snort-build/sources"
tar -xzf pcre2-10.44.tar.gz
cd pcre2-10.44
./configure --prefix=/usr/local
make -j"$(nproc)"
make check
sudo make install

cd "$HOME/snort-build/sources"
tar -xzf gperftools-2.15.tar.gz
cd gperftools-2.15
./configure --prefix=/usr/local
make -j"$(nproc)"
make check
sudo make install

cd "$HOME/snort-build/sources"
tar -xzf ragel-6.10.tar.gz
cd ragel-6.10
./configure --prefix=/usr/local
make -j"$(nproc)"
sudo make install

Build Hyperscan against the extracted Boost source:

cd "$HOME/snort-build/sources"
tar -xzf boost_1_86_0.tar.gz
tar -xzf hyperscan-v5.4.2.tar.gz
cmake -S hyperscan-5.4.2 -B hyperscan-build \
  -DCMAKE_BUILD_TYPE=Release \
  -DCMAKE_INSTALL_PREFIX=/usr/local \
  -DBOOST_ROOT="$HOME/snort-build/sources/boost_1_86_0"
cmake --build hyperscan-build --parallel "$(nproc)"
ctest --test-dir hyperscan-build --output-on-failure
sudo cmake --install hyperscan-build

Optional components vary by Snort release. If a current build does not detect one, consult the matching release documentation instead of copying shared libraries or forcing paths from another version.

Configure capture prerequisites

Identify the intended capture interface rather than copying ens32:

ip -brief address
sudo ethtool -k <SENSOR_INTERFACE> | grep receive-offload

Confirm the interface receives the intended traffic before troubleshooting Snort. A passive sensor normally requires a TAP, SPAN port or virtual-switch mirror; an ordinary endpoint does not see unicast traffic between other hosts.

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

If the design requires GRO/LRO to be disabled, record the original values and create a local unit in /etc/systemd/system, not /lib/systemd/system.

[Unit]
Description=Disable receive offload on the Snort sensor interface
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
ExecStart=/sbin/ethtool -K <SENSOR_INTERFACE> gro off lro off
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now snort-offload.service
sudo ethtool -k <SENSOR_INTERFACE> | grep receive-offload

Validate the installation

/usr/local/bin/snort -V
/usr/local/bin/snort --daq-list
/usr/local/bin/snort -c /usr/local/etc/snort/overview.lua -T

Expected: the recorded engine and DAQ versions are displayed, the intended DAQ module is available, and configuration validation finishes without errors.

Run a short foreground capture, generate authorised test traffic, and stop it with Ctrl+C:

sudo install -d -o root -g root -m 0755 /var/log/snort
sudo /usr/local/bin/snort \
  -c /usr/local/etc/snort/overview.lua \
  -i <SENSOR_INTERFACE> -A alert_fast -l /var/log/snort

Review the shutdown statistics. The received count should increase. Investigate packet drops, DAQ acquisition errors or an unchanged count before loading rules.

Common build failures

Symptom Check
DAQ library not found Run ldconfig; confirm LibDAQ and Snort used compatible prefixes
NFQ absent from --daq-list Ensure Netfilter Queue headers existed before LibDAQ was built, then rebuild it
Hyperscan not reported Review CMake detection and architecture requirements; do not copy libraries manually
Configuration module missing Compare snort.lua with the installed release and validate a clean copy
Capture sees no packets Prove interface and mirror/TAP placement with tcpdump
High packet drops Check NIC type, offloads, CPU allocation and offered packet rate
Completion criteriaThe build record and checksums are retained, the intended DAQ is listed, configuration validation succeeds, and interface offload state matches the documented design.

↑ Back to Snort journey map