Suricata is a high-performance, open-source network intrusion detection and prevention system (IDS/IPS) that inspects traffic in real time against a rule set to identify threats, policy violations, and malicious activity. On RHEL 9, Suricata integrates cleanly with systemd and can run in passive IDS mode (logging alerts without blocking) or active IPS mode (dropping malicious packets via NFQUEUE). This tutorial covers installing Suricata from EPEL, updating rules, tuning the configuration, running as a service, and reading alert logs. By the end you will have a functional IDS monitoring live network traffic with the Emerging Threats ruleset.
Prerequisites
- RHEL 9 server with sudo access
- EPEL repository enabled
- Network interface name known (run
ip link showto find it) - At least 2 GB of free RAM for rule processing
Step 1 — Install Suricata
Suricata is available in the EPEL repository. Install EPEL if not already present, then install Suricata:
dnf install -y epel-release
dnf install -y suricata
Verify the installation and check the version:
suricata --build-info | head -5
suricata -V
Step 2 — Update Suricata Rules
Suricata ships with suricata-update, a tool that downloads and manages rule sources. Update the default Emerging Threats Open ruleset:
# Update rules (downloads Emerging Threats Open by default)
suricata-update
# List available rule sources
suricata-update list-sources
# Optionally enable additional free sources
suricata-update enable-source et/open
suricata-update enable-source oisf/trafficid
suricata-update update
Rules are written to /var/lib/suricata/rules/suricata.rules by default.
Step 3 — Configure suricata.yaml
Edit the main configuration file at /etc/suricata/suricata.yaml. The critical settings are the network interface and HOME_NET (your server’s subnet):
# Set HOME_NET to your internal network range
# Find this section near the top of suricata.yaml and edit:
vars:
address-groups:
HOME_NET: "[192.168.1.0/24,10.0.0.0/8]"
EXTERNAL_NET: "!$HOME_NET"
# Set the capture interface (af-packet section, ~line 580):
af-packet:
- interface: eth0
cluster-id: 99
cluster-type: cluster_flow
defrag: yes
# Confirm the rules path is set:
default-rule-path: /var/lib/suricata/rules
rule-files:
- suricata.rules
Replace eth0 with your actual interface. Replace 192.168.1.0/24 with your actual network range.
Step 4 — Test Configuration and Run in IDS Mode
Validate the configuration before starting the service:
# Test the configuration file for errors
suricata -T -c /etc/suricata/suricata.yaml -v
# Run manually in the foreground on eth0 (IDS mode, read-only)
suricata -c /etc/suricata/suricata.yaml -i eth0
Press Ctrl+C to stop the manual run once you confirm it starts without errors.
Step 5 — Run Suricata as a systemd Service
Enable and start the Suricata systemd service for persistent operation:
systemctl enable --now suricata
systemctl status suricata
# Watch the service log
journalctl -u suricata -f
The service uses /etc/sysconfig/suricata for interface settings. Edit it to match your interface:
cat /etc/sysconfig/suricata
# Change the OPTIONS line if needed:
# OPTIONS="-i eth0 --pidfile /var/run/suricata.pid"
Step 6 — Read Alerts and Switch to IPS Mode
Suricata writes alerts to two log files. The fast log gives a quick summary; the EVE JSON log provides rich structured data:
# Quick alert summary
tail -f /var/log/suricata/fast.log
# Structured JSON alerts (pipe through jq for readability)
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(e.get('timestamp'), e['alert']['signature'], e.get('src_ip'))
except: pass
"
To switch from IDS (detection only) to IPS (active blocking via NFQUEUE), configure nftables to send traffic to the queue, then restart Suricata with the NFQUEUE option:
# Add nftables rule to queue all traffic to Suricata
nft add rule inet filter input queue num 0 bypass
nft add rule inet filter output queue num 0 bypass
# Run Suricata in IPS/NFQUEUE mode
suricata -c /etc/suricata/suricata.yaml -q 0
# Or update /etc/sysconfig/suricata:
# OPTIONS="--af-packet -q 0 --pidfile /var/run/suricata.pid"
Conclusion
You have installed and configured Suricata on RHEL 9, updated the Emerging Threats ruleset, and set it up as a persistent systemd service monitoring live network traffic. Alerts are logged in both human-readable and structured JSON formats for integration with SIEM tools. Running suricata-update regularly via a cron job or systemd timer keeps your rule set current against new threats.
Next steps: How to Install HashiCorp Vault for Secrets Management on RHEL 9, How to Set Up Wazuh SIEM on RHEL 9, and How to Configure Fail2ban on RHEL 9.