In this tutorial, you will learn how to install and configure Snort 3 on Rocky Linux. 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 Rocky Linux
As of this writing, Rocky Linux default repositories do not provide Snort packages. As such, to install Snort 3 on Rocky Linux, then you need to build from the source.
Build and Install Snort 3 from Source Code
For a successful build and installation of Snort 3 on Rocky Linux, there are a number of build tools and dependencies that needs to be installed prior to the build process.
Install EPEL and enable Powertools Repositories;
dnf install epel-release
dnf config-manager --set-enabled powertools
Next, install required build tools and libraries;
dnf -y install bison flex libtool nghttp2 libnghttp2-devel \
libpcap-devel pcre-devel openssl-devel libdnet-devel \
libtirpc-devel git gcc-c++ libunwind-devel cmake hwloc-devel \
luajit-devel xz-devel libnfnetlink-devel libmnl-devel \
libnetfilter_queue-devel uuid-devel libsafec-devel
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 https://github.com/snort3/libdaq.git
cd libdaq
./bootstrap
./configure
make
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 ../
wget https://github.com/gperftools/gperftools/releases/download/gperftools-2.9.1/gperftools-2.9.1.tar.gz
tar xzf gperftools-2.9.1.tar.gz
cd gperftools-2.9.1/
./configure
make
make install
Install Snort 3 on Rocky Linux from Source Code
Now that we have all required dependencies in place, download and install Snort 3 on Rocky Linux;
From the releases page, get the latest release version of Snort tarball and download it. The command below downloads Snort 3.1.28.0 which is the current latest release as of this writing.
cd ../
wget https://github.com/snort3/snort3/archive/refs/tags/3.1.28.0.tar.gz
Extract and navigate to Snort 3 source directory, compile and install it;
tar xzf 3.1.28.0.tar.gz
cd snort3-3.1.28.0
./configure_cmake.sh --prefix=/usr/local --enable-tcmalloc
Sample build summary.
...
-------------------------------------------------------
snort version 3.1.28.0
Install options:
prefix: /usr/local
includes: /usr/local/include/snort
plugins: /usr/local/lib64/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
EXE_LDFLAGS:
MODULE_LDFLAGS:
Feature options:
DAQ Modules: Static ()
libatomic: System-provided
Flatbuffers: OFF
Hyperscan: OFF
ICONV: ON
Libunwind: ON
LZMA: ON
RPC DB: Built-in
SafeC: OFF
TCMalloc: ON
JEMalloc: OFF
UUID: OFF
-------------------------------------------------------
-- Configuring done
-- Generating done
-- Build files have been written to: /root/snort-source-files/snort3-3.1.28.0/build
Navigate to the build directory and compile and install Snort 3 on Rocky Linux;
cd build
export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib64/pkgconfig:/usr/local/lib/pkgconfig
make
make install
Once the installation completes, update shared libraries;
ln -s /usr/local/lib/libtcmalloc.so.4 /lib/
ln -s /usr/local/lib/libdaq.so.3 /lib/
ldconfig
Verify Snort 3 Installation by checking the version;
snort -V
,,_ -*> Snort++ <*-
o" )~ Version 3.1.28.0
'''' By Martin Roesch & The Snort Team
http://snort.org/contact#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.7
Using LuaJIT version 2.1.0-beta3
Using OpenSSL 1.1.1k FIPS 25 Mar 2021
Using libpcap version 1.9.1 (with TPACKET_V3)
Using PCRE version 8.42 2018-03-20
Using ZLIB version 1.2.11
Using LZMA version 5.2.4
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.
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
matches.
Report bugs to [email protected].
Configuring Snort 3 on Rocky Linux
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
Verify;
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 192.168.60.22/24 metric 100 brd 192.168.60.255 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'
[Unit]
Description=Set Snort 3 NIC in promiscuous mode and Disable GRO, LRO on boot
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/sbin/ip link set dev enp0s8 promisc on
ExecStart=/usr/sbin/ethtool -K enp0s8 gro off lro off
TimeoutStartSec=0
RemainAfterExit=yes
[Install]
WantedBy=default.target
EOL
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 Rocky Linux
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- \
https://www.snort.org/downloads/community/snort3-community-rules.tar.gz \
| tar xz -C /usr/local/etc/rules/
ls -1 /usr/local/etc/rules/snort3-community-rules/
AUTHORS
LICENSE
sid-msg.map
snort3-community.rules
VRT-License.txt
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
HOME_NET = '192.168.60.22/32'
-- set up the external network addresses.
-- (leave as "any" in most situations)
-- EXTERNAL_NET = 'any'
EXTERNAL_NET = '!$HOME_NET'
...
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 https://www.snort.org/downloads/openappid/23020 -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++ 3.1.28.0
--------------------------------------------------
Loading /usr/local/etc/snort/snort.lua:
Loading snort_defaults.lua:
Finished snort_defaults.lua:
Loading file_magic.lua:
Finished file_magic.lua:
ssh
host_cache
pop
so_proxy
stream_tcp
mms
smtp
gtp_inspect
packets
dce_http_proxy
stream_icmp
normalizer
ips
binder
wizard
appid
file_id
stream_udp
http2_inspect
http_inspect
ftp_data
search_engine
ftp_server
port_scan
dce_http_server
dce_smb
dce_tcp
netflow
iec104
cip
telnet
ssl
sip
rpc_decode
modbus
host_tracker
stream_user
stream_ip
back_orifice
trace
classifications
dnp3
active
process
ftp_client
decode
daq
alerts
stream
network
references
arp_spoof
output
hosts
dns
dce_udp
imap
file_policy
s7commplus
stream_file
Finished /usr/local/etc/snort/snort.lua:
--------------------------------------------------
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/05-13:57:05.549004 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} 192.168.60.1 -> 192.168.60.22
05/05-13:57:06.559196 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} 192.168.60.1 -> 192.168.60.22
05/05-13:57:07.579311 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} 192.168.60.1 -> 192.168.60.22
05/05-13:57:08.603201 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} 192.168.60.1 -> 192.168.60.22
05/05-13:57:09.627219 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} 192.168.60.1 -> 192.168.60.22
05/05-13:57:10.651640 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} 192.168.60.1 -> 192.168.60.22
05/05-13:57:11.679266 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} 192.168.60.1 -> 192.168.60.22
05/05-13:57:12.699300 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} 192.168.60.1 -> 192.168.60.22
05/05-13:57:13.723307 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} 192.168.60.1 -> 192.168.60.22
...
When cancelled, you should see Packet statistics;
Packet Statistics
--------------------------------------------------
daq
received: 129
analyzed: 119
dropped: 6
outstanding: 10
allow: 119
rx_bytes: 15783
--------------------------------------------------
codec
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
--------------------------------------------------
appid
packets: 115
processed_packets: 115
total_sessions: 5
service_cache_adds: 4
bytes_in_use: 608
items_in_use: 4
--------------------------------------------------
arp_spoof
packets: 4
--------------------------------------------------
back_orifice
packets: 6
--------------------------------------------------
binder
raw_packets: 4
new_flows: 5
inspects: 9
--------------------------------------------------
detection
analyzed: 119
hard_evals: 68
raw_searches: 24
cooked_searches: 2
pkt_searches: 26
alerts: 34
total_alerts: 34
logged: 34
--------------------------------------------------
normalizer
test_tcp_ts_nop: 1
--------------------------------------------------
pcre
pcre_rules: 178
pcre_native: 178
--------------------------------------------------
port_scan
packets: 115
trackers: 8
--------------------------------------------------
search_engine
non_qualified_events: 34
qualified_events: 34
searched_bytes: 5452
--------------------------------------------------
stream
flows: 5
--------------------------------------------------
stream_icmp
sessions: 1
max: 1
created: 1
released: 1
--------------------------------------------------
stream_tcp
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
--------------------------------------------------
stream_udp
sessions: 3
max: 3
created: 3
released: 3
total_bytes: 2541
--------------------------------------------------
wizard
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
--------------------------------------------------
process
signals: 1
--------------------------------------------------
timing
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/05-14:01:33.468399 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} 192.168.60.1 -> 192.168.60.22
05/05-14:01:34.492480 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} 192.168.60.1 -> 192.168.60.22
05/05-14:01:35.516336 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} 192.168.60.1 -> 192.168.60.22
05/05-14:01:36.544332 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} 192.168.60.1 -> 192.168.60.22
05/05-14:01:37.564282 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} 192.168.60.1 -> 192.168.60.22
05/05-14:01:38.588384 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} 192.168.60.1 -> 192.168.60.22
05/05-14:01:39.612393 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} 192.168.60.1 -> 192.168.60.22
05/05-14:01:40.636332 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} 192.168.60.1 -> 192.168.60.22
05/05-14:01:41.664373 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} 192.168.60.1 -> 192.168.60.22
05/05-14:01:42.684480 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} 192.168.60.1 -> 192.168.60.22
05/05-14:01:43.708500 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} 192.168.60.1 -> 192.168.60.22
05/05-14:01:44.732387 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} 192.168.60.1 -> 192.168.60.22
05/05-14:01:45.756329 [**] [1:1000001:1] "ICMP connection test" [**] [Priority: 0] [AppID: ICMP] {ICMP} 192.168.60.1 -> 192.168.60.22
You can include the local rules in snort.lua;
vim /usr/local/etc/snort/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
[Unit]
Description=Snort Daemon
After=syslog.target network.target
[Service]
Type=simple
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
[Install]
WantedBy=multi-user.target
EOL
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: disabled)
Active: active (running) since Thu 2022-05-05 14:00:22 EDT; 4s ago
Main PID: 60655 (snort)
Tasks: 2 (limit: 11256)
Memory: 218.3M
CGroup: /system.slice/snort3.service
└─60655 /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 05 14:00:22 localhost.localdomain systemd[1]: Started Snort Daemon.
That marks the end of our tutorial on how to install Snort 3 on Rocky Linux.
Tks so much! The best tutorial on how to install snort 3 I found