Signature Rules with Snort and Suricata
Writing and reading network rules.
Signature Rules with Snort and Suricata is a free Cyber Security Academy lesson on CoddyKit — lesson 2 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Cyber Security Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Snort and Suricata
Snort and Suricata are the two dominant open-source IDS/IPS engines. They share a largely compatible rule language, so a rule written for one usually runs on the other.
Suricata adds multi-threading, native protocol parsers, file extraction, and rich logging (EVE JSON); Snort 3 modernized its own engine similarly. Learning the rule syntax once gives you leverage over both.
Rule Anatomy
Every rule has two parts: a header and a parenthesized body of options. The header sets the action, protocol, and traffic direction; the body defines what to match and how to report.
alert tcp $EXTERNAL_NET any -> $HOME_NET 80 ( \
msg:"WEB suspicious request"; \
content:"/admin.php"; http_uri; \
sid:1000001; rev:1; )The Header Fields
The header is read left to right:
- action — alert, drop, reject, pass
- protocol — tcp, udp, icmp, ip (or app protocols in Suricata: http, dns, tls)
- source IP/port and destination IP/port
- direction —
->one-way, or<>bidirectional
Variables like $HOME_NET and $EXTERNAL_NET come from your config so rules stay portable across sites.
drop tcp any any -> $HOME_NET 22 ( msg:"SSH blocked"; sid:1000002; rev:1; )Actions: Alert vs Drop
The action determines IDS vs IPS behavior for that rule:
alert— log and notify, do not stop traffic (IDS)drop— silently discard the packet (IPS, inline only)reject— drop and send a TCP reset or ICMP unreachablepass— explicitly allow, skipping later rules
The same engine becomes IDS or IPS depending on whether it is deployed inline and which actions you use.
Content Matching
The content keyword matches a byte pattern in the payload. Text is in quotes; binary is in pipes as hex.
Anchoring keywords sharpen matches: offset, depth, distance, and within constrain where the pattern may appear, which improves both accuracy and performance.
alert tcp any any -> $HOME_NET any ( \
msg:"Malware magic bytes"; \
content:"|4D 5A|"; offset:0; depth:2; \
sid:1000003; rev:1; )Sticky Buffers
Modern rules match against protocol-aware buffers rather than the raw stream. After a buffer keyword, subsequent content matches apply to that part of the parsed protocol.
http_uri— the request URIhttp_header— request/response headershttp_user_agent— the User-Agenttls_sni/dns_query— TLS server name / DNS query
This is far more reliable than searching the whole packet for a substring.
alert http any any -> any any ( \
msg:"Suspicious user agent"; \
http.user_agent; content:"sqlmap"; nocase; \
sid:1000004; rev:1; )PCRE and nocase
When fixed strings are not enough, pcre brings Perl-compatible regular expressions. Pair a cheap content prefilter with a pcre so the regex only runs on candidate packets, preserving performance.
The nocase modifier makes a content match case-insensitive, important for headers and user-controlled fields attackers can vary.
alert http any any -> $HOME_NET any ( \
msg:"SQLi attempt in URI"; \
http.uri; content:"select"; nocase; \
pcre:"/union\s+select/i"; \
sid:1000005; rev:1; )Flow and State Keywords
The flow option scopes a rule to connection state and direction, cutting false positives and cost.
established— only on completed TCP sessionsto_server/to_client— request vs response direction
Matching server responses only when established and to_client avoids firing on stray or spoofed packets.
alert tcp $HOME_NET any -> $EXTERNAL_NET any ( \
msg:"Beacon response"; \
flow:established,to_client; \
content:"|00 01 02 03|"; \
sid:1000006; rev:1; )Metadata: sid, rev, msg, reference
Bookkeeping options keep a ruleset maintainable:
sid— unique signature ID (use 1000000+ for local rules)rev— revision number, bump on every editmsg— the alert text analysts seeclasstype— category that drives priorityreference— link to CVE or advisory
Stable sids and incrementing revs let you track and update rules without breaking dashboards and suppressions.
alert tcp any any -> $HOME_NET 445 ( \
msg:"EternalBlue exploit attempt"; \
flow:to_server,established; content:"|FF|SMB"; \
classtype:attempted-admin; \
reference:cve,2017-0144; sid:1000007; rev:2; )Snort vs Suricata Differences
Though rule-compatible, the engines differ in capability:
- Suricata is multi-threaded, parses application protocols natively, extracts files, computes JA3, and emits EVE JSON
- Snort 3 rewrote its engine for performance and a modular plugin system
Some keywords are engine-specific. Suricata adds app-layer keywords (tls.sni, dns.query, http.method) and dataset/flowbits features. When sharing rules, target the lowest common denominator or maintain engine-specific rule sets.
Rate Filtering and Thresholds
To stop a rule from flooding the console, apply thresholds. detection_filter fires only after N events in a window; threshold with limit caps alert volume.
This is essential for brute-force and scan detections where one event is meaningless but a burst is the signal.
alert tcp any any -> $HOME_NET 22 ( \
msg:"SSH brute force"; flow:to_server; \
detection_filter:track by_src, count 5, seconds 60; \
sid:1000008; rev:1; )Quick Check
Read a rule and predict its behavior.
Recap
You can now read and write Snort/Suricata signatures:
- A rule = header (action, proto, src/dst, direction) + body options
- Action sets IDS vs IPS:
alert,drop,reject,pass contentwith offset/depth and hex matches payload bytes- Sticky buffers (http.uri, tls.sni, dns.query) match parsed protocol fields
pcreandnocasehandle variable patternsflowscopes to state and directionsid/rev/msg/referencekeep rules maintainable- Thresholds tame brute-force and scan noise
Next: detecting threats with no signature at all.
Frequently asked questions
Is the “Signature Rules with Snort and Suricata” lesson free?
Yes — the full text of “Signature Rules with Snort and Suricata” is free to read here on the web, and the Cyber Security Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Cyber Security Academy course, upgrade to CoddyKit PRO.
What will I learn in “Signature Rules with Snort and Suricata”?
Writing and reading network rules. You practise Cyber Security Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Cyber Security Academy?
No prior experience is required. Cyber Security Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Signature Rules with Snort and Suricata” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Cyber Security Academy lesson?
Yes. Every Cyber Security Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- IDS vs IPS Concepts
- Signature Rules with Snort and Suricata
- Anomaly and Behavioral Detection
- Tuning and Deployment