IDS Rules#

Snort and Suricata share a similar rule format, a small DSL describing network packet patterns that an IDS / IPS engine looks for. The Suricata format is a strict superset; many Snort rule sets also load on Suricata.

Used by Snort 2/3, Suricata, OPNsense, pfSense, and most network security platforms. Emerging Threats and Talos publish large rule sets; SOC teams pin a version and tune from there.

Rule Anatomy#

alert tcp $EXTERNAL_NET any -> $HOME_NET 22
  (msg:"SSH brute force attempt";
   flow:established,to_server;
   content:"SSH-";
   threshold:type both, track by_src, count 5, seconds 60;
   classtype:attempted-admin;
   sid:1000001; rev:1;)

A rule is two parts.

  1. Header, action protocol src_ip src_port -> dst_ip dst_port.

  2. Options, (name:value; name:value; ...).

Header Fields#

The first line of every rule sets action, protocol, source and destination IPs and ports, and direction. Variables like $HOME_NET parameterize the addressing so the same rule travels across deployments. Suricata adds protocol names beyond TCP/UDP/ICMP for app-layer matching.

Field

Values

action

alert / log / pass / drop (IPS) / reject

protocol

tcp / udp / icmp / ip; Suricata adds http, tls, dns, smb, smtp, ftp, ssh, …

addresses

IP, CIDR, any, named variables ($HOME_NET)

ports

number, range (80:443), any, named ($HTTP_PORTS)

direction

-> (one-way) / <> (bidirectional)

Common Options#

Options live inside the parentheses and tune what the rule matches and how alerts behave. content is the fast substring match; pcre is the regex fallback; flow gates on connection state; threshold rate-limits; sticky buffers like http.uri extract protocol fields cleanly.

Option

Effect

msg:"..."

alert message

content:"..."

substring match in payload

content:"..."; nocase;

case-insensitive

pcre:"/regex/"

PCRE regex

flow:established,to_server only on established connections

threshold

rate-limit alerts

classtype

rule category

sid:N / rev:N

unique signature id and revision

reference:cve,2021-44228

external reference

priority:1-4

severity

http.method,

http.uri,

http.host,

tls.sni

Suricata sticky-buffer keywords for protocol-aware match

Suricata Extensions#

The capabilities Suricata adds on top of Snort-compatible rules. App-layer protocol awareness, a faster multi-pattern matcher, inline Lua scripting, EVE JSON output for SIEM ingestion, and dataset references for blocklists, each a reason new deployments default to Suricata.

  • App-layer protocols, match HTTP, DNS, TLS, SSH, SMB, Kerberos with protocol-aware fields.

  • Multi-pattern matcher, much faster on large rule sets.

  • Lua rules, inline scripting for custom logic.

  • EVE JSON output, structured logs of every event; the standard way to ship Suricata data into a SIEM.

  • Datasets, IP / domain / hash blocklists referenced from rules.

For new deployments, Suricata is usually the better choice.

Variables#

A typical config file (snort.conf / suricata.yaml) defines network variables.

HOME_NET:        "[10.0.0.0/8,192.168.0.0/16]"
EXTERNAL_NET:    "!$HOME_NET"
HTTP_PORTS:      "80,8080,8443"
HTTP_SERVERS:    "$HOME_NET"
SSH_PORTS:       "22"

Rules then reference $HOME_NET etc.

Examples#

# HTTP -- log4shell user-agent
alert http $EXTERNAL_NET any -> $HOME_NET any
  (msg:"log4shell jndi probe";
   http.user_agent; content:"${jndi:";
   classtype:attempted-admin; sid:1000010; rev:1;)

# DNS -- known C2 domain
alert dns $HOME_NET any -> any any
  (msg:"DNS query to known C2";
   dns.query; content:"badc2.example."; nocase; endswith;
   sid:1000011; rev:1;)

# TLS SNI match
alert tls $HOME_NET any -> $EXTERNAL_NET any
  (msg:"TLS SNI to suspicious domain";
   tls.sni; content:"evil-cdn.example";
   sid:1000012; rev:1;)

Rule Sets#

The published feeds an operator subscribes to. ET Open is the free baseline; Talos paid feeds bring deeper coverage; SSLBL targets TLS C2 fingerprints; Abuse.ch curates many specialized lists. The rule of thumb: pull, pin a snapshot, and tune from there. Never load everything raw.

  • Emerging Threats Open, free; widely used baseline.

  • Talos / Snort Subscriber Rules, paid; deeper coverage.

  • SSLBL, TLS fingerprints of known-bad C2.

  • Abuse.ch, many community feeds (URLhaus, ThreatFox).

Pull, pin, tune; never load everything blindly. False positives become a noise floor.

Tooling#

  • Snort 3, modern Snort with new architecture.

  • Suricata, the recommended modern engine.

  • pulledpork3 / suricata-update, rule-set updaters.

  • Sigma → Suricata, some Sigma rules convert to network-IDS format.

  • Zeek, complementary network analysis with a Lua-like scripting language; not strictly an IDS rule format but often deployed alongside Suricata.

Pitfalls#

The traps that catch IDS authors. Encrypted traffic limits content matching to metadata; PCRE is slower than content so option order matters; misconfigured HOME_NET silently breaks every rule; SID collisions happen across rule sets; hot reloads beat full restarts on production sensors.

  • No payload visibility on encrypted traffic, TLS / SSH is opaque except for SNI / handshake. Rule on metadata, not payloads.

  • Performance vs. specificity, content is fast; pcre is slow. Order options to put content first.

  • Variable misconfiguration, if HOME_NET is wrong, every rule is broken silently.

  • SID collisions, pick a SID range and stick to it (>= 1,000,000 is conventional for local rules).

  • Reload rather than restart, modern engines support hot reload.

When (Not) to Use#

  • Use for north-south network traffic monitoring (perimeter, DMZ, internet egress).

  • Use when you need protocol-level detection (DNS, TLS SNI, HTTP).

  • Don’t expect miracles on encrypted east-west traffic without decryption.

  • Skip for endpoint detection, EDR is the right layer.

See Also#

  • detection.

  • Sigma, the SIEM-side detection format.