Skip to main content
COSMICBYTEZLABS
NewsSecurityHOWTOsToolsStudyTraining
ProjectsChecklistsAI RankingsNewsletterStatusTagsAbout
Subscribe

Press Enter to search or Esc to close

News
Security
HOWTOs
Tools
Study
Training
Projects
Checklists
AI Rankings
Newsletter
Status
Tags
About
RSS Feed
Reading List
Subscribe

Stay in the Loop

Get the latest security alerts, tutorials, and tech insights delivered to your inbox.

Subscribe NowFree forever. No spam.
COSMICBYTEZLABS

Your trusted source for IT intelligence, cybersecurity insights, and hands-on technical guides.

999+ Articles
124+ Guides

CONTENT

  • Latest News
  • Security Alerts
  • HOWTOs
  • Projects
  • Exam Prep

RESOURCES

  • Search
  • Browse Tags
  • Newsletter Archive
  • Reading List
  • RSS Feed

COMPANY

  • About Us
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CosmicBytez Labs. All rights reserved.

System Status: Operational
  1. Home
  2. HOWTOs
  3. Suricata IDS/IPS Deployment: From Install to Active Threat Detection
Suricata IDS/IPS Deployment: From Install to Active Threat Detection
HOWTOIntermediate

Suricata IDS/IPS Deployment: From Install to Active Threat Detection

Deploy Suricata as a full-featured Network Intrusion Detection and Prevention System on Ubuntu. Covers installation, interface capture, Emerging Threats...

Dylan H.

Tutorials

March 30, 2026
10 min read

Prerequisites

  • Ubuntu 22.04 LTS or 24.04 LTS (server or VM)
  • Root or sudo access
  • At least one monitored network interface (physical or virtual)
  • Basic familiarity with Linux networking and systemd
  • Optional: a SIEM (Wazuh, Splunk, Elastic) for log forwarding

Introduction

Suricata is a high-performance, open-source Network Intrusion Detection System (NIDS) and Intrusion Prevention System (NIPS) maintained by the Open Information Security Foundation (OISF). Unlike older tools such as Snort, Suricata is multi-threaded from the ground up, supports hardware-accelerated packet capture via AF_PACKET and DPDK, and ships with a built-in Lua scripting engine for custom detection logic.

In this guide you will:

  • Install Suricata from the OISF PPA on Ubuntu
  • Configure it to capture traffic on a live interface in IDS (passive) mode
  • Download and enable the Emerging Threats Open rule set
  • Switch to inline IPS mode using nftables NFQUEUE
  • Validate detection with a safe test payload
  • Integrate JSON alert logs with a SIEM

By the end, your host will be alerting—and optionally blocking—malicious traffic in real time.


Prerequisites

Before starting, confirm the following:

# Ubuntu version
lsb_release -a
 
# Available interfaces (pick the one that sees production traffic)
ip link show
 
# Kernel version (AF_PACKET requires >= 3.6, NFQUEUE requires >= 2.6.14)
uname -r
 
# Sufficient disk space for logs (recommend ≥ 20 GB)
df -h /var/log

You will also need internet access to pull packages and rule updates during setup.


Step 1 — Install Suricata from the OISF PPA

The Ubuntu default repos often ship an outdated Suricata version. Use the official OISF PPA to get the latest stable release.

# Add OISF stable PPA
sudo add-apt-repository ppa:oisf/suricata-stable -y
sudo apt update
 
# Install Suricata
sudo apt install suricata suricata-update -y
 
# Verify version (should be 7.x or later)
suricata --build-info | head -5

Enable and start the service (it will be reconfigured before it captures anything useful):

sudo systemctl enable suricata
sudo systemctl stop suricata   # stop until fully configured

Step 2 — Update and Enable Rule Sets

Suricata ships with suricata-update, a rule management tool that fetches, merges, and installs rule sets automatically.

2a — Fetch available sources

# List all available rule sources (community + commercial)
sudo suricata-update list-sources

2b — Enable Emerging Threats Open (free, no registration)

# Enable the ET/Open rule set
sudo suricata-update enable-source et/open
 
# Download and install all enabled sources
sudo suricata-update

Rules are written to /var/lib/suricata/rules/suricata.rules. You should see thousands of rules:

wc -l /var/lib/suricata/rules/suricata.rules
# Example: 47382 /var/lib/suricata/rules/suricata.rules

2c — Schedule daily rule updates via cron

echo "0 3 * * * root /usr/bin/suricata-update && systemctl reload suricata" \
  | sudo tee /etc/cron.d/suricata-update

Step 3 — Configure Suricata

The main config lives at /etc/suricata/suricata.yaml. Back it up, then make targeted edits.

sudo cp /etc/suricata/suricata.yaml /etc/suricata/suricata.yaml.bak
sudo nano /etc/suricata/suricata.yaml

3a — Define your HOME_NET

Find and set HOME_NET to your local subnet(s). This controls which side of traffic is treated as "internal":

vars:
  address-groups:
    HOME_NET: "[192.168.0.0/16,10.0.0.0/8,172.16.0.0/12]"
    EXTERNAL_NET: "!$HOME_NET"

3b — Set the capture interface

Find the af-packet section and set your interface. Replace eth0 with your actual interface name:

af-packet:
  - interface: eth0
    cluster-id: 99
    cluster-type: cluster_flow
    defrag: yes
    use-mmap: yes
    tpacket-v3: yes

3c — Enable EVE JSON logging

EVE JSON is the preferred structured log format for SIEM integration. Ensure it is enabled:

outputs:
  - eve-log:
      enabled: yes
      filetype: regular
      filename: /var/log/suricata/eve.json
      types:
        - alert:
            payload: yes
            payload-printable: yes
            packet: yes
            metadata: yes
        - http:
            extended: yes
        - dns:
        - tls:
            extended: yes
        - files:
            force-magic: no
        - ssh
        - flow

3d — Point Suricata at the merged rule file

default-rule-path: /var/lib/suricata/rules
 
rule-files:
  - suricata.rules

3e — Validate the config

sudo suricata -T -c /etc/suricata/suricata.yaml -v
# Should end with: Configuration provided was successfully loaded. Exiting.

Step 4 — Run Suricata in IDS (Passive) Mode

Start Suricata against your interface in IDS mode. This does not block traffic—it only alerts.

# Start in IDS mode on eth0
sudo suricata -c /etc/suricata/suricata.yaml -i eth0 --daemon
 
# Or via systemd after editing the service drop-in
sudo systemctl edit suricata --force

Add the following to the systemd override file:

[Service]
ExecStart=
ExecStart=/usr/bin/suricata -c /etc/suricata/suricata.yaml -i eth0 --pidfile /run/suricata.pid

Then reload and start:

sudo systemctl daemon-reload
sudo systemctl start suricata
sudo systemctl status suricata

Watch live alerts:

sudo tail -f /var/log/suricata/eve.json | jq 'select(.event_type=="alert")'

Step 5 — Switch to Inline IPS Mode via NFQUEUE

IPS mode allows Suricata to actively drop malicious packets. This uses the Linux NFQUEUE target to intercept packets before they are forwarded.

5a — Install nftables (if not present)

sudo apt install nftables -y
sudo systemctl enable --now nftables

5b — Create NFQUEUE rules

Route traffic through Suricata's NFQUEUE. The queue number must match the Suricata config:

sudo nft add table inet filter
sudo nft add chain inet filter forward '{ type filter hook forward priority 0; policy accept; }'
sudo nft add rule inet filter forward queue num 0

For a host-based deployment (protecting the host itself, not forwarding traffic):

sudo nft add chain inet filter input '{ type filter hook input priority 0; policy accept; }'
sudo nft add chain inet filter output '{ type filter hook output priority 0; policy accept; }'
sudo nft add rule inet filter input queue num 0
sudo nft add rule inet filter output queue num 0

Save the ruleset so it survives reboots:

sudo nft list ruleset | sudo tee /etc/nftables.conf

5c — Update Suricata config for IPS mode

In /etc/suricata/suricata.yaml, replace the af-packet section with:

nfq:
  mode: repeat
  repeat-mark: 1
  repeat-mask: 1
  route-queue: 2
  batchcount: 20
  fail-open: yes

5d — Restart with NFQUEUE mode

Update the systemd override to use -q 0 instead of -i eth0:

[Service]
ExecStart=
ExecStart=/usr/bin/suricata -c /etc/suricata/suricata.yaml -q 0 --pidfile /run/suricata.pid
sudo systemctl daemon-reload
sudo systemctl restart suricata

Note: fail-open: yes ensures that if Suricata crashes or is overloaded, packets are passed rather than dropped. For high-security environments, set this to no.


Step 6 — Write a Custom Detection Rule

Suricata rules follow the Snort-compatible syntax. Add custom rules to a local file that persists across suricata-update runs.

Create /etc/suricata/rules/local.rules:

sudo mkdir -p /etc/suricata/rules
sudo nano /etc/suricata/rules/local.rules

Example rules:

# Alert on any HTTP request to a known bad domain
alert http any any -> any any (msg:"POLICY Suspicious domain access"; \
  http.host; content:"malicious-example.com"; nocase; \
  classtype:policy-violation; sid:9000001; rev:1;)
 
# Alert on SSH brute force (>5 connections in 60 seconds from same src)
alert tcp any any -> $HOME_NET 22 (msg:"SCAN SSH Brute Force Attempt"; \
  flags:S; threshold: type both, track by_src, count 5, seconds 60; \
  classtype:attempted-admin; sid:9000002; rev:1;)
 
# Drop outbound DNS queries to port 53 going to non-standard resolvers (IPS mode)
drop dns $HOME_NET any -> ![$DNS_SERVERS] 53 (msg:"POLICY DNS to unauthorized resolver"; \
  classtype:policy-violation; sid:9000003; rev:1;)

Add the local rules file to suricata.yaml:

rule-files:
  - suricata.rules
  - /etc/suricata/rules/local.rules

Reload rules without restarting:

sudo kill -USR2 $(cat /run/suricata.pid)
# Or: sudo systemctl reload suricata

Step 7 — Verification and Testing

7a — Test with the EICAR string over HTTP

The EICAR test string is a safe, universally recognized anti-malware test payload. Fetch it via HTTP (not HTTPS, since TLS decryption isn't configured yet):

# From a monitored host (not the Suricata host itself in IDS mode)
curl -o /dev/null http://testmyids.com
 
# Watch for the alert
sudo tail -f /var/log/suricara/eve.json | jq 'select(.event_type=="alert") | {sig: .alert.signature, src: .src_ip, dest: .dest_ip}'

7b — Check Suricata statistics

# View the stats log
sudo tail -50 /var/log/suricata/stats.log
 
# Or via EVE
sudo tail -f /var/log/suricata/eve.json | jq 'select(.event_type=="stats") | .stats.decoder'

7c — Verify rule count loaded

sudo suricatasc -c "ruleset-reload-nonblocking" /var/run/suricata/suricata-command.socket
sudo suricatasc -c "dump-counters" /var/run/suricata/suricata-command.socket | jq '.message.detect'

7d — Check interface capture stats

sudo suricatasc -c "iface-list" /var/run/suricata/suricata-command.socket
sudo suricatasc -c "iface-stat eth0" /var/run/suricata/suricata-command.socket

A healthy deployment will show captured packets increasing and zero or near-zero drops.


Step 8 — SIEM Integration (EVE JSON Forwarding)

Option A — Filebeat to Elasticsearch/Wazuh

Install Filebeat and configure it to ship Suricata's EVE JSON log:

# /etc/filebeat/modules.d/suricata.yml
- module: suricata
  eve:
    enabled: true
    var.paths: ["/var/log/suricata/eve.json"]
sudo filebeat modules enable suricata
sudo filebeat setup
sudo systemctl restart filebeat

Option B — Wazuh Agent (ossec.conf)

Add a local file entry to the Wazuh agent config at /var/ossec/etc/ossec.conf:

<localfile>
  <log_format>json</log_format>
  <location>/var/log/suricata/eve.json</location>
</localfile>
sudo systemctl restart wazuh-agent

Wazuh ships built-in decoders and rules for Suricata EVE JSON under ruleset ID 86xxx.


Troubleshooting

Suricata starts but no alerts appear

  • Check interface: Run tcpdump -i eth0 -c 10 to confirm traffic is present on the interface.
  • Check HOME_NET: If HOME_NET doesn't include your subnet, many rules won't fire.
  • Rule action: Ensure rules use alert (not drop) in IDS mode.
  • TLS traffic: Suricata cannot inspect encrypted HTTPS without TLS decryption or mirrored traffic. Look for DNS/HTTP alerts first.

High packet drop rate in stats.log

# Increase the AF_PACKET ring buffer size in suricata.yaml
af-packet:
  - interface: eth0
    buffer-size: 67108864   # 64 MB
    ring-size: 2048
    threads: auto

Also increase worker threads to match CPU cores:

threading:
  set-cpu-affinity: yes
  cpu-affinity:
    - management-cpu-set:
        cpu: [ 0 ]
    - worker-cpu-set:
        cpu: [ "1-7" ]
        mode: "exclusive"

NFQUEUE mode: traffic stops flowing

  • Confirm Suricata is running and connected to the queue: sudo ss -lnp | grep suricata
  • Temporarily flush nftables rules to restore connectivity: sudo nft flush ruleset
  • Set fail-open: yes in the nfq config block to prevent drops on Suricata failure

Rules fail to load after suricata-update

# Check for syntax errors in custom rules
sudo suricata -T -c /etc/suricata/suricata.yaml 2>&1 | grep -i error
 
# Verify the rules path exists
ls -la /var/lib/suricata/rules/suricata.rules
ls -la /etc/suricata/rules/local.rules

Suricata consuming excessive CPU

  • Reduce the number of monitored flow types in eve-log (disable flow and files logging)
  • Enable hardware timestamping if supported by your NIC
  • Use stream.memcap to limit TCP reassembly memory:
stream:
  memcap: 1gb
  checksum-validation: yes

Summary

You now have a functional Suricata deployment covering:

ComponentConfiguration
Rule managementsuricata-update + ET/Open, daily cron refresh
Capture modeAF_PACKET (IDS) or NFQUEUE via nftables (IPS)
Custom rules/etc/suricata/rules/local.rules (persists updates)
Structured loggingEVE JSON at /var/log/suricata/eve.json
SIEM integrationFilebeat module or Wazuh agent localfile
Reload without restartkill -USR2 $(cat /run/suricata.pid)

Next steps to harden your deployment:

  • Enable TLS logging with JA3/JA3S fingerprinting for encrypted traffic visibility
  • Add the et/pro or abuse.ch SSL blacklist sources via suricata-update
  • Build a Grafana dashboard from EVE JSON metrics using Loki or Elasticsearch
  • Tune rule thresholds in /etc/suricata/threshold.config to reduce alert fatigue
  • Explore lua scripting for behavioral detection rules that signature-based approaches miss

Suricata's combination of high throughput, protocol-aware parsing, and rich output formats makes it one of the most capable open-source network security sensors available. With ET/Open rules providing daily-updated threat intelligence and NFQUEUE enabling active blocking, this stack gives you enterprise-grade network visibility at zero license cost.

#suricata#IDS#ips#network-security#intrusion-detection#Linux#SIEM#threat-detection

Related Articles

Network Traffic Analysis with Zeek: From Deployment to Threat Detection

Deploy Zeek (formerly Bro) on Linux to passively monitor network traffic, generate structured logs, write detection scripts, and forward data to your SIEM...

6 min read

CrowdSec: Deploy a Community-Powered Intrusion Prevention System

Install and configure CrowdSec on Linux to detect and block attacks using crowdsourced threat intelligence, custom scenarios, and iptables/nftables bouncers.

6 min read

How to Deploy Wazuh SIEM/XDR for Unified Security Monitoring

Step-by-step guide to deploying Wazuh as an open-source SIEM and XDR platform. Covers server installation, agent deployment across Windows and Linux,...

13 min read
Back to all HOWTOs