• Home
  • Articles
  • Tools
  • Support



Suricata Rule writing Guide

Using diligent Suricata testing and correct syntax, one can develop signatures based on forensics of events tested on a VM setup.
A core base of rules are at the following he Emerging Threat Suricata rules download, installed with the update command shown lower down.
https://rules.emergingthreats.net/OPEN_download_instructions.html and the Corelight rules alerts feed
https://feed.corelight.com/corelight.rules

Setup Linux for Suricata testing

Setup of Suricata on a Linux VM can help with defining logic, syntax and working alerting. Guide. The bulk of the Suricata configuration is located at /etc/suricata and the rules are stored at /var/lib/suricata/rules. Its important to note for Suricata to monitor the VM network interface, Promiscuous port monitoring should be on ($IFACE replaced with the interface identity):
sudo /sbin/ip link set $IFACE promisc on

Vmware when working with a promiscuous network adapter should prompt for monitoring, on startup. Also when stopping the Suricata service, the interface stats are displayed in suricata.log when its run correctly: [2560 - Suricata-Main] 2025-04-24 14:59:51 Notice: suricata: Signal Received. Stopping engine. [2560 - Suricata-Main] 2025-04-24 14:59:52 Info: suricata: time elapsed 181.453s [2566 - FR#01] 2025-04-24 14:59:53 Perf: flow-manager: 55 flows processed [2563 - W#01-ens33] 2025-04-24 14:59:53 Perf: af-packet: ens33: (W#01-ens33) kernel: Packets 684, dropped 0 [2564 - W#02-ens33] 2025-04-24 14:59:53 Perf: af-packet: ens33: (W#02-ens33) kernel: Packets 154, dropped 0 To start with a good set of structured rules, download emerging threat rules with the simple command:

sudo suricata-update

This gives a good set of Suricata rules into /var/lib/suricata/rules The location of the rules is set in the configuration file /etc/suricata/suricata.yaml as shown below: default-rule-path: /etc/suricata/rules other rules rule-files: - suricata.rules - local.rules To utilise a test rule and associated command, the instructions on the suricata website show there is a rule created just for confirming setup - https://docs.suricata.io/en/suricata-6.0.9/quickstart.html#alerting The test rule is found by looking through the downloaded Emerging Threat rules:

sudo cat /var/lib/suricata/rules/suricata.rules | grep 2100498

Then need to restart after any rule changes including downloading all these Emerging threat rules -- sudo systemctl restart suricata Check the /var/log/suricata/suricata/log output by using tail -f suricata.log on the file in a window. If there is a cluster error message 'cluser-id 97 already in use' its likely to be true and the cluster-id value in suricata.yaml needs changing Which requires to run the test command

curl http://testmynids.org/uid/index.html

The below output should now be seen in the log when the test has returned the following string to the CLI: uid=0(root) gid=0(root) groups=0(root):

[1:2100498:7] GPL ATTACK_RESPONSE id check returned root [**] [Classification: Potentially Bad Traffic] [Priority: 2] {TCP} 217.160.0.187:80 -> 10.0.0.23:41618

In order to start writing and adapting ones own rules, we create the local.rules file in /var/lib/suricata/rules

Writing Suricata Rules

An example of an overly noisy alert to start with is the below one which will fire for any ICMP traffic: alert icmp any any -> any any (msg:"ICMP Packet found on the system this is a noisy alert"; sid:201010;) The structure of Suricata rules must follow the following format:
drop tcp $HOME_NET any -> $EXTERNAL_NET any (msg:”ET TROJAN Likely Bot Nick in IRC (USA +..)”; flow:established,to_server; flowbits:isset,is_proto_irc; content:”NICK “; pcre:”/NICK .*USA.*[0-9]{3,}/i”; reference:url,doc.emergingthreats.net/2008124; classtype:trojan-activity; sid:2008124; rev:2;)

To alert on failed attempts to a site

alert http any any -> any any (http_response_line; content:"403 Forbidden"; sid:1;)

To alert on unusual contents in an HTTP header

alert ip any any -> any any (ipv4.hdr; content:”|3A|”; offset:9; depth:1; sid:1234; rev:5;)

To pick up on ICMP SMURF scanning

alert icmp $EXTERNAL_NET any -> $HOME_NET any (msg:”GPL SCAN Broadscan Smurf Scanner”; dsize:4; icmp_id:0; icmp_seq:0; itype:8; classtype:attempted-recon; sid:2100478; rev:4;)

Using regular expression is used with a content match to allow best performance, it is used with the pcre command, perl compatible regular expression

drop tcp $HOME_NET any -> $EXTERNAL_NET any (msg:”ET TROJAN Likely Bot Nick in IRC (USA +..)”; flow:established,to_server; flowbits:isset,is_proto_irc; content:”NICK “; pcre:”/NICK .*USA.*[0-9]{3,}/i”; reference:url,doc.emergingthreats.net/2008124; classtype:trojan-activity; sid:2008124; rev:2;)

Note that Suricata always expects a Signature sid: in the written signature, otherwise in testing you will see a signature error in Suricata.log The following two resources can guide oj the exact meaning of the rule components: https://docs.suricata.io/en/suricata-6.0.9/rules/intro.htm https://letsdefend.io/blog/how-to-install-and-configure-suricata-on-ubuntu#updating-suricata-rules