Suricata IDS/IPS Complete Setup & Rule Writing Guide (2026)

·

Suricata is the open-source engine that sits between your network and your SIEM. It reads a copy of your traffic (or sits inline in the packet path), matches it against tens of thousands of signatures, and emits both classic alerts and a rich EVE JSON stream that describes every flow, DNS lookup, TLS handshake and HTTP transaction it sees. It is the beating heart of platforms like Security Onion and pfSense, but it runs perfectly well on its own — and running it yourself is how you actually learn network detection engineering.

This guide targets Suricata 8.0 (8.0.7 is the current stable branch at time of writing; 7.0 remains the long-term-support line). We install it three ways — native on Ubuntu, in Docker with a full compose file, and on an alternative platform — then tune suricata.yaml, load and write rules, flip the engine from passive IDS into inline IPS that drops packets, and — because CyberHawk is a blue-team shop first — ship the output into a SIEM with matched KQL and SPL queries. Everything here is for defending networks you own or are authorised to monitor.

◈ Table of Contents

01 What Suricata Is & Why It Matters 02 Prerequisites & Requirements 03 Method 1 — Native Install (Ubuntu) 04 Method 2 — Docker & Compose 05 Method 3 — RHEL & Firewall Platforms 06 Initial Configuration & First Run 07 Core Configuration That Matters 08 Rule Management & Writing Rules 09 IDS → Inline IPS Mode 10 SIEM Integration (KQL + SPL) 11 Maintenance & Troubleshooting 12 Sources & References
🦅

01 · What Suricata Is & Why It Matters

Foundation

Suricata is a high-performance network threat-detection engine maintained by the non-profit Open Information Security Foundation (OISF). It does three jobs from one binary: IDS (passively watch a traffic copy and alert), IPS (sit inline and drop malicious packets), and NSM (network security monitoring — log metadata about every flow, protocol and file, whether or not a rule fired). That third job is the one people underestimate: even with zero alerts, Suricata's EVE JSON gives you a full record of who talked to whom, over what protocol, with which TLS certificate and JA3 hash.

1
IDS vs IPS vs NSM — the three modes
Concepts

The same rules and config drive all three modes; what changes is where Suricata sits in the network and whether it can modify traffic. Understand this before you touch the config, because it decides your cabling and your capture method.

ModePositionCan block?Typical use
IDSOut-of-band, on a SPAN/mirror port or network TAPNo — alert onlyVisibility, hunting, SOC detection
IPSInline — traffic physically passes through the hostYes — drop / rejectPerimeter / segment enforcement
NSMEither; runs alongside IDS/IPSN/AFlow / protocol / file metadata logging

Start in IDS mode. Get clean detection and zero false-positive noise on a mirror port before you ever put Suricata inline — an inline engine that drops on a bad rule takes production down with it.

2
Suricata vs Snort — why the multi-threading matters
Comparison

Suricata and Snort share a broadly compatible rule language, so ruleset choice is not the deciding factor. Architecture is. Suricata was built multi-threaded from day one and natively parses application-layer protocols and extracts files; Snort 3 added multi-threading later. For most greenfield deployments in 2026, Suricata is the default choice for line-rate inspection.

FeatureSuricata 8.0Snort 3
ThreadingMulti-threaded coreMulti-threaded (Snort 3)
Protocol parsingAutomatic app-layer (HTTP2, TLS, SMB, DNS, QUIC)Service inspectors
Structured outputEVE JSON (native)via plugins
File extraction / hashingBuilt-in (MD5/SHA1/SHA256)Limited
Rule compatibilityReads most Snort rules + ET rulesetsSnort-native

Where Suricata earns its place in a defensive stack:

🛰️

Perimeter Visibility

Mirror the WAN/uplink into Suricata to see command-and-control beacons, exploit attempts and data exfiltration leaving the network.

🧭

East-West Monitoring

Tap inter-VLAN or datacentre traffic to catch lateral movement that never touches the perimeter firewall.

🧾

NSM Metadata for Hunting

Even without alerts, DNS/TLS/HTTP/flow records feed threat hunts and retrospective IOC sweeps in your SIEM.

⛔

Inline Enforcement

Drop known-bad traffic at a segment boundary or home-lab gateway with tuned drop rules.

Suricata inspects what it can see. On switched networks it needs a SPAN/mirror port or a hardware TAP; plugging it into a normal access port shows you only broadcast traffic and the host's own packets.

📋

02 · Prerequisites & Requirements

Planning

Suricata is CPU-bound: throughput scales with cores and RAM because each worker thread inspects a slice of the traffic against the full ruleset held in memory. Under-size the box and you get kernel_drops — packets Suricata never inspected — which is a silent detection gap, not a crash.

3
Hardware & software sizing
Requirements

Sizing depends on inspected throughput and ruleset size. The figures below are a practical baseline for the full ET Open ruleset (~50k rules). A rough field rule of thumb: budget one worker core per ~200–500 Mbps of sustained traffic.

ResourceHome lab / <250 MbpsProduction / 1 Gbps+
CPU2–4 cores MIN8–16 cores REC
RAM4 GB16–32 GB
Disk (logs)20 GB SSD200 GB+ SSD, log rotation
Capture NIC1× monitoring interfaceDedicated NIC, RSS multi-queue
OSUbuntu 22.04/24.04 LTSUbuntu 24.04 / RHEL 9 / Rocky 9
Traffic sourceSPAN / mirror portHardware TAP + aggregation

Give the OS a separate management NIC from the capture NIC. The capture interface should have no IP address — it exists only to receive mirrored packets, which keeps the sensor invisible on the monitored segment.

4
Identify your interfaces before you start
Prep

You need the exact name of the interface Suricata will listen on. Do not guess — confirm it, and note its speed so you can size ring buffers later.

Terminal · discover interfaces
# List interfaces and the default-route NIC $ ip -br link show $ ip route show default # Confirm link speed of the capture NIC (needs ethtool) $ sudo ethtool eth0 | grep -i speed

Throughout this guide the capture interface is eth0. Substitute your real name (often ens160, enp3s0 or eth1). Using the wrong interface is the single most common reason a fresh install produces zero alerts.

🧱

03 · Method 1 — Native Install on Ubuntu

Install A

The OISF maintains an official Ubuntu PPA that always carries the current stable release — this is the recommended path for a dedicated sensor. We will install from the PPA, then show a source build for when you need a feature flag the package does not ship.

5
Install from the official OISF PPA
Recommended

The suricata-stable PPA ships the current 8.0 branch with suricata-update bundled. Install jq too — you will read EVE JSON with it constantly.

Terminal · PPA install
$ sudo apt-get update $ sudo apt-get install -y software-properties-common $ sudo add-apt-repository -y ppa:oisf/suricata-stable $ sudo apt-get update $ sudo apt-get install -y suricata jq
Terminal · verify
$ suricata -V # This is Suricata version 8.0.x RELEASE $ suricata --build-info | grep -E 'AF_PACKET|NFQ|Rust|Hyperscan'

Check --build-info for Hyperscan support. Hyperscan is Intel's high-speed multi-pattern matcher — with it enabled, rule matching is dramatically faster on x86 sensors handling real traffic.

6
Alternative — build from source
Advanced

Build from source only when you need a specific compile-time option (e.g. a particular capture library). Suricata 8.0's engine is written in Rust and C, so the build needs the Rust toolchain and cbindgen alongside the usual C build dependencies.

Terminal · build dependencies
$ sudo apt-get install -y build-essential libpcre2-dev libyaml-dev \ libjansson-dev libcap-ng-dev libmagic-dev libnetfilter-queue-dev \ pkg-config rustc cargo cbindgen
Terminal · configure, compile, install
$ wget https://www.openinfosecfoundation.org/download/suricata-8.0.7.tar.gz $ tar xzf suricata-8.0.7.tar.gz && cd suricata-8.0.7 $ ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var \ --enable-nfqueue --enable-rust $ make -j"$(nproc)" $ sudo make install-full # installs binary, config AND a starter ruleset

make install-full also pulls a default ruleset and lays down a working suricata.yaml. Plain make install does neither — you would then have a binary with no rules and no config, which trips up first-time builders.

🐳

04 · Method 2 — Docker & Compose

Install B

Docker is ideal when you want the sensor isolated from the host OS or reproducible across machines. The catch: to inspect host traffic the container must use network_mode: host and the NET_ADMIN/NET_RAW capabilities — a bridged container only sees its own namespace.

7
Quick disposable run
Run

The community jasonish/suricata image (maintained by an OISF developer) is the fastest way to kick the tyres. Mount host directories for logs and rules so nothing is lost when the container is recreated.

Terminal · pull & run on host network
$ docker pull jasonish/suricata:latest $ docker run --rm -it --net=host \ --cap-add=net_admin --cap-add=net_raw --cap-add=sys_nice \ -v $PWD/logs:/var/log/suricata \ jasonish/suricata:latest -i eth0
8
Production docker-compose.yml
Compose

For a persistent sensor, define it in compose so config, rules and logs are bind-mounted and the container restarts with the host. Create the three local folders first, drop your suricata.yaml into ./config, then bring it up.

docker-compose.yml
services: suricata: image: jasonish/suricata:latest container_name: suricata network_mode: host # required to see host traffic cap_add: - net_admin - net_raw - sys_nice command: -i eth0 # capture interface volumes: - ./config:/etc/suricata - ./logs:/var/log/suricata - ./rules:/var/lib/suricata/rules restart: unless-stopped environment: - TZ=Pacific/Auckland
Terminal · launch & watch
$ mkdir -p config logs rules $ docker compose up -d $ docker compose logs -f suricata $ docker compose exec suricata suricata -V

Run suricata-update inside the container with docker compose exec suricata suricata-update, then restart the service. Because ./rules is bind-mounted, the fetched ruleset survives image upgrades.

🖧

05 · Method 3 — RHEL & Firewall Platforms

Install C

Two common alternatives to a bare Ubuntu box: an enterprise RHEL/Rocky sensor, and running Suricata as an inline IPS engine inside an existing firewall distribution like pfSense or OPNsense.

9
RHEL 9 / Rocky Linux 9 via COPR
RHEL

OISF publishes an official Fedora COPR repository that builds current Suricata for RHEL-family systems. Enable EPEL first for dependencies.

Terminal · Rocky/RHEL 9 install
$ sudo dnf install -y epel-release dnf-plugins-core $ sudo dnf copr enable @oisf/suricata-8.0 $ sudo dnf install -y suricata jq $ sudo systemctl enable --now suricata
10
pfSense / OPNsense as an appliance
Firewall

Both pfSense and OPNsense ship Suricata as an installable package/plugin that runs inline on a WAN or LAN interface with a GUI for rules and drop policy. This is the least-effort route to an inline IPS if you already run one of these firewalls — you enable it per-interface rather than editing YAML.

  • 1
    pfSense: System → Package Manager → Available Packages → install suricata, then Services → Suricata to add an interface.
  • 2
    OPNsense: Services → Intrusion Detection → Administration → tick Enabled and IPS mode, choose interfaces, then Download rules under the Schedule/Download tabs.
  • 3
    On a firewall, always enable on the LAN side of NAT where you see real internal IPs, not just the post-NAT WAN address.

Firewall-integrated Suricata uses that platform's own service scripts and file layout. The command-line tuning in the next sections applies to standalone installs (Methods 1–2); on pfSense/OPNsense make the equivalent changes in the GUI so the platform does not overwrite your edits.

⚙️

06 · Initial Configuration & First Run

Setup

The master config is /etc/suricata/suricata.yaml. It is large, but only a handful of settings matter for a working first run: your network variables, the capture method, and the interface.

11
Set HOME_NET to your real networks
Critical

HOME_NET tells Suricata which addresses are "yours" — nearly every rule is written in terms of traffic to/from home versus external. Get this wrong and directional rules silently misfire. Edit the vars → address-groups block.

/etc/suricata/suricata.yaml · vars
vars: address-groups: HOME_NET: "[192.168.0.0/16,10.0.0.0/8,172.16.0.0/12]" EXTERNAL_NET: "!$HOME_NET" port-groups: HTTP_PORTS: "80" SHELLCODE_PORTS: "!80"

Set HOME_NET to the networks you actually monitor — do not leave it as any. With HOME_NET: any, EXTERNAL_NET becomes !any (nothing), and a large class of "external → internal" rules will never match.

12
Configure AF_PACKET capture
Capture

On Linux, AF_PACKET is the default high-performance capture method for IDS mode. Point it at your interface and set cluster-type: cluster_flow so packets from the same flow always hit the same worker thread.

/etc/suricata/suricata.yaml · af-packet
af-packet: - interface: eth0 cluster-id: 99 cluster-type: cluster_flow defrag: yes use-mmap: yes ring-size: 200000 # raise if you see kernel_drops tpacket-v3: yes
Terminal · disable NIC offloading (accurate capture)
# Offloading hands Suricata reassembled super-frames — turn it off on the capture NIC $ sudo ethtool -K eth0 gro off lro off tso off gso off rx-vlan-offload off

Leaving generic-receive-offload (gro) or large-receive-offload (lro) on the capture NIC makes the kernel merge packets before Suricata sees them, corrupting stream reassembly and causing missed detections. Disable them and persist the change via a systemd unit or your network config.

13
Validate config, then first run
Launch

Always run the config self-test (-T) before starting the service — it parses the YAML and loads every rule, catching typos and bad signatures without touching traffic.

Terminal · test then run
# Test config + rules (v = verbose) $ sudo suricata -T -c /etc/suricata/suricata.yaml -v # Foreground run for a first look $ sudo suricata -c /etc/suricata/suricata.yaml -i eth0
Terminal · run as a managed service
# Set the capture interface for the systemd unit $ sudoedit /etc/default/suricata # set IFACE=eth0, LISTENMODE=af-packet $ sudo systemctl enable --now suricata $ systemctl status suricata --no-pager
First run succeeds when
  • suricata -T reports "Configuration provided was successfully loaded. Exiting."
  • /var/log/suricata/suricata.log ends with "engine started"
  • /var/log/suricata/stats.log begins updating every 8 seconds
  • /var/log/suricata/eve.json starts filling with flow/dns/tls events
🧩

07 · Core Configuration That Matters

Tuning

The defaults get you alerts; these settings get you a usable, performant sensor. The single most important output is EVE JSON — it is what your SIEM consumes.

14
EVE JSON — the output that feeds everything
Output

EVE (Extensible Event Format) writes one JSON object per line, tagged with an event_type. Enable only the event types you will actually use — logging every HTTP transaction on a busy link fills disks fast.

/etc/suricata/suricata.yaml · eve-log
outputs: - eve-log: enabled: yes filetype: regular filename: eve.json types: - alert: metadata: yes tagged-packets: yes - anomaly - http: extended: yes - dns - tls: extended: yes - flow - files: force-hash: [sha256]
event_typeWhat it records
alertA rule matched — signature, severity, 5-tuple, category
flowConnection summary: bytes, packets, duration, state
dnsEvery query and answer — gold for C2 and DGA hunting
tlsSNI, cert subject/issuer, JA3/JA3S fingerprints
httpHost, URI, method, user-agent, status
filesTransferred file names + hashes (for IOC matching)
15
Read EVE JSON like a pro with jq
Analysis

Before EVE reaches a SIEM you will triage it on the box with jq. These three one-liners cover 90% of day-to-day sensor work.

Terminal · triage with jq
# Live-tail only alerts, compact one-line summaries $ tail -f /var/log/suricata/eve.json | jq -c 'select(.event_type=="alert") | {ts:.timestamp, sig:.alert.signature, src:.src_ip, dst:.dest_ip}' # Top 10 firing signatures $ jq -r 'select(.event_type=="alert") | .alert.signature' eve.json | sort | uniq -c | sort -rn | head # Every unique TLS SNI seen (C2 / beacon hunting) $ jq -r 'select(.event_type=="tls") | .tls.sni' eve.json | sort -u

Set cpu-affinity in the threading section to pin worker threads to specific cores and keep them off the management/IRQ cores. On multi-queue NICs this is the highest-impact performance change after enabling Hyperscan.

✍️

08 · Rule Management & Writing Rules

Detection

Rules are the detections. You will run a mix of community rulesets (managed by suricata-update) and your own local rules for environment-specific threats.

16
Manage rulesets with suricata-update
Rulesets

suricata-update fetches, merges and enables rule sources. By default it pulls the free Emerging Threats (ET) Open ruleset into /var/lib/suricata/rules/suricata.rules.

Terminal · fetch and manage rules
# First fetch — pulls ET Open by default $ sudo suricata-update # See available free/commercial sources, then enable one $ sudo suricata-update update-sources $ sudo suricata-update list-sources $ sudo suricata-update enable-source et/open $ sudo suricata-update

Point Suricata at the merged rule file and your own local rules in suricata.yaml:

/etc/suricata/suricata.yaml · rules
default-rule-path: /var/lib/suricata/rules rule-files: - suricata.rules - /etc/suricata/rules/local.rules # your custom rules
17
Anatomy of a Suricata rule
Syntax

Every rule is action protocol src_ip src_port direction dst_ip dst_port (options). The options in parentheses carry the message, the match logic (keywords) and the mandatory metadata (sid, rev).

local.rules · annotated example
alert http $HOME_NET any -> $EXTERNAL_NET any ( \ msg:"CyberHawk Suspicious PowerShell User-Agent"; \ flow:established,to_server; \ http.user_agent; content:"WindowsPowerShell"; nocase; \ classtype:trojan-activity; \ sid:1000001; rev:1; \ )
FieldMeaning
actionalert (log), drop (IPS block, log), reject (block + RST), pass (whitelist)
protocolip, tcp, udp, icmp — or app-layer: http, tls, dns, smb, ssh
direction-> one way, <> both directions
flowState/direction, e.g. established,to_server
contentPayload/keyword match; pair with nocase, depth, offset
sid / revUnique signature ID (use 1000000+ for local) and revision

Reserved SID ranges matter: keep your custom rules at sid ≥ 1000000. Low SIDs collide with community rulesets and will be silently overwritten on the next suricata-update.

18
Write real detection rules
Hands-on

Below are four production-style local rules. The first is a harmless connectivity test; the rest map to real, high-value detections. Note the use of app-layer keywords (http.header, dns.query, tls.sni) — these are faster and more precise than raw content matches.

local.rules · ICMP sanity check
alert icmp any any -> $HOME_NET any (msg:"CyberHawk ICMP ping to HOME_NET"; itype:8; sid:1000010; rev:1;)
local.rules · Log4Shell JNDI exploit (CVE-2021-44228)
alert http any any -> $HOME_NET any ( \ msg:"CyberHawk Log4Shell JNDI lookup in HTTP header"; \ flow:established,to_server; \ http.header; content:"jndi|3a|"; nocase; \ pcre:"/\$\{jndi:(ldap|ldaps|rmi|dns|nis|iiop|corba|nds|http):/i"; \ classtype:attempted-admin; reference:cve,2021-44228; \ sid:1000011; rev:1;)
local.rules · Newly-created / suspicious TLD DNS lookup
alert dns $HOME_NET any -> any any ( \ msg:"CyberHawk DNS query to high-risk TLD"; \ dns.query; pcre:"/\.(zip|mov|top|xyz)$/i"; \ classtype:bad-unknown; sid:1000012; rev:1;)
local.rules · TLS SNI to a known-bad domain
alert tls $HOME_NET any -> any any ( \ msg:"CyberHawk TLS SNI matches watchlist domain"; \ tls.sni; content:"bad-c2-domain.example"; nocase; endswith; \ classtype:trojan-activity; sid:1000013; rev:1;)

ET Open already ships strong coverage for Log4Shell, EternalBlue (CVE-2017-0144 / MS17-010) and thousands more. Write local rules for what the community rulesets do not know: your internal watchlist domains, your naming conventions, and traffic that should never happen on your network.

19
Test that your rules actually fire
Verify

A rule you have not seen fire is a rule you do not have. Reload rules, generate matching traffic, and confirm the alert lands in both fast.log and eve.json.

Terminal · reload, generate, confirm
# Validate the new local rule parses $ sudo suricata -T -c /etc/suricata/suricata.yaml -S /etc/suricata/rules/local.rules -v # Reload rules live, no restart / no dropped packets $ sudo suricatasc -c reload-rules # Trigger the canonical ET/GPL test signature (sid 2100498) $ curl -s http://testmynids.org/uid/index.html > /dev/null # Confirm the alert $ tail -n 5 /var/log/suricata/fast.log $ jq -c 'select(.event_type=="alert") | .alert.signature' /var/log/suricata/eve.json | tail -n 3

If nothing fires: recheck the capture interface, confirm the traffic actually crossed the monitored link (a curl from the sensor itself may not be mirrored), and verify NIC offloading is off. "No alerts" almost always means "no packets," not "no threats."

⛔

09 · IDS → Inline IPS Mode

Enforcement

To block instead of merely alert, Suricata must be inline — traffic has to pass through it. There are two supported ways to do that on Linux: NFQUEUE (hook into iptables/nftables) and AF_PACKET IPS (bridge two interfaces). We show both, plus the packet path.

IDS sees a copy and can only alert; IPS sits in the packet path and can drop.
20
IPS via NFQUEUE (single-homed host)
NFQUEUE

NFQUEUE hands packets from the Linux firewall to Suricata for a verdict. This is the simplest inline method on a gateway/router host. You queue traffic with iptables, then run Suricata with -q.

Terminal · queue traffic + run inline
# Send forwarded traffic to queue 0 for a verdict $ sudo iptables -I FORWARD -j NFQUEUE --queue-num 0 --queue-bypass # Run Suricata inline on that queue (-q 0) $ sudo suricata -c /etc/suricata/suricata.yaml -q 0

--queue-bypass lets traffic pass if Suricata is down (fail-open) — safer for availability. Omit it for fail-closed (traffic stops if the engine dies). Choose deliberately: fail-open favours uptime, fail-closed favours security. Never discover which you picked during an incident.

21
Turn alerts into blocks
Drop policy

In IPS mode, only rules with the drop (or reject) action block. You can flip whole ET categories to drop with suricata-update's drop filter rather than hand-editing thousands of rules.

/etc/suricata/drop.conf
# Convert matching signatures from alert -> drop at update time re:trojan-activity re:attempted-admin 2100498 # the specific test sid, by number
Terminal · apply and confirm inline mode
$ sudo suricata-update --drop-conf /etc/suricata/drop.conf $ sudo suricatasc -c reload-rules # Blocked packets now show event_type alert with action "blocked" $ jq -c 'select(.event_type=="alert" and .alert.action=="blocked") | .alert.signature' /var/log/suricata/eve.json | tail

Roll out IPS in stages: run inline but keep every rule as alert for a week, review what would have dropped, and only then promote proven-clean categories to drop. This is how you avoid blocking a business-critical app on day one.

🔗

10 · SIEM Integration (KQL + SPL)

Blue Team

A sensor whose alerts nobody reads is just a space heater. Ship eve.json to your SIEM and build detections on top. Below: how to forward, then matched KQL (Microsoft Sentinel) and SPL (Splunk) for the same three hunts.

22
Forward EVE JSON to your SIEM
Shipping

Because EVE is line-delimited JSON, any log shipper can tail it. The common patterns: Filebeat's Suricata module into Elastic, the Splunk Universal Forwarder into Splunk, and the Azure Monitor Agent into a Sentinel custom table (Suricata_CL). Wazuh reads eve.json natively.

Filebeat · enable the Suricata module (Elastic)
$ sudo filebeat modules enable suricata $ sudo sed -i 's#var.paths.*#var.paths: ["/var/log/suricata/eve.json"]#' /etc/filebeat/modules.d/suricata.yml $ sudo filebeat setup && sudo systemctl restart filebeat
Wazuh agent · read eve.json (ossec.conf)
<localfile> <log_format>json</log_format> <location>/var/log/suricata/eve.json</location> </localfile>
23
Detection 1 — top firing signatures
Triage

What this finds: the loudest Suricata alerts over the last 24 hours — your triage starting point and a fast way to spot a noisy rule that needs tuning.

DETECTS > Alert volume by signature (Microsoft Sentinel / Log Analytics)
KQL · Microsoft Sentinel
Suricata_CL | where TimeGenerated > ago(24h) | where event_type_s == "alert" | summarize Hits = count() by Signature = alert_signature_s, Category = alert_category_s | sort by Hits desc | take 25
DETECTS > Same triage view in Splunk
SPL · Splunk
index=suricata sourcetype="suricata:json" event_type=alert earliest=-24h | stats count AS Hits by alert.signature alert.category | sort - Hits | head 25
24
Detection 2 — high-severity alerts to internal hosts
Priority

What this finds: severity-1 alerts targeting your own address space — exploitation attempts and confirmed trojan activity that jump the queue.

DETECTS > Priority-1 alerts destined for internal hosts (Sentinel)
KQL · Microsoft Sentinel
Suricata_CL | where event_type_s == "alert" | where alert_severity_d == 1 | where ipv4_is_private(dest_ip_s) | project TimeGenerated, alert_signature_s, src_ip_s, dest_ip_s, dest_port_d | sort by TimeGenerated desc
DETECTS > Same priority filter in Splunk
SPL · Splunk
index=suricata sourcetype="suricata:json" event_type=alert "alert.severity"=1 | search dest_ip=10.0.0.0/8 OR dest_ip=192.168.0.0/16 OR dest_ip=172.16.0.0/12 | table _time alert.signature src_ip dest_ip dest_port | sort - _time
25
Detection 3 — IPS blocks & beaconing DNS
Hunt

What this finds: traffic Suricata actually dropped in IPS mode, plus internal hosts making an abnormally high number of DNS queries to few unique domains — a classic C2 beacon or DGA pattern surfaced from EVE dns events.

DETECTS > Dropped/blocked packets in the last hour (Sentinel)
KQL · Microsoft Sentinel
Suricata_CL | where event_type_s == "alert" and alert_action_s == "blocked" | where TimeGenerated > ago(1h) | summarize Drops = count() by alert_signature_s, src_ip_s | sort by Drops desc
DETECTS > DNS beacon shape — high query count, low domain diversity (Splunk)
index=suricata sourcetype="suricata:json" event_type=dns dns.type=query | stats count AS queries dc(dns.rrname) AS unique_domains by src_ip | where queries > 500 AND unique_domains < 5 | sort - queries

Field names depend on your ingestion path — a Sentinel custom-log table flattens keys to alert_signature_s, while the Splunk TA keeps nested alert.signature. Run one raw query first and read the actual field names before building dashboards.

🛠️

11 · Maintenance & Troubleshooting

Operations

A sensor is not fire-and-forget. Keep rules fresh, watch for packet loss, and know the failure signatures cold.

26
Automate rule updates & live reload
Upkeep

Fresh rules matter — ET Open updates daily. Schedule suricata-update then trigger a live reload so no packets are dropped during the refresh.

Terminal · cron job (daily 03:30)
$ echo '30 3 * * * root suricata-update && suricatasc -c reload-rules' | sudo tee /etc/cron.d/suricata-update
Terminal · the unix-socket control channel
$ sudo suricatasc -c uptime $ sudo suricatasc -c reload-rules # hot-reload rules $ sudo suricatasc -c iface-stat -i eth0 # drops on the capture NIC
27
Watch for packet loss — the silent killer
Health

If kernel_drops climbs, Suricata is discarding traffic it never inspected — you have a blind spot, not an error. Track it from stats.log or the EVE stats event.

Terminal · check drop counters
$ grep -E 'capture.kernel_packets|capture.kernel_drops' /var/log/suricata/stats.log | tail # Drop % from the EVE stats event $ jq -c 'select(.event_type=="stats") | {pkts:.stats.capture.kernel_packets, drops:.stats.capture.kernel_drops}' /var/log/suricata/eve.json | tail -n 1

Chronic drops? In order of impact: enable Hyperscan, pin worker threads with cpu-affinity, raise ring-size, split load across NIC RSS queues, then trim rule categories you do not need. Throwing cores at the problem is the last resort, not the first.

28
Troubleshooting — common failures
Fix-it

The problems you will actually hit, and the first thing to check for each.

SymptomLikely causeFix
Zero alerts everWrong interface / traffic not mirrored / offloading onConfirm -i iface, verify SPAN, run ethtool -K
Rules not loadingrule-files path wrong or SID collisionsuricata -T -v; check suricata.log for parse errors
High kernel_dropsUnder-sized CPU / small ring bufferHyperscan, cpu-affinity, raise ring-size
IPS not blockingRule is alert, or NFQUEUE not setUse drop action; confirm iptables NFQUEUE rule
eve.json fills diskLogging every http/flow on busy linkTrim eve-log types; add logrotate
Service won't startYAML indentation / bad interface in defaultsjournalctl -u suricata; suricata -T

Never edit suricata.yaml on a live IPS sensor without running suricata -T first. A single mis-indented line takes the engine down — and in fail-closed mode, that stops production traffic with it.

📚

12 · Sources & References

Verify
Suricata Official Documentation (OISF) — Install, Config & Rules Suricata Docs — Rule Syntax & Keywords Reference Suricata Docs — Ubuntu Installation (PPA) Suricata Docs — EVE JSON Output Format suricata-update — Ruleset Management Tool (GitHub) jasonish/suricata — Community Docker Image Proofpoint Emerging Threats — ET Open Ruleset NVD — CVE-2021-44228 (Log4Shell, CVSS 10.0) NVD — CVE-2017-0144 (EternalBlue / MS17-010, CVSS 8.8) MITRE ATT&CK — Command & Control (TA0011)

Build it in the lab first. Stand up Suricata on a mirror port, fire the testmynids.org signature, watch the alert land in eve.json, then write one local rule for something only your network knows. That loop — deploy, trigger, confirm, tune — is detection engineering. Pair this with the CyberHawk Blog guides on Security Onion, Wireshark and Zeek to build a full network-monitoring stack.

Want the detections production-ready? The CyberHawk SOPs turn Suricata alerts into full response playbooks with tuned KQL and SPL for C2, lateral movement and exfiltration.

◈ Stay Connected

Follow CyberHawk Threat Intel for threat intelligence, deployment guides and hands-on SOC tooling content.

🌐 Website ▶️ YouTube ▶️ YouTube (2) 𝕏 Twitter / X ♪ TikTok ✈️ Telegram
🔍 IOC Scanner 🛠️ Live Tools 📚 Courses 🚨 Threat Intel 📝 Blog 📋 SOPs

"They can't exploit you if you are the Exploit."