In this module
NF1.5 Suricata Installation and Rule Management
You understand IDS concepts from NF0 — signature matching, alert generation, rule management. If you've deployed Suricata before, the installation will be familiar. This sub covers installation from the OISF PPA, initial configuration, rule management with suricata-update, and your first alert generation against a test PCAP.
Zeek tells you what happened on the network. Suricata tells you when something bad happened. Together, they form a detection and investigation pair — Suricata fires the alert, Zeek provides the context. But Suricata with stale rules is a false sense of security. And Suricata without Zeek is a detection engine with no investigation capability.
This sub installs Suricata, configures it for EVE JSON output (for structured alert data), sets up suricata-update for automated rule management, and validates the installation against a PCAP that contains known malicious traffic.
Deliverable: A working Suricata installation with the ET Open ruleset loaded, EVE JSON output configured, Community ID enabled, and a validated alert against test traffic.
Figure NF1.5 — Suricata setup pipeline. Community ID in the EVE output is the critical configuration — it enables correlation between Suricata alerts and Zeek metadata for the same network flow.
Step 1 — Install Suricata
Add the OISF (Open Information Security Foundation) PPA and install:
sudo add-apt-repository ppa:oisf/suricata-stable -y
sudo apt update
sudo apt install -y suricata suricata-updateVerify the installation:
suricata --build-info | head -5
suricata -VThe version should be 7.0+ (current stable). The build info confirms features like AF_PACKET, Rust, and EVE output are compiled in.
Step 2 — Configure Suricata
Suricata's configuration file is /etc/suricata/suricata.yaml. The file is large (2000+ lines) — you only need to change a few settings for the lab.
Enable Community ID in the EVE output. This is the critical configuration that links Suricata alerts to Zeek logs:
sudo nano /etc/suricata/suricata.yamlFind the community-id section (search for community-id:) and set it to true:
community-id:
enabled: trueFind the eve-log section and verify it's enabled with the alert type included. The default configuration usually has this correct, but verify:
outputs:
- eve-log:
enabled: yes
filename: eve.json
types:
- alert:
payload: yes
payload-printable: yes
http-body: yes
http-body-printable: yesSet the log directory to your sensor's log path:
default-log-dir: /opt/sensor/suricata-logs/Set the HOME_NET variable to match NE's internal ranges (and your lab network):
vars:
address-groups:
HOME_NET: "[10.0.0.0/8,172.16.0.0/12,192.168.0.0/16]"Step 3 — Install and Update Rules
suricata-update manages rule downloads and installation. Run the initial update:
sudo suricata-updateThis downloads the Emerging Threats (ET) Open ruleset — approximately 40,000 rules covering malware, C2, exploit kits, and attack patterns. The rules are installed to /var/lib/suricata/rules/suricata.rules.
Verify rules loaded:
sudo suricata-update list-sources
wc -l /var/lib/suricata/rules/suricata.rulesThe rule count should be 30,000-50,000 active rules.
Step 4 — Test Against a PCAP
Run Suricata against a test PCAP that contains known malicious traffic. The malware-traffic-analysis.net site provides excellent test PCAPs with known C2 traffic that will trigger ET rules:
sudo suricata -r /opt/sensor/pcap/test-capture.pcap \
-l /opt/sensor/suricata-logs/ \
--set classification-file=/etc/suricata/classification.config \
--set reference-config-file=/etc/suricata/reference.configCheck for alerts in the EVE JSON output:
cat /opt/sensor/suricata-logs/eve.json | jq 'select(.event_type=="alert")' | head -30If the PCAP contains malicious traffic, you should see alert entries with fields including alert.signature, alert.category, alert.severity, and community_id.
Verify Community ID is present in alerts:
cat /opt/sensor/suricata-logs/eve.json | jq 'select(.event_type=="alert") | .community_id' | head -5Each alert should show a Community ID hash. Take one of these hashes and search for it in the Zeek conn.log you generated from the same PCAP:
grep "THE_COMMUNITY_ID" /opt/sensor/zeek-logs/test-run/conn.logIf you find a match, the Zeek-Suricata correlation is working. The same network flow appears in both tools, linked by Community ID.
Step 5 — Automate Rule Updates
Create a daily cron job to update rules automatically:
echo "0 4 * * * root suricata-update && systemctl reload suricata" | \
sudo tee /etc/cron.d/suricata-updateThis runs suricata-update at 04:00 daily and reloads Suricata to pick up new rules. For live sensor deployments, the reload is important — new rules only take effect after Suricata reloads its rule file.
For the lab, the cron job ensures your rules stay current when you use the sensor over the course of multiple modules.
The ET Open ruleset has approximately 40,000 rules. Running all 40,000 against high-throughput traffic requires significant CPU. Should you disable rules you don't need to improve performance?
For the lab: no. Run all rules. You want maximum detection coverage because you're learning what the rules detect, and disabled rules produce no learning opportunities.
For production: yes, carefully. Disable rule categories that don't apply to your environment (ET INFO rules if you don't want informational alerts, ET GAMES if you don't care about gaming traffic, ET P2P for peer-to-peer protocols). But never disable a category without understanding what's in it — ET MALWARE and ET TROJAN contain high-value detections you don't want to lose.
Module NF8 covers rule management in depth — writing custom rules, tuning false positives, and building a rule management workflow.
Suricata detects known threats. Zeek records what happened. These are different capabilities. Suricata without Zeek tells you "Cobalt Strike detected" but can't tell you which other hosts are also compromised, how much data was exfiltrated, or what the attack timeline looks like. Zeek without Suricata records everything but doesn't alert you when something known-bad happens.
The pair works like this: Suricata fires the alert (something bad matched). You take the Community ID from the alert and find the same session in Zeek logs. Zeek tells you the session duration, byte counts, DNS resolution, TLS certificate, and other context. Then you query Zeek for the same destination IP across all hosts — finding other compromised systems that Suricata may not have alerted on (because the attacker used a slightly different technique that dodged the signature).
Run both. They serve different functions.
cat /opt/sensor/suricata-logs/eve.json | \
jq -r 'select(.event_type=="alert") | .alert.category' | \
sort | uniq -c | sort -rnTry it: Count alerts by category
Setup. Your Suricata installation with EVE JSON output from a test PCAP analysis.
Task. Count the Suricata alerts by category:
Expected result. A sorted list of alert categories with counts. Common categories: "A Network Trojan was detected," "Potentially Bad Traffic," "Misc activity." The specific categories depend on what traffic was in your PCAP.
Debugging branch. If no alerts appear: try a different PCAP known to contain malicious traffic. If jq errors: verify eve.json is valid JSON with head -1 /opt/sensor/suricata-logs/eve.json | jq .
suricata -V
suricata --build-info | grep -E "AF_PACKET|Rust|EVE"
systemctl status suricata # (live deployment only)sudo suricata-update # Download and install latest rules
sudo suricata-update list-sources # Show available rule sources
wc -l /var/lib/suricata/rules/suricata.rules # Count active rulessudo suricata -r file.pcap -l /opt/sensor/suricata-logs/
cat eve.json | jq 'select(.event_type=="alert")' | head -20
cat eve.json | jq -r 'select(.event_type=="alert") | "\(.timestamp) \(.alert.signature)"'# Get CID from Suricata alert
CID=$(cat eve.json | jq -r 'select(.event_type=="alert") | .community_id' | head -1)
# Find same flow in Zeek
grep "$CID" conn.log# All alerts
cat eve.json | jq 'select(.event_type=="alert")'
# All flow records
cat eve.json | jq 'select(.event_type=="flow")'
# All TLS events
cat eve.json | jq 'select(.event_type=="tls")'# Disable all ET INFO rules (informational noise for most SOCs)
echo 'group:emerging-info.rules' | sudo tee -a /etc/suricata/disable.conf
sudo suricata-updateYou've built the sensor and mapped the evidence landscape.
NF0 established why network evidence matters when every other source is compromised. NF1 built your Zeek + Suricata sensor with the 10 investigation query patterns. From here, every module teaches protocol-specific investigation against real attack scenarios.
- DNS deep dive (NF3) — tunnelling detection, DGA analysis, passive DNS infrastructure mapping, and the INC-NE-2026-0227 AiTM phishing DNS trail
- Protocol analysis (NF4–NF7) — HTTP/HTTPS, SMB lateral movement, SSH tunnelling, and email protocol investigation with Zeek metadata and PCAP
- Detection and hunting (NF8–NF11) — Suricata rule writing, C2 beacon detection with JA3, NetFlow analytics, and proactive network threat hunting
- NSM architecture (NF13) — production sensor deployment at 1–10 Gbps with Arkime, Security Onion, and enterprise storage planning
- INC-NE-2026-0830 capstone (NF14) — multi-stage investigation using only network evidence: phishing → domain-fronted C2 → lateral movement → DNS tunnel exfiltration
Cancel anytime