Suricata is a high-performance, open-source network threat detection engine that can operate as an Intrusion Detection System (IDS) to alert on suspicious traffic, or as an Intrusion Prevention System (IPS) to actively block it. On RHEL 8, Suricata integrates naturally with firewalld‘s NFQUEUE target for inline packet inspection, and its Lua scripting and Eve JSON logging make it suitable for production security operations centers. In this tutorial you will install Suricata from EPEL 8, configure your network variables and interface settings, update community rule sets, run Suricata in IDS mode, and understand the pathway to IPS mode.

Prerequisites

  • RHEL 8 server with a non-root sudo user
  • EPEL 8 repository enabled
  • At least 2 GB RAM (4 GB recommended for busy networks)
  • Network interface name (obtain with ip -o link show)
  • firewalld running; nftables or iptables for IPS NFQUEUE mode

Step 1 — Install Suricata from EPEL 8

Enable EPEL if not already active, then install Suricata and the suricata-update rule management tool.

dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
dnf install -y suricata
suricata --build-info | head -5

The output confirms the compiled-in features including AF_PACKET, NFQUEUE, and Lua support. The main configuration file lands at /etc/suricata/suricata.yaml and rules are stored under /var/lib/suricata/rules/.

Step 2 — Configure suricata.yaml

Edit the core configuration to define your protected network range, the listening interface, and enable Community ID hashing (which correlates Suricata events with other tools like Zeek).

# Open the configuration file
vi /etc/suricata/suricata.yaml

Find and update the following sections:

# --- HOME_NET: set to your server/network IP range ---
vars:
  address-groups:
    HOME_NET: "[192.168.1.0/24,10.0.0.0/8]"
    EXTERNAL_NET: "!$HOME_NET"

# --- AF-PACKET interface (IDS mode) ---
af-packet:
  - interface: eth0
    cluster-id: 99
    cluster-type: cluster_flow
    defrag: yes

# --- Enable Community ID for cross-tool correlation ---
outputs:
  - eve-log:
      enabled: yes
      filetype: regular
      filename: /var/log/suricata/eve.json
      community-id: true
      types:
        - alert
        - http
        - dns
        - tls
        - flow

Replace eth0 with your actual interface and adjust HOME_NET to match your environment. Save and close the file.

Step 3 — Update Rules with suricata-update

Suricata ships with no rules active by default. Use suricata-update to fetch and compile the latest Emerging Threats Open ruleset and any other sources you enable.

# List available rule sources
suricata-update list-sources

# Enable a free community source (ET Open is enabled by default)
suricata-update enable-source et/open

# Download and compile all enabled rule sources
suricata-update

# Verify rules were written
ls -lh /var/lib/suricata/rules/suricata.rules
wc -l /var/lib/suricata/rules/suricata.rules

Add suricata-update to a daily cron job or systemd timer to keep rules current:

echo "0 2 * * * root /usr/bin/suricata-update && /usr/bin/systemctl reload suricata" 
  > /etc/cron.d/suricata-update

Step 4 — Start Suricata in IDS Mode

Enable and start the Suricata service. The default systemd unit runs Suricata in AF_PACKET IDS mode, capturing a copy of packets without dropping them.

systemctl enable --now suricata
systemctl status suricata

# Confirm Suricata loaded rules and started without errors
journalctl -u suricata -n 30

# Watch live alerts
tail -f /var/log/suricata/fast.log

Generate a test alert using the EICAR-style Suricata test rule:

curl -A "BlackSun" http://testmynids.org/uid/index.html 2>/dev/null
grep "GPL ATTACK_RESPONSE" /var/log/suricata/fast.log | tail -5

Step 5 — Reading fast.log and eve.json

Suricata writes concise one-line alerts to fast.log and rich structured JSON to eve.json. Use jq to query the JSON log effectively.

dnf install -y jq

# Show last 5 alerts with signature, source, and destination
jq 'select(.event_type=="alert") | {timestamp, src_ip, dest_ip, alert: .alert.signature}' 
  /var/log/suricata/eve.json | tail -40

# Count alerts by signature category
jq -r 'select(.event_type=="alert") | .alert.category' 
  /var/log/suricata/eve.json | sort | uniq -c | sort -rn | head -10

Step 6 — Enabling IPS Mode with NFQUEUE

In IPS mode Suricata intercepts live packets via Netfilter’s NFQUEUE and can drop them based on rule actions. This requires a firewalld rule to redirect traffic into the queue before enabling the NFQUEUE input mode in Suricata.

# Add NFQUEUE rules via firewalld direct rules (queue 0 for all traffic)
firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 0 -j NFQUEUE --queue-num 0
firewall-cmd --permanent --direct --add-rule ipv4 filter OUTPUT 0 -j NFQUEUE --queue-num 0
firewall-cmd --reload

# Edit /etc/suricata/suricata.yaml — comment out af-packet section and add:
# nfq:
#   mode: accept
#   fail-open: yes

# Restart Suricata in NFQUEUE mode
systemctl restart suricata
systemctl status suricata

Warning: IPS mode will drop packets matching drop-action rules. Test thoroughly in IDS mode first, tune rules to eliminate false positives, then switch to IPS only on a non-production interface initially.

Conclusion

You have installed Suricata from EPEL 8, configured HOME_NET and AF_PACKET capture on your chosen interface, populated the ruleset with suricata-update, started the IDS service, and explored alert output via both fast.log and structured Eve JSON. You also have the foundation to move to inline IPS mode using firewalld NFQUEUE rules when you are ready.

Next steps: How to Integrate Suricata with the ELK Stack on RHEL 8, How to Configure fail2ban with Suricata Alerts on RHEL 8, and How to Set Up Port Knocking for SSH on RHEL 8.