Private detections let Suricata alert on traffic that public rulesets do not describe, such as internal test paths, organization-specific indicators, or short-lived investigation markers. Keeping those signatures in a separate local file makes custom rules easier to review without editing the managed ruleset that suricata-update rebuilds.
Packaged Ubuntu configurations commonly load the compiled /var/lib/suricata/rules/suricata.rules file and can also load an extra absolute rule file. A local file under /etc/suricata/rules keeps the private rule visible in configuration review while leaving /var/lib/suricata/rules for generated rule output.
Use a private sid value that does not collide with managed rules, test the configuration before touching the running service, and trigger the signature against lab traffic before relying on it. A lab HTTP test rule can match a request for /local-rule-test and write a visible alert with sid 1000001.
Related: How to disable a Suricata rule
Related: How to suppress a Suricata signature ID
Steps to add a local Suricata rule:
- Create the local rules directory.
$ sudo install -d -m 0755 /etc/suricata/rules
- Add the local signature to its own rule file.
$ sudo vi /etc/suricata/rules/local.rules
- /etc/suricata/rules/local.rules
alert http any any -> any any (msg:"SG local HTTP rule test"; http.uri; content:"/local-rule-test"; sid:1000001; rev:1;)
Use a local sid range reserved for your environment. Reusing a managed rule sid can make suppression, thresholding, and alert triage point at the wrong signature.
- Include the local file in the active rule list.
$ sudo vi /etc/suricata/suricata.yaml
- /etc/suricata/suricata.yaml
default-rule-path: /var/lib/suricata/rules rule-files: - suricata.rules - /etc/suricata/rules/local.rules
An absolute path keeps local.rules outside the managed default-rule-path while still loading it with the compiled rule file.
- Refresh the managed ruleset used by the same configuration.
$ sudo suricata-update 25/6/2026 -- 07:51:42 - <Info> -- Using Suricata configuration /etc/suricata/suricata.yaml 25/6/2026 -- 07:51:42 - <Info> -- No sources configured, will use Emerging Threats Open ##### snipped ##### 25/6/2026 -- 07:51:45 - <Info> -- Writing rules to /var/lib/suricata/rules/suricata.rules: total: 66793; enabled: 50866; added: 0; removed 0; modified: 0 25/6/2026 -- 07:51:45 - <Info> -- No changes detected, exiting.
suricata-update writes the managed /var/lib/suricata/rules/suricata.rules file that remains listed beside the local rule file.
Related: How to update Suricata rules - Test the full Suricata configuration with both rule files.
$ sudo suricata -T -c /etc/suricata/suricata.yaml -v Notice: suricata: This is Suricata version 8.0.3 RELEASE running in SYSTEM mode ##### snipped ##### Info: detect: 2 rule files processed. 50867 rules successfully loaded, 0 rules failed, 0 rules skipped Notice: suricata: Configuration provided was successfully loaded. Exiting.
The loaded rule file count should increase to include the local file, and the failed rule count should remain 0.
Related: How to test Suricata configuration - Replay lab traffic that should match the new local rule.
$ sudo suricata -r /tmp/local-rule-test.pcap -c /etc/suricata/suricata.yaml -l /tmp/suricata-local-rule i: suricata: This is Suricata version 8.0.3 RELEASE running in USER mode i: threads: Threads created -> RX: 1 W: 8 FM: 1 FR: 1 Engine started. i: suricata: Signal Received. Stopping engine. i: pcap: read 1 file, 4 packets, 292 bytes
Use a lab pcap that contains the traffic your rule is meant to catch. For the sample rule, the capture must contain an HTTP request for /local-rule-test.
- Confirm that the replay wrote the local alert.
$ sudo cat /tmp/suricata-local-rule/fast.log 06/25/2024-08:00:00.000000 [**] [1:1000001:1] SG local HTTP rule test [**] [Classification: (null)] [Priority: 3] {TCP} 192.0.2.10:49152 -> 198.51.100.20:80The bracketed alert ID should show the local sid and revision from /etc/suricata/rules/local.rules. Use /tmp/suricata-local-rule/eve.json when the alert pipeline reads EVE JSON instead of fast.log.
Related: How to view Suricata alert logs - Restart the running Suricata service after the local rule passes the replay test.
$ sudo systemctl restart suricata
Restarting loads the updated rule-files list into the service that monitors live traffic.
Related: How to manage the Suricata service - Remove the temporary replay log directory.
$ sudo rm -rf /tmp/suricata-local-rule
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.