Install and Configure Snort 3 on Ubuntu 22.04


In this tutorial, you will learn how to install and configure Snort 3 on Ubuntu 22.04. Snort is a lightweight network intrusion detection system. It features rules-based logging and can perform content searching/matching in addition to detecting a variety of other attacks and probes, such as buffer overflows, stealth port scans, CGI attacks, SMB probes, and much more. Snort has a real-time alerting capability, with alerts being sent to syslog, a separate “alert” file, or even to a Windows computer via Samba.

Install and Configure Snort 3 on Ubuntu 22.04

As of this writing, Ubuntu 22.04 provides snort 2.9 on its default Universe repos;

apt-cache policy snort
  Installed: (none)
  Version table: 500
        500 jammy/universe amd64 Packages

Build and Install Snort 3 on Ubuntu 22.04 from Source Code

In order to install and configure Snort 3 on Ubuntu 22.04, you need to build it from the source.

Run System Update

To begin with, run system package cache update;

apt update
apt upgrade

Install Required Build Tools

For a successful build and installation of Snort 3 on Ubuntu 22.04, there are a number of build tools and dependencies that needs to be installed prior to the build process as outlined on the Dependencies page.

apt install build-essential libpcap-dev libpcre3-dev \
libnet1-dev zlib1g-dev luajit hwloc libdnet-dev \
libdumbnet-dev bison flex liblzma-dev openssl libssl-dev \
pkg-config libhwloc-dev cmake cpputest libsqlite3-dev uuid-dev \
libcmocka-dev libnetfilter-queue-dev libmnl-dev autotools-dev \
libluajit-5.1-dev libunwind-dev libfl-dev -y

Download and install latest version of the Snort DAQ (Data Acquisition library) . DAQ is not available on the default Ubuntu repos and hence, you need to build and install it from the source;

mkdir snort-source-files && cd snort-source-files
git clone
cd libdaq
make install

Download and install google’s thread-caching malloc, Tcmalloc, a memory allocator optimized for high concurrency situations which will provide better speed for the trade-off of higher memory usage. This is an optional dependency but highly recommended.

cd ../
tar xzf gperftools-2.9.1.tar.gz
cd gperftools-2.9.1/
make install

Install Snort 3 on Ubuntu 22.04 from Source Code

Now that we have all required dependencies in place, download and install Snort 3 on Ubuntu 22.04;

From the releases page, get the latest release version of Snort tarball and download it. The command below downloads Snort which is the current latest release as of this writing.

cd ../

Extract and navigate to Snort 3 source directory, compile and install it;

tar xzf
cd snort3-
./ --prefix=/usr/local --enable-tcmalloc

Sample build summary.

snort version

Install options:
    prefix:     /usr/local
    includes:   /usr/local/include/snort
    plugins:    /usr/local/lib/snort

Compiler options:
    CC:             /usr/bin/cc
    CXX:            /usr/bin/c++
    CFLAGS:            -fvisibility=hidden   -DNDEBUG -g -ggdb  -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free  -O2 -g -DNDEBUG
    CXXFLAGS:          -fvisibility=hidden   -DNDEBUG -g -ggdb  -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free  -O2 -g -DNDEBUG

Feature options:
    DAQ Modules:    Static (afpacket;bpf;dump;fst;nfq;pcap;savefile;trace)
    libatomic:      System-provided
    Flatbuffers:    OFF
    Hyperscan:      OFF
    ICONV:          ON
    Libunwind:      ON
    LZMA:           ON
    RPC DB:         Built-in
    SafeC:          OFF
    TCMalloc:       ON
    JEMalloc:       OFF
    UUID:           ON

-- Configuring done
-- Generating done
-- Build files have been written to: /root/snort-source-files/snort3-

Navigate to the build directory and compile and install Snort 3 on Ubuntu 22.04;

cd build
make install

Once the installation completes, update shared libraries;


Verify Snort 3 Installation by checking the version;

snort -V
   ,,_     -*> Snort++ <*-
  o"  )~   Version
   ''''    By Martin Roesch & The Snort Team
           Copyright (C) 2014-2022 Cisco and/or its affiliates. All rights reserved.
           Copyright (C) 1998-2013 Sourcefire, Inc., et al.
           Using DAQ version 3.0.6
           Using LuaJIT version 2.1.0-beta3
           Using OpenSSL 3.0.2 15 Mar 2022
           Using libpcap version 1.10.1 (with TPACKET_V3)
           Using PCRE version 8.39 2016-06-14
           Using ZLIB version 1.2.11
           Using LZMA version 5.2.5

The above confirms that Snort 3 installation is successful and is working fine.

Obtaining Snort Command Line Help

To obtain Snort command line help, simply execute either of the commands below and check the difference;

snort --help
snort -?
Snort has several options to get more help:

-? list command line options (same as --help)
--help this overview of help
--help-commands [<module prefix>] output matching commands
--help-config [<module prefix>] output matching config options
--help-counts [<module prefix>] output matching peg counts
--help-limits print the int upper bounds denoted by max*
--help-module <module> output description of given module
--help-modules list all available modules with brief help
--help-modules-json dump description of all available modules in JSON format
--help-plugins list all available plugins with brief help
--help-options [<option prefix>] output matching command line options
--help-signals dump available control signals
--list-buffers output available inspection buffers
--list-builtin [<module prefix>] output matching builtin rules
--list-gids [<module prefix>] output matching generators
--list-modules [<module type>] list all known modules
--list-plugins list all known modules
--show-plugins list module and plugin versions

--help* and --list* options preempt other processing so should be last on the
command line since any following options are ignored.  To ensure options like
--markup and --plugin-path take effect, place them ahead of the help or list

Options that filter output based on a matching prefix, such as --help-config
won't output anything if there is no match.  If no prefix is given, everything

Report bugs to [email protected]

Configuring Snort 3 on Ubuntu 22.04

Configure Network Interface Cards

First off, put the interface on which Snort is listening for network traffic on promiscuous mode so that it can be able to see all of the network traffic sent to it rather than seeing only the traffic originating from within the Snort 3 server alone.

ip link set dev enp0s8 promisc on


ip add sh enp0s8
3: enp0s8: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 08:00:27:84:be:8b brd ff:ff:ff:ff:ff:ff
    inet metric 100 brd scope global dynamic enp0s8
       valid_lft 377sec preferred_lft 377sec
    inet6 fe80::a00:27ff:fe84:be8b/64 scope link 
       valid_lft forever preferred_lft forever

Disable Interface Offloading to prevent Snort from truncating large packets larger than 1518 bytes. You can check if this feature is enabled;

ethtool -k enp0s8 | grep receive-offload
generic-receive-offload: on
large-receive-offload: off [fixed]

GRO is enabled while LRO is fixed and hence cannot be changed.

Then disable;

ethtool -K enp0s8 gro off lro off

The two NIC changes are temporary. To ensure the changes persists across system reboot, create and enable a systemd service unit to implement the changes;

cat > /etc/systemd/system/snort3-nic.service << 'EOL'
Description=Set Snort 3 NIC in promiscuous mode and Disable GRO, LRO on boot

ExecStart=/usr/sbin/ip link set dev enp0s8 promisc on
ExecStart=/usr/sbin/ethtool -K enp0s8 gro off lro off


Reload systemd configuration settings;

systemctl daemon-reload

Start and enable the service on boot;

systemctl enable --now snort3-nic.service

Install Snort 3 Rulesets on Ubuntu 22.04

Rulesets is the main artery for Snorts intrusion detection engine. There are three types of Snort Rules:

  • Community Rules
  • Registered Rules
  • Subscriber Rules

In this tutorial, we will install the community Snort rules;

Create Snort Rules directory. In the /usr/local/etc/snort/snort_defaults.lua config file, the default rules path (RULE_PATH), is defined as /usr/local/etc/rules.

mkdir /usr/local/etc/rules

Download Snort 3 community rules from Snort 3 downloads page;

wget -qO- \ \
| tar xz -C /usr/local/etc/rules/
ls -1 /usr/local/etc/rules/snort3-community-rules/

Now that we have the rules to get us started in place, you need to configure Snort 3.

Open the main configuration file for editing;

vim /usr/local/etc/snort/snort.lua

Set the networks to protect against attacks as the value for the HOME_NET variable. This can be a single IP address, subnets... For simplicity, i just set this to the subnet of Snort 3 interface. The EXTERNAL_NET is anything other than our HOME_NET;

-- HOME_NET and EXTERNAL_NET must be set now
-- setup the network addresses you are protecting

-- set up the external network addresses.
-- (leave as "any" in most situations)
-- EXTERNAL_NET = 'any'

Save the changes and exit the file.

Next, update the paths to your rules in the /usr/local/etc/snort/snort.lua configuration file.

ips =
    -- use this to enable decoder and inspector alerts
    --enable_builtin_rules = true,

    -- use include for rules files; be sure to set your path
    -- note that rules files can include other rules files
    -- (see also related path vars at the top of snort_defaults.lua)
    variables = default_variables,
    rules = [[ 
    include $RULE_PATH/snort3-community-rules/snort3-community.rules

Save and exit the configuration file.

Installing Snort OpenAppID

OpenAppID is an application layer plugin that enables Snort to detect various applications,  Facebook, Netflix, Twitter, and Reddit, used in the network. Run the commands below download from Snort 3 downloads page and install Snort OpenAppID;

wget -O OpenAppId-23020.tgz
tar -xzvf OpenAppId-23020.tgz
cp -R odp /usr/local/lib/

Next, edit the Snort 3 configuration file and define the location of the OpenAppID libraries;

vim /usr/local/etc/snort/snort.lua
appid =
    -- appid requires this to use appids in rules
    --app_detector_dir = 'directory to load appid detectors from'
    app_detector_dir = '/usr/local/lib',
    log_stats = true,


Save and exit the configuration file.

Create Snorts Log directory;

mkdir /var/log/snort

Next, run syntax checking;

snort -c /usr/local/etc/snort/snort.lua
o")~   Snort++
Loading /usr/local/etc/snort/snort.lua:
Loading snort_defaults.lua:
Finished snort_defaults.lua:
Loading file_magic.lua:
Finished file_magic.lua:
Finished /usr/local/etc/snort/snort.lua:
Loading /usr/local/etc/rules/snort3-community-rules/snort3-community.rules:
Finished /usr/local/etc/rules/snort3-community-rules/snort3-community.rules:
ips policies rule stats
              id  loaded  shared enabled    file
               0     551       0     551    /usr/local/etc/snort/snort.lua
rule counts
       total rules loaded: 551
               text rules: 551
            option chains: 551
            chain headers: 48
                 flowbits: 45
     flowbits not checked: 37
port rule counts
             tcp     udp    icmp      ip
     any      23       0       0       0
     src      42       1       0       0
     dst      85       7       0       0
    both       0       1       0       0
   total     150       9       0       0
service rule counts          to-srv  to-cli
                      dns:        4       0
                      ftp:        4       2
                 ftp-data:        1      44
                     http:      287      77
                    http2:      287      77
                     imap:        1      65
                      irc:        1       1
              netbios-ssn:       24       1
                     pop3:        1      65
                      rdp:        1       0
                     smtp:       66       0
                      ssl:       11      16
                   telnet:        2       0
                    total:      690     348
fast pattern groups
                      src: 7
                      dst: 19
                      any: 1
                to_server: 26
                to_client: 18
search engine
                instances: 71
                 patterns: 1209
            pattern chars: 15025
               num states: 11962
         num match states: 1162
             memory scale: KB
             total memory: 416.373
           pattern memory: 61.8301
        match list memory: 136.234
        transition memory: 209.434
        fast pattern only: 792
pcap DAQ configured to passive.

Snort successfully validated the configuration (with 0 warnings).
o")~   Snort exiting

Create Custom local rules for the purposes of testing our Snort setup.

vim /usr/local/etc/rules/local.rules

Create a rule to detect ping tests;

alert icmp any any -> $HOME_NET any (msg:"ICMP connection test"; sid:1000001; rev:1;)

Save and exit the local rules file. Check the syntax;

snort -c /usr/local/etc/snort/snort.lua -R /usr/local/etc/rules/local.rules

Next, run the test by executing the command below;

snort -c /usr/local/etc/snort/snort.lua -R /usr/local/etc/rules/local.rules -i enp0s8 -A alert_fast -s 65535 -k none

On another terminal, ping your Snort server. While the ping runs, you should see the alert lines written to standard output;

05/03-11:24:01.979485 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} ->
05/03-11:24:03.006407 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} ->
05/03-11:24:04.026118 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} ->
05/03-11:24:05.053991 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} ->
05/03-11:24:06.074083 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} ->
05/03-11:24:07.097995 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} ->
05/03-11:24:08.122173 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} ->
05/03-11:24:09.145955 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} ->
05/03-11:24:10.169989 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} ->
05/03-11:24:11.194106 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} ->
05/03-11:24:12.218152 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} ->
05/03-11:24:13.241983 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} ->
05/03-11:24:14.266063 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} ->
05/03-11:24:15.289931 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} ->
05/03-11:24:16.314112 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} ->
05/03-11:24:17.337879 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} ->
05/03-11:24:18.362716 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} ->
05/03-11:24:19.364461 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} ->
05/03-11:24:20.365276 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} ->
05/03-11:24:21.370316 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} ->
05/03-11:24:22.371367 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} ->
05/03-11:24:23.386220 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} ->
05/03-11:24:24.410267 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} ->
05/03-11:24:25.410309 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} ->
05/03-11:24:26.426397 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} ->
05/03-11:24:27.427366 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} ->
05/03-11:24:28.442598 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} ->
05/03-11:24:29.443398 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} ->

When cancelled, you should see Packet statistics;

Packet Statistics
                 received: 129
                 analyzed: 119
                  dropped: 6
              outstanding: 10
                    allow: 119
                 rx_bytes: 15783
                    total: 119         	(100.000%)
                      arp: 4           	(  3.361%)
                      eth: 119         	(100.000%)
                    icmp4: 68          	( 57.143%)
                     ipv4: 115         	( 96.639%)
                      tcp: 41          	( 34.454%)
                      udp: 6           	(  5.042%)
Module Statistics
                  packets: 115
        processed_packets: 115
           total_sessions: 5
       service_cache_adds: 4
             bytes_in_use: 608
             items_in_use: 4
                  packets: 4
                  packets: 6
              raw_packets: 4
                new_flows: 5
                 inspects: 9
                 analyzed: 119
               hard_evals: 68
             raw_searches: 24
          cooked_searches: 2
             pkt_searches: 26
                   alerts: 34
             total_alerts: 34
                   logged: 34
          test_tcp_ts_nop: 1
               pcre_rules: 178
              pcre_native: 178
                  packets: 115
                 trackers: 8
     non_qualified_events: 34
         qualified_events: 34
           searched_bytes: 5452
                    flows: 5
                 sessions: 1
                      max: 1
                  created: 1
                 released: 1
                 sessions: 1
                      max: 1
                  created: 1
                 released: 1
             instantiated: 1
                   setups: 1
            data_trackers: 1
              segs_queued: 21
            segs_released: 21
                segs_used: 21
          rebuilt_packets: 2
            rebuilt_bytes: 392
          client_cleanups: 1
          server_cleanups: 1
        partial_fallbacks: 1
                 max_segs: 17
                max_bytes: 3196
                 sessions: 3
                      max: 3
                  created: 3
                 released: 3
              total_bytes: 2541
                tcp_scans: 17
                udp_scans: 3
               udp_misses: 3
Appid Statistics
detected apps and services
              Application: Services   Clients    Users      Payloads   Misc       Referred  
                     dhcp: 2          0          0          0          0          0         
                     icmp: 1          0          0          0          0          0         
                  unknown: 1          0          0          0          0          0         
Summary Statistics
                  signals: 1
                  runtime: 00:00:50
                  seconds: 50.745225
                 pkts/sec: 2
o")~   Snort exiting

Configure Snort 3 Logging

To write Snort 3 events to log files, you need to configure alert settings. There are different Snort logging options that are explained well in the Snort 3 manual, Logger Modules section. To output the event data to a file, in brief format (as defined in the command line above by option -A alert_type), open the snort.lua configuration and head over to the outputs section.

vim /usr/local/etc/snort/snort.lua
-- 7. configure outputs

-- event logging
-- you can enable with defaults from the command line with -A 
-- uncomment below to set non-default configs
--alert_csv = { }
alert_fast = { 
        file = true, 
        packet = false,
        limit = 10,
--alert_full = { }
--alert_sfsocket = { }
--alert_syslog = { }
--unified2 = { }

The setting will cause snort to write logs to alert_fast.txt file.

Save and exit the configuration and run syntax checking.

snort -c /usr/local/etc/snort/snort.lua

Run the command again, this time, without the option, -A alert_fast, but with an option to specify the log directory, -l /var/log/snort.

snort -c /usr/local/etc/snort/snort.lua -R /usr/local/etc/rules/local.rules -i enp0s8 -s 65535 -k none -l /var/log/snort/

Run the ping test again.

If you check on the logs directory, you should see an alert_fast.txt file created. You can tail this file;

tail -f /var/log/snort/alert_fast.txt
05/03-11:29:52.378834 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} ->
05/03-11:29:53.403033 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} ->
05/03-11:29:54.427078 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} ->
05/03-11:29:55.451495 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} ->
05/03-11:29:56.475263 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} ->
05/03-11:29:57.499234 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} ->
05/03-11:29:58.523283 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} ->
05/03-11:29:59.547394 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} ->
05/03-11:30:00.575010 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} ->
05/03-11:30:01.595749 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} ->

You can include the local rules in snort.lua;

ips =
    -- use this to enable decoder and inspector alerts
    --enable_builtin_rules = true,

    -- use include for rules files; be sure to set your path
    -- note that rules files can include other rules files
    -- (see also related path vars at the top of snort_defaults.lua)
    variables = default_variables,
    rules = [[ 
    include $RULE_PATH/snort3-community-rules/snort3-community.rules
    include $RULE_PATH/local.rules

Running Snort as a Service

While it is possible to run Snort as a daemon in the background with command line option -D, it is also possible to create a systemd service unit for Snort.

If you are going to run Snort as a service, it is prudent to run it a non privileged system user. Hence, create a non login system user account for Snort;

useradd -r -s /usr/sbin/nologin -M -c SNORT_IDS snort

Create a systemd service unit for Snort to be run as snort user. Adjust your interfaces accordingly.

cat > /etc/systemd/system/snort3.service << EOL
Description=Snort Daemon

ExecStart=/usr/local/bin/snort -c /usr/local/etc/snort/snort.lua -s 65535 -k none -l /var/log/snort -D -i enp0s8 -m 0x1b -u snort -g snort
ExecStop=/bin/kill -9 $MAINPID


Reload systemd configs;

systemctl daemon-reload

Set the ownership and permissions on the log file;

chmod -R 5775 /var/log/snort
chown -R snort:snort /var/log/snort

Start and enable Snort to run on system boot. The service will run as root and then drop the privileges to Snort user created.

systemctl enable --now snort3

Check the service to confirm if it is running;

systemctl status snort3
● snort3.service - Snort Daemon
     Loaded: loaded (/etc/systemd/system/snort3.service; enabled; vendor preset: enabled)
     Active: active (running) since Tue 2022-05-03 11:32:20 UTC; 5s ago
   Main PID: 31520 (snort)
      Tasks: 2 (limit: 2241)
     Memory: 215.4M
        CPU: 805ms
     CGroup: /system.slice/snort3.service
             └─31520 /usr/local/bin/snort -c /usr/local/etc/snort/snort.lua -s 65535 -k none -l /var/log/snort -D -i enp0s8 -m 0x1b -u snort -g snort

May 03 11:32:20 jellyfish systemd[1]: Started Snort Daemon.

That marks the end of our tutorial on how to install and configure Snort 3 on Ubuntu 22.04.

Note that we have just scratched the service on what the configuration and what Snort 3 is capable of.


Snort 3 Installation

Further Reading

Snort 3 User Manual

Related Tutorials

Install and Setup Suricata on Ubuntu 22.04/Ubuntu 20.04

Integrate Suricata with Wazuh for Log Processing


Please enter your comment!
Please enter your name here