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
FoundationSuricata 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.
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.
| Mode | Position | Can block? | Typical use |
|---|---|---|---|
| IDS | Out-of-band, on a SPAN/mirror port or network TAP | No — alert only | Visibility, hunting, SOC detection |
| IPS | Inline — traffic physically passes through the host | Yes — drop / reject | Perimeter / segment enforcement |
| NSM | Either; runs alongside IDS/IPS | N/A | Flow / 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.
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.
| Feature | Suricata 8.0 | Snort 3 |
|---|---|---|
| Threading | Multi-threaded core | Multi-threaded (Snort 3) |
| Protocol parsing | Automatic app-layer (HTTP2, TLS, SMB, DNS, QUIC) | Service inspectors |
| Structured output | EVE JSON (native) | via plugins |
| File extraction / hashing | Built-in (MD5/SHA1/SHA256) | Limited |
| Rule compatibility | Reads most Snort rules + ET rulesets | Snort-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
PlanningSuricata 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.
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.
| Resource | Home lab / <250 Mbps | Production / 1 Gbps+ |
|---|---|---|
| CPU | 2–4 cores MIN | 8–16 cores REC |
| RAM | 4 GB | 16–32 GB |
| Disk (logs) | 20 GB SSD | 200 GB+ SSD, log rotation |
| Capture NIC | 1× monitoring interface | Dedicated NIC, RSS multi-queue |
| OS | Ubuntu 22.04/24.04 LTS | Ubuntu 24.04 / RHEL 9 / Rocky 9 |
| Traffic source | SPAN / mirror port | Hardware 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.
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.
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 AThe 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.
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.
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.
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.
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 BDocker 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.
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.
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.
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 CTwo 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.
OISF publishes an official Fedora COPR repository that builds current Suricata for RHEL-family systems. Enable EPEL first for dependencies.
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.
- 1pfSense:
System → Package Manager → Available Packages→ installsuricata, thenServices → Suricatato add an interface. - 2OPNsense:
Services → Intrusion Detection → Administration→ tick Enabled and IPS mode, choose interfaces, then Download rules under the Schedule/Download tabs. - 3On 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
SetupThe 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.
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.
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.
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.
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.
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.
- 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
TuningThe 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.
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.
| event_type | What it records |
|---|---|
| alert | A rule matched — signature, severity, 5-tuple, category |
| flow | Connection summary: bytes, packets, duration, state |
| dns | Every query and answer — gold for C2 and DGA hunting |
| tls | SNI, cert subject/issuer, JA3/JA3S fingerprints |
| http | Host, URI, method, user-agent, status |
| files | Transferred file names + hashes (for IOC matching) |
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.
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
DetectionRules are the detections. You will run a mix of community rulesets (managed by suricata-update) and your own local rules for environment-specific threats.
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.
Point Suricata at the merged rule file and your own local rules in suricata.yaml:
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).
| Field | Meaning |
|---|---|
| action | alert (log), drop (IPS block, log), reject (block + RST), pass (whitelist) |
| protocol | ip, tcp, udp, icmp — or app-layer: http, tls, dns, smb, ssh |
| direction | -> one way, <> both directions |
| flow | State/direction, e.g. established,to_server |
| content | Payload/keyword match; pair with nocase, depth, offset |
| sid / rev | Unique 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.
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.
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.
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.
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
EnforcementTo 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.
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.
--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.
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.
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 TeamA 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.
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.
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.
What this finds: severity-1 alerts targeting your own address space — exploitation attempts and confirmed trojan activity that jump the queue.
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.
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
OperationsA sensor is not fire-and-forget. Keep rules fresh, watch for packet loss, and know the failure signatures cold.
Fresh rules matter — ET Open updates daily. Schedule suricata-update then trigger a live reload so no packets are dropped during the refresh.
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.
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.
The problems you will actually hit, and the first thing to check for each.
| Symptom | Likely cause | Fix |
|---|---|---|
| Zero alerts ever | Wrong interface / traffic not mirrored / offloading on | Confirm -i iface, verify SPAN, run ethtool -K |
| Rules not loading | rule-files path wrong or SID collision | suricata -T -v; check suricata.log for parse errors |
| High kernel_drops | Under-sized CPU / small ring buffer | Hyperscan, cpu-affinity, raise ring-size |
| IPS not blocking | Rule is alert, or NFQUEUE not set | Use drop action; confirm iptables NFQUEUE rule |
| eve.json fills disk | Logging every http/flow on busy link | Trim eve-log types; add logrotate |
| Service won't start | YAML indentation / bad interface in defaults | journalctl -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
VerifyBuild 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.
"They can't exploit you if you are the Exploit."