Hello Everyone,
After having spent more than a week trying to understand the IPS mode in Suricata, trying both the Netfilter (NFQ) and af-packet modes, I finally decided to configure my Suricata installation as an af-packet inline/IPS mode on my Ubuntu virtual private server with a single network interface and limited resources (1 vCPU, 3 GB RAM). I finally tested it today and it failed! My testing was trying to drop ping requests. Here’s a step-by-step of what I did.
Before implementing the af-packet inline/IPS mode, I’d to find out which Suricata rule gets triggered when pings come in. I pinged my VPS and the following alert was logged in file, ‘/var/log/suricata/fast.log’:
12/31/2024-12:25:14.937611 [**] [1:2100369:7] GPL ICMP PING BayRS Router [**] [Classification: Misc activity] [Priority: 3] {ICMP} 96.32.XXX.XXX:8 -> 23.94.XX.XXX:0
So, the relevant rule is with an sid (signature ID) of 2100369. I located this rule in ‘/var/lib/suricata/rules/suricata.rules’ and looks like this:
alert icmp $EXTERNAL_NET any -> $HOME_NET any (msg:"GPL ICMP PING BayRS Router"; itype:8; content:"|01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F|"; depth:32; reference:arachnids,438; reference:arachnids,444; classtype:misc-activity; sid:2100369; rev:7; metadata:created_at 2010_09_23, confidence Medium, signature_severity Informational, updated_at 2019_07_26;)
I included the sid (2100369) in file ‘/etc/suricata/disable.conf’ to disable it, copied the rule over to my custom rules file at ‘/var/lib/suricata/rules/custom.rules’ to be modified. In my custom rules file, I edited it to appear like the following:
drop icmp $EXTERNAL_NET any -> $HOME_NET any (msg:"DROPPED: GPL ICMP PING BayRS Router"; itype:8; content:"|01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F|"; depth:32; threshold: type limit, track by_src, seconds 300, count 1; reference:arachnids,438; reference:arachnids,444; classtype:misc-activity; sid:1000003; rev:7; metadata:created_at 2010_09_23, confidence Medium, signature_severity Informational, updated_at 2019_07_26;)
Basically, I replaced ‘alert’ with ‘drop’, inserted 'DROPPED: ’ right after ‘msg:"’ for more appropriate description of expected outcome, replaced the original sid with 1000003 ( which is within the 1000000-1999999 range reserved for local use to avoid conflicts) and inserted threshold settings, ‘threshold: type limit, track by_src, seconds 300, count 1;’, in the options area to make sure I’m not getting flooded with alerts.
Portions of the relevant settings in my main Suricata configuration file ‘/etc/suricata/suricata.yaml’ look like this:
%YAML 1.1
---
vars:
address-groups:
HOME_NET: "[23.94.XX.XXX]"
EXTERNAL_NET: "!$HOME_NET"
af-packet:
- interface: eth0
threads: 1
copy-mode: ips
bypass: no
defrag: yes
cluster-type: cluster_flow
cluster-id: 98
tpacket-v3: yes
ring-size: 1024
buffer-size: 64535
use-mmap: yes
default-rule-path: /var/lib/suricata/rules
rule-files:
- custom.rules
- suricata.rules
Tested for the correctness of the configuration file.
$ sudo suricata -T -c /etc/suricata/suricata.yaml -v
Notice: suricata: This is Suricata version 7.0.8 RELEASE running in SYSTEM mode
Info: cpu: CPUs/cores online: 1
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. 41420 rules successfully loaded, 0 rules failed, 0
Info: threshold-config: Threshold config parsed: 0 rule(s) found
Info: detect: 41423 signatures processed. 1166 are IP-only rules, 4292 are inspecting packet payload, 35746 inspect application layer, 108 are decoder event only
Notice: suricata: Configuration provided was successfully loaded. Exiting.
Seeing ‘Setting engine mode to IDS mode by default’ in the test result is unexpected when it was supposed to be IPS.
I then executed the following commands to apply the changes.
sudo systemctl restart suricata
sudo suricata-update
From my local computer, I pinged my VPS and here’s the result:
$ ping -c 4 23.94.XX.XXX
PING 23.94.XX.XXX (23.94.XX.XXX): 56 data bytes
64 bytes from 23.94.XX.XXX: icmp_seq=0 ttl=53 time=11.536 ms
64 bytes from 23.94.XX.XXX: icmp_seq=1 ttl=53 time=16.576 ms
64 bytes from 23.94.XX.XXX: icmp_seq=2 ttl=53 time=15.246 ms
64 bytes from 23.94.XX.XXX: icmp_seq=3 ttl=53 time=81.148 ms
--- 23.94.XX.XXX ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max/stddev = 11.536/31.127/81.148/28.939 ms
As you can see, there is 0% packet loss indicating the custom drop rule did not work.
The ‘/var/log/suricata/fast.log’ recorded this:
12/31/2024-12:36:16.571952 [wDrop] [**] [1:1000003:7] DROPPED: GPL ICMP PING BayRS Router [**] [Classification: Misc activity] [Priority: 3] {ICMP} 96.32.XXX.XXX:8 -> 23.94.XX.XXX:0
So, as you can see all my 4 ping packets have been received although my Suricata installation that’s supposed to operate in an IPS mode triggered the corresponding drop rule for pings and wrote a record in the log file as if it dropped the ping packets when it actually did not. Please note the bypass setting under af-packet is set to ‘no’ to ensure packets won’t bypass Suricata even when it’s overwhelmed.
This is really frustrating me. If Suricata will not drop ping packets how can I have the confidence it would drop any other kinds of dangerous packets out in the internet wilderness? Please help.