Create Local Rules and Investigate EVE¶
Create a scoped local rule, run positive and negative tests, and trace the
result through fast.log and EVE JSON.
Configure the local rules file¶
Keep locally managed signatures separate from downloaded content and use a
local SID of at least 1000000:
sudo install -d -o root -g root -m 0755 /etc/suricata/rules
sudo install -o root -g root -m 0644 /dev/null /etc/suricata/rules/local.rules
alert icmp any any -> $HOME_NET any (
msg:"LOCAL LAB ICMP echo request";
itype:8;
classtype:misc-activity;
sid:1000001;
rev:1;
)
Add the file to rule-files in /etc/suricata/overview.yaml without changing
the managed rule path:
default-rule-path: /var/lib/suricata/rules
rule-files:
- suricata.rules
- /etc/suricata/rules/local.rules
The detailed procedure below also retains the demonstrated sid:1 example and
its fast.log evidence. Use the maintained local SID range for new rules.
Validate the rule¶
sudo suricata -T -c /etc/suricata/overview.yaml -v
sudo systemctl restart suricata
sudo systemctl is-active suricata
Run both tests from an authorised lab host:
- Positive: send one ICMP echo request into
$HOME_NET; expect SID1000001. - Negative: generate a different ICMP type or traffic outside the scoped
direction; expect no SID
1000001event.
sudo tail -n 30 /var/log/suricata/fast.log
sudo jq 'select(.event_type=="alert" and .alert.signature_id==1000001)' \
/var/log/suricata/eve.json
If the rule does not fire, verify interface counters, HOME_NET, direction,
rule loading, event timestamps, and clock synchronisation before broadening it.
Demonstrated ET Open alert test¶
The PoC also exercised ET Open SID 2100498 against a public test endpoint.
The signature, command, and observed fast.log output are retained for
traceability. For a repeatable new lab, prefer a locally controlled fixture
because public endpoints and downloaded rule revisions can change.
To test the IDS functionality of Suricata it's best to test with a signature. The signature with ID 2100498 from the ET Open ruleset is written specific for such test cases.
2100498:
alert ip any any -> any any (msg:"GPL ATTACK_RESPONSE id check returned root"; content:"uid=0|28|root|29|"; classtype:bad-unknown; sid:2100498; rev:7; metadata:created_at 2010_09_23, updated_at 2010_09_23;)
The syntax and logic behind those signatures is covered in other chapters. This will alert on any IP traffic that has the content within its payload. This rule can be triggered quite easy. Before we trigger it, start tail to see updates to fast.log.
The following output should now be seen in the log:
09/12/2024-13:51:32.520238 [**] [1:2100498:7] GPL ATTACK_RESPONSE id check returned root [**] [Classification: Potentially Bad Traffic] [Priority: 2] {TCP} 65.9.141.53:80 -> 10.0.0.25:34606Alerts:
This should include the timestamp and the IP of your system.
Detailed local-rule procedure¶
This procedure preserves the demonstrated rule-file path, sid:1 rule,
configuration change, service commands, ping test, and resulting alerts.
Translate the rule to the maintained local SID and file path shown above when
building a new sensor.
Stop Suricata service:
Create local.rules
Write following rule to alert on ping to internal network (note syntax is very similar to Snort)
Edit suricata.yml
Add local.rules to rule-files
default-rule-path: /var/lib/suricata/rules
rule-files:
- suricata.rules
- /usr/share/suricata/rules/local.rules
Test Suricata configuration:
Start Suricata and verify it is running and active.
Execute ping to Suricata host from another host in internal network
Verify that the alerts have been logged
09/12/2024-14:14:31.052314 [**] [1:1:1] ICMP Ping Detected [**] [Classification: (null)] [Priority: 3] {ICMP} 10.0.0.25:0 -> 10.0.0.20:0
09/12/2024-14:14:57.907164 [**] [1:1:1] ICMP Ping Detected [**] [Classification: (null)] [Priority: 3] {ICMP} 10.0.0.20:3 -> 10.0.0.1:3
Investigate EVE JSON¶
Use EVE as the primary structured evidence source:
sudo jq 'select(.event_type=="alert")' /var/log/suricata/eve.json
sudo jq 'select(.event_type=="dns")' /var/log/suricata/eve.json
sudo jq 'select(.event_type=="http")' /var/log/suricata/eve.json
sudo jq 'select(.event_type=="tls")' /var/log/suricata/eve.json
sudo jq 'select(.event_type=="stats") | .stats.capture' /var/log/suricata/eve.json
For one alert, record its timestamp, signature, action, source and destination,
flow_id, community_id, interface, and related protocol events. Community ID
can correlate a flow with Zeek, Security Onion, or another compatible data
source; flow_id links Suricata events from the same flow. The
Wazuh Suricata integration guide
provides one example of forwarding this structured evidence into a wider
security-monitoring workflow.
Complete EVE alert example¶
The demonstrated EVE workflow and complete ICMP alert are included below so the structured fields can be compared directly with the shorter queries above.
The more advanced output is the EVE JSON output which is explained in detail in Eve JSON Output. To see what this looks like it's recommended to use jq to parse the JSON output.
Alerts:
This will display more detail about each alert with a better readability, including meta-data.
{
"timestamp": "2024-09-12T14:21:18.932116+1200",
"flow_id": 1750955545135946,
"in_iface": "ens32",
"event_type": "alert",
"src_ip": "10.0.0.25",
"src_port": 0,
"dest_ip": "10.0.0.20",
"dest_port": 0,
"proto": "ICMP",
"icmp_type": 0,
"icmp_code": 0,
"pkt_src": "wire/pcap",
"community_id": "1:7Z0C1taw8mzKweAktDBR9AYDoBA=",
"alert": {
"action": "allowed",
"gid": 1,
"signature_id": 1,
"rev": 1,
"signature": "ICMP Ping Detected",
"category": "",
"severity": 3
},
"direction": "to_client",
"flow": {
"pkts_toserver": 1,
"pkts_toclient": 1,
"bytes_toserver": 98,
"bytes_toclient": 98,
"start": "2024-09-12T14:21:18.931964+1200",
"src_ip": "10.0.0.20",
"dest_ip": "10.0.0.25"
}
}
Stats:
sudo tail -f /var/log/suricata/eve.json | jq 'select(.event_type=="stats")|.stats.capture.kernel_packets'
sudo tail -f /var/log/suricata/eve.json | jq 'select(.event_type=="stats")'
The first example displays the number of packets captured by the kernel; the second examples shows all of the statistics.
Tune and version the rule¶
Change one condition at a time, increment rev, repeat both tests, and retain:
- the rule before and after tuning;
- the reason for the change;
- positive and negative evidence;
- observed event volume; and
- expected blind spots.