Install Suricata IDS/IPS on VPS — Intrusion Detection

Install Suricata IDS/IPS on VPS — Intrusion Detection

September 2026 · 10 min read

Suricata is an open-source Intrusion Detection and Prevention System (IDS/IPS) maintained by the OISF (Open Information Security Foundation). It analyzes network traffic in real-time, detecting port scans, exploit attempts, malware C2 traffic, SQL injection over HTTP, and thousands of other threats using Emerging Threats rules. Suricata supports multi-threading (fast even on single-core VPS), operates in both IDS mode (logging only) and IPS mode (blocking via NFQueue), and can natively parse protocols like HTTP, TLS/SSL, DNS, FTP, and SMB without external tools. This guide covers installation through viewing real alerts.

IDS vs IPS — Which Mode to Use?

ModeHow It WorksBest For
IDS (af-packet)Copies traffic via kernel ring buffers — logs only, never blocksProduction VPS where you want visibility first and need to tune rules
IPS (NFQueue)Routes packets through kernel queue — Suricata can drop in real-timeVPS with tuned rules ready for active blocking

Start with IDS mode for 1–2 weeks to identify false positives before enabling IPS.

Install Suricata on Ubuntu/Debian

# Add the OISF PPA (Ubuntu) — gets a newer version than the default repo
sudo add-apt-repository ppa:oisf/suricata-stable -y
sudo apt update
sudo apt install suricata -y

# Verify the version
suricata --build-info | head -5

# Enable and start the service
sudo systemctl enable suricata
sudo systemctl start suricata
sudo systemctl status suricata
Tip: On Debian, use backports instead of the PPA: echo "deb http://deb.debian.org/debian bookworm-backports main" | sudo tee /etc/apt/sources.list.d/backports.list && sudo apt install -t bookworm-backports suricata

Identify Your Network Interface

# List active interfaces
ip a

# Find the interface carrying your traffic (usually eth0 or ens3)
ip route get 8.8.8.8 | grep dev

Note the interface name (e.g., eth0 or ens3) — you'll use it in the configuration below.

Configure suricata.yaml

sudo nano /etc/suricata/suricata.yaml

Find and update these key settings:

# 1. Set HOME_NET to your VPS IP/subnet
vars:
  address-groups:
    HOME_NET: "[YOUR_VPS_IP/32]"
    # Example: "[203.0.113.50/32]"

# 2. Set your interface (find the af-packet section)
af-packet:
  - interface: eth0      # Replace with your interface name
    cluster-id: 99
    cluster-type: cluster_flow
    defrag: yes

# 3. Enable JSON logging (eve-log)
outputs:
  - eve-log:
      enabled: yes
      filetype: regular
      filename: eve.json
      types:
        - alert:
            payload: yes
            payload-printable: yes
            http-body: yes
        - http:
            extended: yes
        - dns:
            query: yes
            answer: yes
        - tls:
            extended: yes

Update Rules with suricata-update

# Download Emerging Threats Open rules (free, no subscription needed)
sudo suricata-update

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

# Enable ET Pro if you have a subscription
# sudo suricata-update enable-source et/pro --secret-code YOUR_CODE

# Reload rules into the running Suricata process
sudo suricata-update
sudo suricatasc -c reload-rules
Tip: Schedule daily rule updates with cron: echo "0 3 * * * root suricata-update && suricatasc -c reload-rules" | sudo tee /etc/cron.d/suricata-update

Run Suricata in IDS Mode

# Test the configuration before starting
sudo suricata -T -c /etc/suricata/suricata.yaml -v

# Start via systemd (IDS mode — af-packet)
sudo systemctl restart suricata

# Or run manually for debugging
sudo suricata -c /etc/suricata/suricata.yaml -i eth0

# Check stats
sudo suricatasc -c dump-counters | grep -E "decoder|detect|alert"

Switch to IPS Mode with NFQueue

# Install NFQueue kernel support
sudo apt install libnetfilter-queue-dev -y

# Route all traffic through NFQueue queue 0
sudo iptables -I INPUT -j NFQUEUE --queue-num 0 --queue-bypass
sudo iptables -I OUTPUT -j NFQUEUE --queue-num 0 --queue-bypass
sudo iptables -I FORWARD -j NFQUEUE --queue-num 0 --queue-bypass

# Edit suricata.yaml to use NFQueue instead of af-packet:
# nfq:
#   mode: accept
#   fail-open: yes

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

# Persist iptables rules across reboots
sudo apt install iptables-persistent -y
sudo netfilter-persistent save
Tip: Always use --queue-bypass with NFQueue iptables rules. If Suricata crashes, traffic continues to flow — your VPS won't disconnect.

View Alerts and Logs

# Stream alerts in real-time
sudo tail -f /var/log/suricata/eve.json | python3 -c "
import sys, json
for line in sys.stdin:
    try:
        e = json.loads(line)
        if e.get('event_type') == 'alert':
            print(f\"{e['timestamp']} [{e['alert']['severity']}] {e['alert']['signature']} {e.get('src_ip','')} -> {e.get('dest_ip','')}\")
    except: pass
"

# Read the human-readable fast.log
sudo tail -f /var/log/suricata/fast.log

# Count and rank top alerts today
sudo jq -r 'select(.event_type=="alert") | .alert.signature' /var/log/suricata/eve.json | sort | uniq -c | sort -rn | head -20

Write Custom Detection Rules

# Create a local rules file
sudo nano /etc/suricata/rules/local.rules

# Alert on SSH brute-force attempts from external hosts
alert tcp any any -> $HOME_NET 22 (msg:"SSH Brute Force Attempt"; flags:S; threshold: type both, track by_src, count 5, seconds 60; classtype:attempted-admin; sid:9000001; rev:1;)

# Detect SQL injection patterns in HTTP URIs
alert http any any -> $HOME_NET any (msg:"SQL Injection Attempt"; content:"union select"; nocase; http.uri; classtype:web-application-attack; sid:9000002; rev:1;)

# Add the custom rule file to suricata.yaml under rule-files:
# rule-files:
#   - /etc/suricata/rules/local.rules

# Reload rules
sudo suricatasc -c reload-rules

Verify Suricata Is Working Correctly

# 1. Check daemon stats
sudo suricatasc -c dump-counters | grep -E "uptime|alert|decoder"

# 2. Trigger a test alert using a known User-Agent string
curl -sA "BlackSun" http://localhost/ 2>/dev/null
sudo grep "User-Agent" /var/log/suricata/fast.log | tail -5

# 3. Confirm eve.json contains event data
sudo jq '.event_type' /var/log/suricata/eve.json | sort | uniq -c

# 4. View interface capture statistics
sudo suricatasc -c iface-stat eth0

# 5. Confirm the process is running
ps aux | grep suricata
sudo systemctl status suricata --no-pager
Tip: If eve.json is empty, verify Suricata is listening on the correct interface with sudo suricatasc -c iface-list.

Troubleshooting Common Issues

Error: "PCAP packet drop" or unexpectedly low alert counts

Suricata can't keep up with traffic at high throughput. Increase worker threads in suricata.yaml:

# Under threading: in suricata.yaml
threading:
  set-cpu-affinity: no
  detect-thread-ratio: 1.5

# For af-packet, increase threads per interface
af-packet:
  - interface: eth0
    threads: 2
    cluster-id: 99
    cluster-type: cluster_flow

Error: "suricata.service: Start request repeated too quickly"

Suricata is crashing due to a configuration error. Check the logs before restarting:

# View recent error output
sudo journalctl -u suricata -n 50 --no-pager

# Validate config syntax
sudo suricata -T -c /etc/suricata/suricata.yaml -v 2>&1 | grep -E "Error|Warning"

# If you see "Failed to open" — check that rule files exist
ls -la /var/lib/suricata/rules/
sudo suricata-update  # Re-download rules

Error: "NFQ queue 0: recv failed" in IPS mode

The NFQueue iptables rule isn't in place, or the required kernel modules aren't loaded:

# Confirm the iptables NFQUEUE rule exists
sudo iptables -L -n | grep NFQUEUE

# Load kernel modules
sudo modprobe nfnetlink_queue
sudo modprobe nf_conntrack

# Run Suricata as root in IPS mode
sudo suricata -c /etc/suricata/suricata.yaml -q 0 --user root

# Enable fail-open to prevent lockout on crash
# In suricata.yaml:
# nfq:
#   fail-open: yes

Too many false positives flooding your logs

Suppress specific rules without removing the entire rule set using a threshold config:

# Create or edit the threshold file
sudo nano /etc/suricata/threshold.conf

# Suppress a specific rule by SID
suppress gen_id 1, sig_id 2010935
suppress gen_id 1, sig_id 2010935, track by_src, ip 192.168.1.0/24

# Reload
sudo suricatasc -c reload-rules

# Or disable an entire category via disable.conf
sudo nano /etc/suricata/disable.conf
# Add: re:emerging-scan

Suricata consuming too much RAM on a small VPS

Reduce memory caps for flow tracking and defragmentation:

# In suricata.yaml
flow:
  memcap: 64mb       # Reduced from default 128mb
  hash-size: 65536
  prealloc: 10000

stream:
  memcap: 64mb

defrag:
  memcap: 32mb

# Apply changes
sudo systemctl restart suricata

Frequently Asked Questions

How resource-intensive is Suricata on a budget VPS?

In IDS mode (af-packet), Suricata typically uses 5–15% CPU on a 1–2 vCore VPS and 200–400 MB RAM depending on traffic volume and the number of enabled rules. On a 1 GB RAM VPS, enable only the rule groups relevant to your workload — for example, emerging-web-server and emerging-exploit — and disable unrelated sets with suricata-update disable-source to keep memory usage low.

How does Suricata compare to CrowdSec, and can they work together?

Suricata operates at the network level, inspecting raw packet payloads and protocol fields — ideal for catching exploits and malware C2 traffic that log-based systems miss. CrowdSec is a log-based behavioral analyzer using crowdsourced threat intelligence to block suspicious IPs. They complement each other well: Suricata detects network-level threats and writes to eve.json, while CrowdSec reads Suricata's fast.log and automatically blocks offending IPs.

Can a misconfigured Suricata lock me out of my VPS?

Yes — in NFQueue IPS mode, a misconfigured drop rule or a Suricata crash without --queue-bypass can cut off all traffic. Protect yourself: (1) always add --queue-bypass to your iptables NFQueue rules, (2) set fail-open: yes in suricata.yaml, and (3) always start in IDS mode and test for 1–2 weeks to confirm there are no false positives against your normal traffic before switching to IPS mode.