Skip to content
SumGuy's Ramblings
Go back

Suricata vs Snort: Intrusion Detection for the Paranoid Home Lab Owner

Something Is Probably Happening on Your Network Right Now

You’ve got a firewall. You’re running UFW or OPNsense with strict rules. But a firewall only controls what traffic can enter and exit — it has no opinion about what that traffic contains. A connection to port 443 is allowed. The firewall doesn’t care if that connection is someone trying SQL injection, scanning for vulnerabilities, or your kid’s laptop running a cryptominer.

An IDS (Intrusion Detection System) watches actual traffic content, matches it against signatures of known attacks, and alerts you. An IPS (Intrusion Prevention System) goes further — it blocks the traffic in real time.

Snort and Suricata are the two main open-source options. You’ve probably heard of Snort. You should probably be using Suricata.

What IDS/IPS Actually Does

An IDS/IPS sits in the traffic path (or listens on a mirrored port) and:

  1. Reassembles network streams into protocol-aware views
  2. Matches traffic against a rule set of known attack signatures
  3. Alerts (IDS) or drops (IPS) matching traffic
  4. Logs detailed information about what it found

Rules look like this:

alert http any any -> $HOME_NET any (msg:"ET SCAN Nmap User-Agent"; 
    content:"Nmap Scripting Engine"; http_user_agent; 
    classtype:web-application-attack; sid:2000537;)

That rule says: if we see an HTTP request with “Nmap Scripting Engine” in the User-Agent header going to our network, fire an alert. Simple in concept, powerful at scale with thousands of such rules covering every known attack pattern.

Snort: The Pioneer

Snort has been around since 1998. It essentially invented the modern IDS. The rule format is the industry standard — “Snort rules” is a synonym for IDS signatures in many contexts.

Snort 3 (the current version) is a significant rewrite with better performance than Snort 2, but it has a long history of being single-threaded and not scaling well on high-bandwidth networks.

Pros:

Cons:

Suricata: The Modern Choice

Suricata was built by the OISF (Open Information Security Foundation) starting in 2009, specifically designed to be multi-threaded from the ground up.

Pros:

Cons:

For a home lab on modern hardware (even a Pi 4 or a modest VM), use Suricata. The multi-threading alone is worth it, and the EVE JSON logging makes it actually useful for analysis rather than just generating alerts you ignore.

Installing Suricata

# Debian/Ubuntu — use the official OISF PPA for latest version
sudo add-apt-repository ppa:oisf/suricata-stable
sudo apt update
sudo apt install suricata

# Verify
suricata --version

# RHEL/Fedora
sudo dnf install suricata

Getting Rules

# Install suricata-update for rule management
sudo apt install python3-suricata-update  # or pip3 install suricata-update

# Download the free Emerging Threats Open ruleset
sudo suricata-update

# List available rule sources
sudo suricata-update list-sources

# Enable additional free sources
sudo suricata-update enable-source et/open
sudo suricata-update enable-source oisf/trafficid
sudo suricata-update enable-source ptresearch/attackdetection

# Update all enabled sources
sudo suricata-update

Rules are saved to /var/lib/suricata/rules/suricata.rules by default.

suricata.yaml: The Essential Config

The default config is enormous (2000+ lines). Here’s what you actually need to change:

sudo nano /etc/suricata/suricata.yaml
# Your home network definition — CRITICAL, get this right
vars:
  address-groups:
    HOME_NET: "[192.168.0.0/16,10.0.0.0/8,172.16.0.0/12]"
    EXTERNAL_NET: "!$HOME_NET"
    HTTP_SERVERS: "$HOME_NET"
    DNS_SERVERS: "$HOME_NET"
  
  port-groups:
    HTTP_PORTS: "80"
    HTTPS_PORTS: "443"

# Network interface to listen on
af-packet:
  - interface: eth0
    cluster-id: 99
    cluster-type: cluster_flow
    defrag: yes
    threads: auto  # Uses all CPU cores

# EVE JSON logging — your main output
outputs:
  - eve-log:
      enabled: yes
      filetype: regular
      filename: /var/log/suricata/eve.json
      types:
        - alert:
            metadata: yes
            http: yes
            tls: yes
        - http:
            extended: yes
        - dns:
            query: yes
            answer: yes
        - tls:
            extended: yes
        - stats:
            totals: yes

# Rules location
default-rule-path: /var/lib/suricata/rules
rule-files:
  - suricata.rules
# Test the configuration
sudo suricata -T -c /etc/suricata/suricata.yaml

# Start in IDS mode (AFPACKET - listening, not blocking)
sudo systemctl enable --now suricata

# Check it's running
sudo systemctl status suricata
sudo tail -f /var/log/suricata/eve.json | python3 -m json.tool

Running in IDS Mode vs IPS Mode

IDS mode (AF_PACKET): Suricata listens on a copy of traffic. It can alert but not block. Safe for initial deployment — you see what would have been blocked without actually affecting traffic.

# IDS mode — specify interface
sudo suricata -c /etc/suricata/suricata.yaml -i eth0

IPS mode (NFQueue): Traffic is redirected through Suricata via Linux netfilter. Suricata can drop packets. Affects real traffic — be careful.

# Set up NFQueue
sudo iptables -I FORWARD -j NFQUEUE --queue-num 0
sudo iptables -I INPUT -j NFQUEUE --queue-num 0
sudo iptables -I OUTPUT -j NFQUEUE --queue-num 0

# Run in IPS mode
sudo suricata -c /etc/suricata/suricata.yaml -q 0

For a home lab, start with IDS mode. Run it for a week, review the alerts, tune the rules, then consider IPS mode if you want actual blocking.

Reading EVE JSON Logs

EVE JSON is Suricata’s superpower — every alert, HTTP request, DNS query, and TLS connection logged as structured JSON.

# Watch alerts in real time
sudo tail -f /var/log/suricata/eve.json | jq 'select(.event_type=="alert")'

# See what's being hit
sudo jq 'select(.event_type=="alert") | {src: .src_ip, dest: .dest_ip, sig: .alert.signature}' \
    /var/log/suricata/eve.json

# DNS queries (great for finding malware C2 traffic)
sudo jq 'select(.event_type=="dns" and .dns.type=="query") | {src: .src_ip, query: .dns.rrname}' \
    /var/log/suricata/eve.json | head -50

# Top talkers
sudo jq -r 'select(.event_type=="alert") | .src_ip' /var/log/suricata/eve.json \
    | sort | uniq -c | sort -rn | head -20

Integration with Elastic/Splunk

EVE JSON was designed for ingestion into SIEM platforms:

# Filebeat config to ship to Elasticsearch
filebeat.inputs:
  - type: log
    enabled: true
    paths:
      - /var/log/suricata/eve.json
    json.keys_under_root: true
    json.add_error_key: true

output.elasticsearch:
  hosts: ["localhost:9200"]
  index: "suricata-%{+yyyy.MM.dd}"

The official Suricata Kibana dashboards give you visual traffic analysis, alert timelines, and top-threats views in minutes once the data is flowing.

OPNsense and pfSense Integration

Both OPNsense and pfSense have Suricata (and Snort) available as packages:

OPNsense: Services → Intrusion Detection

This is the easiest path for home labs — no separate box needed. The IDS/IPS runs directly on your gateway.

For dedicated IDS on a separate machine, a Pi 4 with Suricata watching a mirrored port from a managed switch works well and keeps load off your router.

Tuning to Reduce False Positives

The biggest mistake: enabling every rule and drowning in alerts. Start with less and tune up:

# Disable noisy rules by SID
sudo suricata-update add-command --suppress-rule 2101411  # Suppress specific SID

# Or create a threshold file
cat > /etc/suricata/threshold.conf << 'EOF'
# Suppress alerts from your own scanners/tools
suppress gen_id 1, sig_id 2001219, track by_src, ip 192.168.1.100

# Threshold — only alert once per minute for this rule
threshold gen_id 1, sig_id 2002992, type both, track by_src, count 5, seconds 60
EOF

Run IDS for a week, collect your baselines, suppress the legitimate traffic patterns, then the remaining alerts are actually interesting.

The paranoia is warranted. The signal is there. You just need to turn down the noise first.


Share this post on:

Previous Post
BGP in Your Home Lab: Dynamic Routing for People Who've Run Out of Static Routes
Next Post
Systemd Timers vs Cron: Scheduling Tasks Like It's Not 1995