Suricata
SURICATA IDS/IPS is an open source IDS that monitors communications on the network and detects suspicious traffic. Its basic mechanism is signature-based, so it can detect predefined unauthorized communications. Suricata is also characterized by its ability to provide protection as well as detection.
1.Suricata Install
①Install required packages
1 2 |
# apt -y install libpcre2-dev libpcre3 libpcre3-dbg libpcre3-dev build-essential autoconf automake libtool libpcap-dev libnet1-dev libyaml-0-2 libyaml-dev zlib1g zlib1g-dev libcap-ng-dev libcap-ng0 make libmagic-dev libjansson-dev libjansson4 pkg-config libnspr4-dev libnss3-dev liblz4-dev rustc cargo python3-pip # apt -y install libnetfilter-queue-dev libnetfilter-queue1 libnfnetlink-dev libnfnetlink0 |
➁Suricata install
Please visit the official website to check the latest version. As of May 4, 2024, the latest stable version of Srikata is 7.0.5
Download and Extract
1 2 |
# wget https://www.openinfosecfoundation.org/download/suricata-7.0.5.tar.gz # tar xzf suricata-7.0.5.tar.gz |
configuration and installation
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# cd suricata-7.0.5 # /configure --enable-nfqueue --prefix=/usr --sysconfdir=/etc --localstatedir=/var # make && make install-full You can now start suricata by running as root something like: /usr/bin/suricata -c /etc/suricata/suricata.yaml -i eth0 If a library like libhtp.so is not found, you can run suricata with: LD_LIBRARY_PATH=/usr/lib /usr/bin/suricata -c /etc/suricata/suricata.yaml -i eth0 The Emerging Threats Open rules are now installed. Rules can be updated and managed with the suricata-update tool. For more information please see: https://docs.suricata.io/en/latest/rule-management/index.html make[1]: Leaving directory '/root/suricata-7.0.5' |
Version Check
1 2 |
# suricata -V This is Suricata version 7.0.5 RELEASE |
Stop the Suricata service as it needs to be configured first.
1 |
# systemctl stop suricata |
2.Configure Suricata
①Determine interface and IP address where Suricata will inspect network packets
1 2 3 |
# ip --brief add lo UNKNOWN 127.0.0.1/8 ::1/128 ens33 UP 192.168.11.83/24 fe80::xxx:xxxx:xxxx:xxxx/64 |
Edit /etc/suricata/suricata.yaml file
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# vi /etc/suricata/suricata.yaml # Line 18 : change HOME_NET: "[192.168.11.0/24]" # Kine 136 : change community-id: false → community-id: true # Line 615 : change af-packet: - interface: eth0 ↓ af-packet: - interface: ens33 ←Change to your own interface name |
➁suricata Update
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# suricata-update -o /etc/suricata/rules -------omission------- 2/5/2024 -- 11:39:42 - <Info> -- Loaded 48910 rules. 2/5/2024 -- 11:39:42 - <Info> -- Disabled 14 rules. 2/5/2024 -- 11:39:42 - <Info> -- Enabled 0 rules. 2/5/2024 -- 11:39:42 - <Info> -- Modified 0 rules. 2/5/2024 -- 11:39:42 - <Info> -- Dropped 0 rules. 2/5/2024 -- 11:39:42 - <Info> -- Enabled 136 rules for flowbit dependencies. 2/5/2024 -- 11:39:42 - <Info> -- Backing up current rules. 2/5/2024 -- 11:39:42 - <Info> -- Writing rules to /etc/suricata/rules/suricata.rules: total: 48910; enabled: 37185; added: 48910; removed 0; modified: 0 2/5/2024 -- 11:39:42 - <Info> -- Writing /etc/suricata/rules/classification.config 2/5/2024 -- 11:39:43 - <Info> -- Testing with suricata -T. 2/5/2024 -- 11:40:07 - <Info> -- Done. |
It also shows the number of rules processed, in this example 48910 were added, of which 37185 were activated.
➂Check configuration file
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# suricata -T -c /etc/suricata/suricata.yaml -v Notice: suricata: This is Suricata version 7.0.5 RELEASE running in SYSTEM mode Info: cpu: CPUs/cores online: 2 Info: suricata: Running suricata under test mode Info: suricata: Setting engine mode to IDS mode by default Info: exception-policy: master exception-policy set to: auto Info: logopenfile: fast output device (regular) initialized: fast.log Info: logopenfile: eve-log output device (regular) initialized: eve.json Info: logopenfile: stats output device (regular) initialized: stats.log Info: detect: 1 rule files processed. 37236 rules successfully loaded, 0 rules failed, 0 Info: threshold-config: Threshold config parsed: 0 rule(s) found Info: detect: 37239 signatures processed. 1137 are IP-only rules, 4877 are inspecting packet payload, 31013 inspect application layer, 108 are decoder event only Notice: suricata: Configuration provided was successfully loaded. Exiting |
④Confirm that the service starts
Enter the name of each network interface (ens33 in this case)
1 |
# suricata -c /etc/suricata/suricata.yaml -i ens33 |
The following appears
1 2 |
i: suricata: This is Suricata version 7.0.5 RELEASE running in SYSTEM mode i: threads: Threads created -> W: 2 FM: 1 FR: 1 Engine started |
3.Automatic startup of Suricata services
①Create systemd service
1 2 3 4 5 6 7 8 9 10 11 |
# vi /etc/systemd/system/suricata.service [Unit] Description=Suricata IDS/IPS After=network.target [Service] ExecStart=/usr/bin/suricata -c /etc/suricata/suricata.yaml -i ens33 [Install] WantedBy=default.target |
➁Enable Suricata
1 2 |
# systemctl enable suricata Created symlink /etc/systemd/system/default.target.wants/suricata.service → /etc/systemd/system/suricata.service |
➂Start Suricata
1 2 |
# systemctl daemon-reload # systemctl start suricata |
④Check Suricata's status
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# systemctl status suricata ● suricata.service - Suricata IDS/IPS Loaded: loaded (/etc/systemd/system/suricata.service; enabled; preset: enabled) Active: active (running) since Fri 2024-05-03 12:46:02 JST; 30s ago Main PID: 23182 (Suricata-Main) Tasks: 8 (limit: 4556) Memory: 776.9M (peak: 812.1M) CPU: 3.049s CGroup: /system.slice/suricata.service mq23182 /usr/bin/suricata -c /etc/suricata/suricata.yaml -i ens33 May 03 12:46:02 lepard systemd[1]: Started suricata.service - Suricata IDS/IPS. May 03 12:46:02 lepard suricata[23182]: i: suricata: This is Suricata version 7.0.5 RELEASE running in SYSTEM mode May 03 12:46:05 lepard suricata[23182]: i: threads: Threads created -> W: 2 FM: 1 FR: 1 Engine started |
4.Testing the Suricata Rule
①Test ET Open rule number 2100498
1 2 |
# curl http://testmynids.org/uid/index.html uid=0(root) gid=0(root) groups=0(root) |
Check log file by specifying rule number
1 2 |
# grep 2100498 /var/log/suricata/fast.log 05/03/2024-12:54:12.517864 [**] [1:2100498:7] GPL ATTACK_RESPONSE id check returned root [**] [Classification: Potentially Bad Traffic] [Priority: 2] {TCP} 99.86.199.74:80 -> 192.168.11.83:47068 |
➁Check events in /var/log/suricata/eve.log
Install jq
1 |
# apt install jq |
Filter EVE Log events by searching for 2100498 signatures
Display alert objects with signature_id keys that match the values in 2100498
1 |
# jq 'select(.alert .signature_id==2100498)' /var/log/suricata/eve.json |
The following appears
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
{ "timestamp": "2024-05-03T12:54:12.517864+0900", "flow_id": 1259841387789651, "in_iface": "ens33", "event_type": "alert", "src_ip": "99.86.199.74", "src_port": 80, "dest_ip": "192.168.11.83", "dest_port": 47068, "proto": "TCP", "pkt_src": "wire/pcap", "community_id": "1:b6Z5YOjKiLOagLna2F8gX75pnDM=", "alert": { "action": "allowed", "gid": 1, "signature_id": 2100498, "rev": 7, "signature": "GPL ATTACK_RESPONSE id check returned root", "category": "Potentially Bad Traffic", "severity": 2, "metadata": { "created_at": [ "2010_09_23" ], "updated_at": [ "2019_07_26" ] } }, |
5.Creating and Applying Custom Rules
①Create custom signatures for Custom Rules files
1 2 3 |
# vi /etc/suricata/rules/local.rules Include the following alert icmp any any -> $HOME_NET any (msg:"ICMP Ping"; sid:10001; rev:1;) |
➁Edit configuration file (define path for local.rules above)
1 2 3 4 5 6 7 8 |
# vi /etc/suricata/suricata.yaml # Added around line 2155 default-rule-path: /var/lib/suricata/rules rule-files: - suricata.rules - /etc/suricata/rules/local.rules |
③Testing the configuration file
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# suricata -T -c /etc/suricata/suricata.yaml -v Notice: suricata: This is Suricata version 7.0.5 RELEASE running in SYSTEM mode Info: cpu: CPUs/cores online: 2 Info: suricata: Running suricata under test mode Info: suricata: Setting engine mode to IDS mode by default Info: exception-policy: master exception-policy set to: auto Info: logopenfile: fast output device (regular) initialized: fast.log Info: logopenfile: eve-log output device (regular) initialized: eve.json Info: logopenfile: stats output device (regular) initialized: stats.log Info: detect: 2 rule files processed. 37237 rules successfully loaded, 0 rules failed, 0 Info: threshold-config: Threshold config parsed: 0 rule(s) found Info: detect: 37240 signatures processed. 1138 are IP-only rules, 4877 are inspecting packet payload, 31013 inspect application layer, 108 are decoder event only Notice: suricata: Configuration provided was successfully loaded. Exiting |
④Suricat service restart
1 |
# systemctl restart suricata |
⑤Testing the application of Custom Rules
Run ping on another PC on the same local network to see if it was logged
1 2 3 |
# cat /var/log/suricata/fast.log 05/03/2024-13:06:06.322710 [**] [1:10000:1] ICMP Ping [**] [Classification: (null)] [Priority: 3] {ICMP} 192.168.11.22:8 -> 192.168.11.83:0 05/03/2024-13:06:06.322819 [**] [1:10000:1] ICMP Ping [**] [Classification: (null)] [Priority: 3] {ICMP} 192.168.11.83:0 -> 192.168.11.22:0 |
⑥Obtain logs in JSON format
Ping another PC on the same local network
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# tail -f /var/log/suricata/eve.json | jq 'select(.event_type=="alert")' When ping is executed, the following is displayed in the console { "timestamp": "2024-05-03T13:24:01.134991+0900", "flow_id": 298106683534580, "in_iface": "ens33", "event_type": "alert", "src_ip": "192.168.11.83", "src_port": 0, "dest_ip": "192.168.11.22", "dest_port": 0, "proto": "ICMP", "icmp_type": 0, "icmp_code": 0, "pkt_src": "wire/pcap", "community_id": "1:s8KsUEhci/Nac9CjIft0d/rc2+U=", "alert": { "action": "allowed", "gid": 1, "signature_id": 10001, "rev": 1, "signature": "ICMP Ping", "category": "", "severity": 3 }, "direction": "to_client", "flow": { "pkts_toserver": 2, "pkts_toclient": 1, "bytes_toserver": 148, "bytes_toclient": 74, "start": "2024-05-03T13:24:01.134944+0900", "src_ip": "192.168.11.22", "dest_ip": "192.168.11.83" } } |
6.Adding a Rule Set Provider
①List Default Provider List
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# suricata-update list-sources Name: et/open Vendor: Proofpoint Summary: Emerging Threats Open Ruleset License: MIT Name: et/pro Vendor: Proofpoint Summary: Emerging Threats Pro Ruleset License: Commercial Replaces: et/open Parameters: secret-code Subscription: https://www.proofpoint.com/us/threat-insight/et-pro-ruleset Name: etnetera/aggressive Vendor: Etnetera a.s. Summary: Etnetera aggressive IP blacklist License: MIT Name: malsilo/win-malware Vendor: malsilo Summary: Commodity malware rules License: MIT Name: oisf/trafficid Vendor: OISF Summary: Suricata Traffic ID ruleset License: MIT Name: scwx/enhanced Vendor: Secureworks Summary: Secureworks suricata-enhanced ruleset License: Commercial Parameters: secret-code Subscription: https://www.secureworks.com/contact/ (Please reference CTU Countermeasures) Name: scwx/malware Vendor: Secureworks Summary: Secureworks suricata-malware ruleset License: Commercial Parameters: secret-code Subscription: https://www.secureworks.com/contact/ (Please reference CTU Countermeasures) Name: scwx/security Vendor: Secureworks Summary: Secureworks suricata-security ruleset License: Commercial Parameters: secret-code Subscription: https://www.secureworks.com/contact/ (Please reference CTU Countermeasures) Name: sslbl/ja3-fingerprints Vendor: Abuse.ch Summary: Abuse.ch Suricata JA3 Fingerprint Ruleset License: Non-Commercial Name: sslbl/ssl-fp-blacklist Vendor: Abuse.ch Summary: Abuse.ch SSL Blacklist License: Non-Commercial Name: stamus/lateral Vendor: Stamus Networks Summary: Lateral movement rules License: GPL-3.0-only Name: tgreen/hunting Vendor: tgreen Summary: Threat hunting rules License: GPLv3 |
If you include the tgreen/hunting ruleset as an example
1 2 3 4 5 6 7 8 9 10 11 |
# suricata-update enable-source tgreen/hunting 4/5/2024 -- 11:23:57 - <Info> -- Using data-directory /var/lib/suricata. 4/5/2024 -- 11:23:57 - <Info> -- Using Suricata configuration /etc/suricata/suricata.yaml 4/5/2024 -- 11:23:57 - <Info> -- Using /usr/share/suricata/rules for Suricata provided rules. 4/5/2024 -- 11:23:57 - <Info> -- Found Suricata version 7.0.5 at /usr/bin/suricata. 4/5/2024 -- 11:23:57 - <Warning> -- Source index does not exist, will use bundled one. 4/5/2024 -- 11:23:57 - <Warning> -- Please run suricata-update update-sources. 4/5/2024 -- 11:23:57 - <Info> -- Creating directory /var/lib/suricata/update/sources 4/5/2024 -- 11:23:57 - <Info> -- Enabling default source et/open 4/5/2024 -- 11:23:57 - <Info> -- Source tgreen/hunting enabled |
Perform update
1 |
# suricata-update -o /etc/suricata/rules |
Snort3
1.Install required packages
1 |
# apt install build-essential libpcap-dev libpcre3-dev libnet1-dev zlib1g-dev luajit hwloc 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 |
2. Install DAQ library
Download and install DAQ library
1 2 3 4 5 6 |
# git clone https://github.com/snort3/libdaq.git # cd libdaq/ ~/libdaq# ./bootstrap ~/libdaq# ./configure ~/libdaq# make ~/libdaq# make install |
3. Install Gperftools
Profiler tool used to improve the performance of a particular application or service by improving memory handling in multiple instances
1 2 3 4 5 6 7 |
# cd # wget https://github.com/gperftools/gperftools/releases/download/gperftools-2.13/gperftools-2.13.tar.gz # tar xzf gperftools-2.13.tar.gz # cd gperftools-2.13 ~/gperftools-2.13# ./configure ~/gperftools-2.13# make ~/gperftools-2.13# make install |
4. SNORT3 Install
①Download and deploy SNORT3
1 2 3 4 5 |
# cd # wget https://github.com/snort3/snort3/archive/refs/heads/master.zip # apt install unzip # unzip master.zip # cd snort3-master |
➁configuration
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# ./configure_cmake.sh --prefix=/usr/local --enable-tcmalloc ------------------------------------------------------- snort version 3.1.84.0 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 EXE_LDFLAGS: MODULE_LDFLAGS: Feature options: DAQ Modules: Static (afpacket;bpf;dump;fst;gwlb;nfq;pcap;savefile;trace) libatomic: System-provided Hyperscan: OFF ICONV: ON Libunwind: ON LZMA: ON RPC DB: Built-in SafeC: OFF TCMalloc: ON JEMalloc: OFF UUID: ON NUMA: ON LibML: OFF ------------------------------------------------------- -- Configuring done (4.5s) -- Generating done (0.5s) -- Build files have been written to: /root/snort3-master/build |
➂Install
1 2 3 |
# cd build # make # make install |
④Update shared libraries
1 |
# ldconfig |
⑤Check version
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# snort -V ,,_ -*> Snort++ <*- o" )~ Version 3.1.84.0 '''' By Martin Roesch & The Snort Team http://snort.org/contact#team Copyright (C) 2014-2024 Cisco and/or its affiliates. All rights reserved. Copyright (C) 1998-2013 Sourcefire, Inc., et al. Using DAQ version 3.0.14 Using LuaJIT version 2.1.1703358377 Using OpenSSL 3.0.13 30 Jan 2024 Using libpcap version 1.10.4 (with TPACKET_V3) Using PCRE version 8.39 2016-06-14 Using ZLIB version 1.3 Using LZMA version 5.4.5 |
⑥Test default settings
1 |
# snort -c /usr/local/etc/snort/snort.lua |
If it is normal, it will be displayed as follows
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
-------------------------------------------------- o")~ Snort++ 3.1.84.0 -------------------------------------------------- Loading /usr/local/etc/snort/snort.lua: Loading snort_defaults.lua: Finished snort_defaults.lua: ----omission----- -------------------------------------------------- rule counts total rules loaded: 208 text rules: 208 option chains: 208 chain headers: 1 -------------------------------------------------- service rule counts to-srv to-cli file_id: 208 208 total: 208 208 -------------------------------------------------- fast pattern groups to_server: 1 to_client: 1 -------------------------------------------------- search engine (ac_bnfa) instances: 2 patterns: 416 pattern chars: 2508 num states: 1778 num match states: 370 memory scale: KB total memory: 68.5879 pattern memory: 18.6973 match list memory: 27.3281 transition memory: 22.3125 appid: MaxRss diff: 3328 appid: patterns loaded: 300 -------------------------------------------------- pcap DAQ configured to passive. Snort successfully validated the configuration (with 0 warnings). o")~ Snort exiting |
5. Identify and configure network interfaces
①Check network interface
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host noprefixroute valid_lft forever preferred_lft forever 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:0c:29:1c:f2:f6 brd ff:ff:ff:ff:ff:ff altname enp2s1 inet 192.168.11.83/24 brd 192.168.11.255 scope global ens33 valid_lft forever preferred_lft forever inet6 fe80::20c:29ff:fe1c:f2f6/64 scope link valid_lft forever preferred_lft forever |
The network interface name is ens33
➁Set network interface to promiscuous mode
1 |
# ip link set dev ens33 promisc on |
Check settings
1 2 |
# ip addr | grep ens33 | grep mtu 2: ens33: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 |
➂Set Large Receive Offload (LRO) and Generic Receive Offload (GRO) to off state
Check current status
1 2 3 |
# ethtool -k ens33 | grep receive-offload generic-receive-offload: on large-receive-offload: off [fixed] |
Set LRO and GRO offload status to off state
1 |
# ethtool -K ens33 gro off lro off |
6. Create systemd service for network interface
1 2 |
# touch /etc/systemd/system/snort3-nic.service # vi /etc/systemd/system/snort3-nic.service |
Contents of snort3-nic.service
1 2 3 4 5 6 7 8 9 10 11 12 13 |
[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 ens33 promisc on ExecStart=/usr/sbin/ethtool -K ens33 gro off lro off TimeoutStartSec=0 RemainAfterExit=yes [Install] WantedBy=default.target |
Reload the systemd daemon and apply the changes
1 |
# systemctl daemon-reload |
Start and enable snort3-nic.service
1 2 3 |
# systemctl start snort3-nic.service # systemctl enable snort3-nic.service Created symlink /etc/systemd/system/default.target.wants/snort3-nic.service → /etc/systemd/system/snort3-nic.service |
Check the status of snort3-nic.service
1 2 3 4 5 6 7 8 9 |
# systemctl status snort3-nic.service ● snort3-nic.service - Set Snort 3 NIC in promiscuous mode and Disable GRO, LRO on boot Loaded: loaded (/etc/systemd/system/snort3-nic.service; enabled; preset: enabled) Active: active (exited) since Fri 2024-05-03 17:43:10 JST; 39s ago Main PID: 61473 (code=exited, status=0/SUCCESS) CPU: 6ms May 03 17:43:10 lepard systemd[1]: Starting snort3-nic.service - Set Snort 3 NIC in promiscuous mode and Disable GRO, LRO on boot... May 03 17:43:10 lepard systemd[1]: Finished snort3-nic.service - Set Snort 3 NIC in promiscuous mode and Disable GRO, LRO on boot. |
7. Adding Snort Rules
7.1 Community rule sets added
①Create a folder for Snort rules and download the community ruleset from the Snort website
1 2 |
# mkdir /usr/local/etc/snort/rules # wget -qO- https://www.snort.org/downloads/community/snort3-community-rules.tar.gz | tar xz -C /usr/local/etc/snort/rules/ |
➁ Edit Snort main configuration file
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# vi /usr/local/etc/snort/snort.lua # Line 24 : Change to own network HOME_NET = '192.168.11.0/24' # Line 28 : change EXTERNAL_NET = '!$HOME_NET' # Per Line 193 : add 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 /usr/local/etc/snort/rules/snort3-community-rules/snort3-community.rules ]] } |
➂Test main configuration changes
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# snort -c /usr/local/etc/snort/snort.lua If all is well, the following is displayed ... -------------------------------------------------- search engine (ac_bnfa) instances: 338 patterns: 10778 pattern chars: 175278 num states: 123344 num match states: 10498 memory scale: MB total memory: 3.68713 pattern memory: 0.577984 match list memory: 1.33597 transition memory: 1.73192 fast pattern only: 7099 appid: MaxRss diff: 3328 appid: patterns loaded: 300 -------------------------------------------------- pcap DAQ configured to passive. Snort successfully validated the configuration (with 0 warnings). o")~ Snort exiting |
7.2 Add custom rules
①Create a file in the Snort rules directory
1 2 3 4 |
# touch /usr/local/etc/snort/rules/local.rules # vi /usr/local/etc/snort/rules/local.rules alert icmp any any -> $HOME_NET any (msg:"Incoming ICMP"; sid:1000001; rev:1;) |
➁Edit Snort Main Configuration
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# vi /usr/local/etc/snort/snort.lua # Add per line 194 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 /usr/local/etc/snort/rules/local.rules include /usr/local/etc/snort/rules/snort3-community-rules/snort3-community.rules ]] } |
➂Test main configuration changes
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# snort -c /usr/local/etc/snort/snort.lua If all is well, the following is displayed ... -------------------------------------------------- search engine (ac_bnfa) instances: 338 patterns: 10778 pattern chars: 175278 num states: 123344 num match states: 10498 memory scale: MB total memory: 3.68713 pattern memory: 0.577984 match list memory: 1.33597 transition memory: 1.73192 fast pattern only: 7099 appid: MaxRss diff: 3328 appid: patterns loaded: 300 -------------------------------------------------- pcap DAQ configured to passive. Snort successfully validated the configuration (with 0 warnings). o")~ Snort exiting |
8. OpenAppID Installation
Once the OpenAppID extension is installed, Snort can detect network threats at the application layer level
①Download and deploy OpenAppID
1 2 |
# wget https://www.snort.org/downloads/openappid/33380 -O OpenAppId-33380.tgz # tar -xzvf OpenAppId-33380.tgz |
➁Copy the extracted folder (odp) to the following directory
1 |
# cp -R odp /usr/local/lib/ |
➂Edit the main configuration file and define the location of the OpenAppID folder
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
# vi /usr/local/etc/snort/snort.lua Add per line 101 appid = { -- appid requires this to use appids in rules app_detector_dir = '/usr/local/lib', log_stats = true, } Add per line 105 appid_listener = { json_logging = true, file = "/var/log/snort/appid-output.log", } |
④Test main configuration changes
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# snort -c /usr/local/etc/snort/snort.lua If all is well, the following is displayed ... -------------------------------------------------- search engine (ac_bnfa) instances: 338 patterns: 10778 pattern chars: 175278 num states: 123344 num match states: 10498 memory scale: MB total memory: 3.68713 pattern memory: 0.577984 match list memory: 1.33597 transition memory: 1.73192 fast pattern only: 7099 appid: MaxRss diff: 225920 appid: patterns loaded: 11537 -------------------------------------------------- pcap DAQ configured to passive. Snort successfully validated the configuration (with 0 warnings). o")~ Snort exiting |
9. Create systemd service for Snort
9.1 Check all setups
Snort on network interface using local.rules
1 |
# snort -c /usr/local/etc/snort/snort.lua -R /usr/local/etc/snort/rules/local.rules -i ens33 -A alert_fast -s 65535 -k none |
Sending a ping command to the Ubuntu server IP address from another PC on the same network
You will see the following alert log in the console window of the host server
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
05/03-19:11:01.942097 [**] [1:1000001:1] "Incoming ICMP" [**] [Priority: 0] [AppID: ICMP] {ICMP} 192.168.11.22 -> 192.168.11.83 05/03-19:11:01.942098 [**] [1:1000001:1] "Incoming ICMP" [**] [Priority: 0] [AppID: ICMP] {ICMP} 192.168.11.22 -> 192.168.11.83 05/03-19:11:01.974136 [**] [1:1000001:1] "Incoming ICMP" [**] [Priority: 0] [AppID: ICMP] {ICMP} 192.168.11.83 -> 192.168.11.22 05/03-19:11:02.948665 [**] [1:1000001:1] "Incoming ICMP" [**] [Priority: 0] [AppID: ICMP] {ICMP} 192.168.11.22 -> 192.168.11.83 05/03-19:11:02.948665 [**] [1:1000001:1] "Incoming ICMP" [**] [Priority: 0] [AppID: ICMP] {ICMP} 192.168.11.22 -> 192.168.11.83 05/03-19:11:02.948739 [**] [1:1000001:1] "Incoming ICMP" [**] [Priority: 0] [AppID: ICMP] {ICMP} 192.168.11.83 -> 192.168.11.22 05/03-19:11:02.948845 [**] [1:1000001:1] "Incoming ICMP" [**] [Priority: 0] [AppID: ICMP] {ICMP} 192.168.11.83 -> 192.168.11.22 05/03-19:11:03.956689 [**] [1:1000001:1] "Incoming ICMP" [**] [Priority: 0] [AppID: ICMP] {ICMP} 192.168.11.22 -> 192.168.11.83 05/03-19:11:03.956689 [**] [1:1000001:1] "Incoming ICMP" [**] [Priority: 0] [AppID: ICMP] {ICMP} 192.168.11.22 -> 192.168.11.83 05/03-19:11:03.956746 [**] [1:1000001:1] "Incoming ICMP" [**] [Priority: 0] [AppID: ICMP] {ICMP} 192.168.11.83 -> 192.168.11.22 05/03-19:11:03.956824 [**] [1:1000001:1] "Incoming ICMP" [**] [Priority: 0] [AppID: ICMP] {ICMP} 192.168.11.83 -> 192.168.11.22 05/03-19:11:04.966197 [**] [1:1000001:1] "Incoming ICMP" [**] [Priority: 0] [AppID: ICMP] {ICMP} 192.168.11.22 -> 192.168.11.83 05/03-19:11:04.966197 [**] [1:1000001:1] "Incoming ICMP" [**] [Priority: 0] [AppID: ICMP] {ICMP} 192.168.11.22 -> 192.168.11.83 05/03-19:11:04.966304 [**] [1:1000001:1] "Incoming ICMP" [**] [Priority: 0] [AppID: ICMP] {ICMP} 192.168.11.83 -> 192.168.11.22 05/03-19:11:04.966564 [**] [1:1000001:1] "Incoming ICMP" [**] [Priority: 0] [AppID: ICMP] {ICMP} 192.168.11.83 -> 192.168.11.22 |
9.2 Create systemd service for Snort
①Create user (snort) for Snort service
1 |
# useradd -r -s /usr/sbin/nologin -M snort |
➁Create log folder and set permissions
1 2 3 |
# mkdir /var/log/snort # chmod -R 5775 /var/log/snort # chown -R snort:snort /var/log/snort |
➂Create SNORT systemd service file
1 2 |
# touch /etc/systemd/system/snort3.service # vi /etc/systemd/system/snort3.service |
Contents of snort3.service
1 2 3 4 5 6 7 8 9 10 11 |
[Unit] Description=Snort3 IDS Daemon Service 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 ens33 -m 0x1b -u snort -g snort ExecStop=/bin/kill -9 $MAINPID [Install] WantedBy=multi-user.target |
④Reload and enable Snort service
1 2 3 |
# systemctl daemon-reload # systemctl enable --now snort3 Created symlink /etc/systemd/system/multi-user.target.wants/snort3.service → /etc/systemd/system/snort3.service. |
⑤Start Snort service and check status
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
# systemctl start snort3 # systemctl status snort3 ● snort3.service - Snort3 IDS Daemon Service Loaded: loaded (/etc/systemd/system/snort3.service; enabled; preset: enabled) Active: active (running) since Sat 2024-05-04 09:41:16 JST; 1min 52s ago Main PID: 1658 (snort3) Tasks: 2 (limit: 4556) Memory: 288.9M (peak: 289.2M) CPU: 4.633s CGroup: /system.slice/snort3.service mq1658 /usr/local/bin/snort -c /usr/local/etc/snort/snort.lua -s 65535 -k none -l /var/log/snort -D -i ens33 -m 0x1b -u snort -g snort May 04 09:41:16 lepard snort[1658]: instances: 338 May 04 09:41:16 lepard snort[1658]: patterns: 10778 May 04 09:41:16 lepard snort[1658]: pattern chars: 175278 May 04 09:41:16 lepard snort[1658]: num states: 123344 May 04 09:41:16 lepard snort[1658]: num match states: 10498 May 04 09:41:16 lepard snort[1658]: memory scale: MB May 04 09:41:16 lepard snort[1658]: total memory: 3.68713 May 04 09:41:16 lepard snort[1658]: pattern memory: 0.577984 May 04 09:41:16 lepard snort[1658]: match list memory: 1.33597 May 04 09:41:16 lepard snort[1658]: transition memory: 1.73192 |
10. Snort JSON logging configuration
①Edit Snort configuration file
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
# vi /usr/local/etc/snort/snort.lua Add to end of line 281 "7. configure outputs section" --------------------------------------------------------------------------- -- 7. configure outputs --------------------------------------------------------------------------- --------------- -- additional logs --packet_capture = { } --file_log = { } alert_json = { file = true, limit = 50, fields = 'timestamp msg pkt_num proto pkt_gen pkt_len dir src_addr src_port dst_addr dst_port service rule priority class action b64_data' } |
➁Restart Snort
1 |
# systemctl restart snort3 |
➂Checking the configuration
Ping command from another PC on the same network to the Ubuntu host server
A log is recorded and saved in the Snort alert_json.txt file. Check the log file
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# tail -f /var/log/snort/alert_json.txt The following log results are displayed { "timestamp" : "05/04-09:57:21.234382", "msg" : "Incoming ICMP", "pkt_num" : 879, "proto" : "ICMP", "pkt_gen" : "raw", "pkt_len" : 60, "dir" : "S2C", "src_addr" : "192.168.11.83", "dst_addr" : "192.168.11.22", "service" : "unknown", "rule" : "1:1000001:1", "priority" : 0, "class" : "none", "action" : "allow", "b64_data" : "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dndhYmNkZWZnaGk=" } { "timestamp" : "05/04-09:57:21.234477", "msg" : "Incoming ICMP", "pkt_num" : 880, "proto" : "ICMP", "pkt_gen" : "raw", "pkt_len" : 60, "dir" : "S2C", "src_addr" : "192.168.11.83", "dst_addr" : "192.168.11.22", "service" : "unknown", "rule" : "1:1000001:1", "priority" : 0, "class" : "none", "action" : "allow", "b64_data" : "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dndhYmNkZWZnaGk=" } { "timestamp" : "05/04-09:57:22.242861", "msg" : "Incoming ICMP", "pkt_num" : 991, "proto" : "ICMP", "pkt_gen" : "raw", "pkt_len" : 60, "dir" : "C2S", "src_addr" : "192.168.11.22", "dst_addr" : "192.168.11.83", "service" : "unknown", "rule" : "1:1000001:1", "priority" : 0, "class" : "none", "action" : "allow", "b64_data" : "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dndhYmNkZWZnaGk=" } { "timestamp" : "05/04-09:57:22.242861", "msg" : "Incoming ICMP", "pkt_num" : 992, "proto" : "ICMP", "pkt_gen" : "raw", "pkt_len" : 60, "dir" : "C2S", "src_addr" : "192.168.11.22", "dst_addr" : "192.168.11.83", "service" : "unknown", "rule" : "1:1000001:1", "priority" : 0, "class" : "none", "action" : "allow", "b64_data" : "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dndhYmNkZWZnaGk=" } { "timestamp" : "05/04-09:57:22.242912", "msg" : "Incoming ICMP", "pkt_num" : 993, "proto" : "ICMP", "pkt_gen" : "raw", "pkt_len" : 60, "dir" : "S2C", "src_addr" : "192.168.11.83", "dst_addr" : "192.168.11.22", "service" : "unknown", "rule" : "1:1000001:1", "priority" : 0, "class" : "none", "action" : "allow", "b64_data" : "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dndhYmNkZWZnaGk=" } { "timestamp" : "05/04-09:57:22.242985", "msg" : "Incoming ICMP", "pkt_num" : 994, "proto" : "ICMP", "pkt_gen" : "raw", "pkt_len" : 60, "dir" : "S2C", "src_addr" : "192.168.11.83", "dst_addr" : "192.168.11.22", "service" : "unknown", "rule" : "1:1000001:1", "priority" : 0, "class" : "none", "action" : "allow", "b64_data" : "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dndhYmNkZWZnaGk=" } { "timestamp" : "05/04-09:57:23.254556", "msg" : "Incoming ICMP", "pkt_num" : 1018, "proto" : "ICMP", "pkt_gen" : "raw", "pkt_len" : 60, "dir" : "C2S", "src_addr" : "192.168.11.22", "dst_addr" : "192.168.11.83", "service" : "unknown", "rule" : "1:1000001:1", "priority" : 0, "class" : "none", "action" : "allow", "b64_data" : "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dndhYmNkZWZnaGk=" } { "timestamp" : "05/04-09:57:23.254557", "msg" : "Incoming ICMP", "pkt_num" : 1019, "proto" : "ICMP", "pkt_gen" : "raw", "pkt_len" : 60, "dir" : "C2S", "src_addr" : "192.168.11.22", "dst_addr" : "192.168.11.83", "service" : "unknown", "rule" : "1:1000001:1", "priority" : 0, "class" : "none", "action" : "allow", "b64_data" : "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dndhYmNkZWZnaGk=" } { "timestamp" : "05/04-09:57:23.254611", "msg" : "Incoming ICMP", "pkt_num" : 1020, "proto" : "ICMP", "pkt_gen" : "raw", "pkt_len" : 60, "dir" : "S2C", "src_addr" : "192.168.11.83", "dst_addr" : "192.168.11.22", "service" : "unknown", "rule" : "1:1000001:1", "priority" : 0, "class" : "none", "action" : "allow", "b64_data" : "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dndhYmNkZWZnaGk=" } { "timestamp" : "05/04-09:57:23.254678", "msg" : "Incoming ICMP", "pkt_num" : 1021, "proto" : "ICMP", "pkt_gen" : "raw", "pkt_len" : 60, "dir" : "S2C", "src_addr" : "192.168.11.83", "dst_addr" : "192.168.11.22", "service" : "unknown", "rule" : "1:1000001:1", "priority" : 0, "class" : "none", "action" : "allow", "b64_data" : "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dndhYmNkZWZnaGk=" } |