Appearance
Suricata Network IDS/IPS Cheat Sheet
Overview
Suricata is a high-performance Network Intrusion Detection System (NIDS), Intrusion Prevention System (IPS), and Network Security Monitoring (NSM) engine. It provides real-time intrusion detection, inline intrusion prevention, network security monitoring, and offline pcap processing. Suricata is widely used in enterprise environments for threat detection, network monitoring, and security analysis with its multi-threaded architecture and advanced detection capabilities.
⚠️ Note: Suricata requires proper network positioning and rule configuration for effective threat detection. It should be deployed with appropriate network access and regularly updated rule sets.
Installation
Package Manager Installation
bash
# Ubuntu/Debian
sudo apt update
sudo apt install suricata
# CentOS/RHEL/Fedora
sudo dnf install epel-release
sudo dnf install suricata
# macOS with Homebrew
brew install suricata
# Verify installation
suricata --version
Source Installation
bash
# Install dependencies (Ubuntu/Debian)
sudo apt install libpcre3-dev libpcap-dev libnet1-dev libyaml-dev libjansson-dev libcap-ng-dev libmagic-dev libnetfilter-queue-dev libnetfilter-log-dev libnfnetlink-dev pkg-config
# Install dependencies (CentOS/RHEL)
sudo dnf install pcre-devel libpcap-devel libnet-devel libyaml-devel jansson-devel libcap-ng-devel file-devel libnetfilter_queue-devel libnetfilter_log-devel libnfnetlink-devel
# Download and compile Suricata
wget https://www.openinfosecfoundation.org/download/suricata-6.0.8.tar.gz
tar -xzf suricata-6.0.8.tar.gz
cd suricata-6.0.8
# Configure with features
./configure --prefix=/usr/local --sysconfdir=/etc --localstatedir=/var \
--enable-nfqueue --enable-nflog --enable-unix-socket
# Compile and install
make -j$(nproc)
sudo make install
# Create user and directories
sudo useradd -r -s /bin/false suricata
sudo mkdir -p /var/log/suricata /var/lib/suricata /etc/suricata/rules
sudo chown -R suricata:suricata /var/log/suricata /var/lib/suricata
Docker Installation
bash
# Pull Suricata image
docker pull jasonish/suricata
# Run Suricata in container
docker run --rm -it --net=host --cap-add=NET_ADMIN \
-v $(pwd)/suricata.yaml:/etc/suricata/suricata.yaml \
-v $(pwd)/logs:/var/log/suricata \
jasonish/suricata -i eth0
# Create custom Dockerfile
cat > Dockerfile << 'EOF'
FROM jasonish/suricata
COPY custom-rules/ /etc/suricata/rules/
COPY suricata.yaml /etc/suricata/
ENTRYPOINT ["suricata"]
EOF
docker build -t custom-suricata .
Basic Configuration
Main Configuration (/etc/suricata/suricata.yaml)
yaml
# suricata.yaml - Main configuration file
# Network interfaces
af-packet:
- interface: eth0
cluster-id: 99
cluster-type: cluster_flow
defrag: yes
use-mmap: yes
tpacket-v3: yes
# Logging configuration
outputs:
- fast:
enabled: yes
filename: fast.log
append: yes
- eve-log:
enabled: yes
filetype: regular
filename: eve.json
types:
- alert
- http
- dns
- tls
- files
- smtp
- ssh
- flow
# Rule configuration
default-rule-path: /etc/suricata/rules
rule-files:
- suricata.rules
- emerging-threats.rules
- local.rules
# Detection engine
detect-engine:
- profile: medium
- custom-values:
toclient-groups: 3
toserver-groups: 25
# Threading
threading:
set-cpu-affinity: no
cpu-affinity:
- management-cpu-set:
cpu: [ 0 ]
- receive-cpu-set:
cpu: [ 0 ]
- worker-cpu-set:
cpu: [ "1-3" ]
detect-thread-ratio: 1.0
# Host OS policy
host-os-policy:
windows: [0.0.0.0/0]
bsd: []
bsd-right: []
old-linux: []
linux: []
old-solaris: []
solaris: []
hpux10: []
hpux11: []
irix: []
macos: []
vista: []
windows2k3: []
Rule Management
bash
# Download Emerging Threats rules
sudo suricata-update
# Update rules with specific sources
sudo suricata-update --reload-command="sudo systemctl reload suricata"
# List available rule sources
suricata-update list-sources
# Enable specific rule sources
sudo suricata-update enable-source et/open
sudo suricata-update enable-source oisf/trafficid
# Disable rules
echo "drop tcp any any -> any any (msg:\"Disabled rule\"; sid:1000001; rev:1;)" | \
sudo tee -a /etc/suricata/rules/disable.conf
Basic Usage
Running Suricata
bash
# Run in IDS mode on interface
sudo suricata -i eth0
# Run with specific configuration
sudo suricata -c /etc/suricata/suricata.yaml -i eth0
# Run in daemon mode
sudo suricata -c /etc/suricata/suricata.yaml -i eth0 -D
# Process pcap file
suricata -r capture.pcap -c /etc/suricata/suricata.yaml
# Run with specific log directory
sudo suricata -i eth0 -l /var/log/suricata/
# Verbose mode
sudo suricata -i eth0 -v
Service Management
bash
# Start Suricata service
sudo systemctl start suricata
# Enable auto-start
sudo systemctl enable suricata
# Check status
sudo systemctl status suricata
# Restart service
sudo systemctl restart suricata
# Reload rules without restart
sudo systemctl reload suricata
# View logs
sudo journalctl -u suricata -f
Rule Testing
bash
# Test rule syntax
suricata -T -c /etc/suricata/suricata.yaml
# Test specific rule file
suricata -T -S /etc/suricata/rules/local.rules
# Validate configuration
sudo suricata --dump-config
# Check rule statistics
sudo suricata --engine-analysis
Rule Development
Basic Rule Syntax
bash
# Basic alert rule
alert tcp any any -> any 80 (msg:"HTTP traffic detected"; sid:1000001; rev:1;)
# Drop rule (IPS mode)
drop tcp any any -> any 22 (msg:"SSH brute force attempt"; threshold:type both,track by_src,count 5,seconds 60; sid:1000002; rev:1;)
# HTTP-specific rule
alert http any any -> any any (msg:"Suspicious user agent"; http.user_agent; content:"sqlmap"; sid:1000003; rev:1;)
# DNS rule
alert dns any any -> any any (msg:"DNS tunneling attempt"; dns.query; content:"|00|"; sid:1000004; rev:1;)
# TLS/SSL rule
alert tls any any -> any any (msg:"Self-signed certificate"; tls.cert_subject; content:"CN=localhost"; sid:1000005; rev:1;)
Advanced Rule Examples
bash
# /etc/suricata/rules/local.rules
# SQL injection detection
alert http any any -> any any (msg:"SQL injection attempt"; http.uri; pcre:"/(\%27)|(\')|(\-\-)|(\%23)|(#)/i"; reference:url,www.owasp.org; classtype:web-application-attack; sid:1000010; rev:1;)
# XSS detection
alert http any any -> any any (msg:"Cross-site scripting attempt"; http.uri; pcre:"/<script[^>]*>.*?<\/script>/i"; reference:url,www.owasp.org; classtype:web-application-attack; sid:1000011; rev:1;)
# Command injection
alert http any any -> any any (msg:"Command injection attempt"; http.uri; pcre:"/(\||;|&|\$\(|\`)/"; classtype:web-application-attack; sid:1000012; rev:1;)
# File upload detection
alert http any any -> any any (msg:"Suspicious file upload"; http.header; content:"Content-Type|3a 20|multipart/form-data"; http.uri; pcre:"/\.(php|asp|aspx|jsp|exe|bat|cmd)$/i"; sid:1000013; rev:1;)
# Cryptocurrency mining detection
alert http any any -> any any (msg:"Cryptocurrency mining script"; http.response_body; content:"CoinHive"; nocase; sid:1000014; rev:1;)
# DNS over HTTPS detection
alert tls any any -> any 443 (msg:"DNS over HTTPS detected"; tls.sni; content:"cloudflare-dns.com"; sid:1000015; rev:1;)
# Tor traffic detection
alert tcp any any -> any any (msg:"Tor traffic detected"; flow:established; content:"|16 03|"; offset:0; depth:2; content:"|01|"; offset:5; depth:1; sid:1000016; rev:1;)
# Lateral movement detection
alert smb any any -> any any (msg:"SMB lateral movement"; smb.command; content:"SMB_COM_SESSION_SETUP_ANDX"; sid:1000017; rev:1;)
# Data exfiltration detection
alert tcp any any -> any any (msg:"Large data transfer"; threshold:type both,track by_src,count 1,seconds 60; byte_test:4,>,1000000,0; sid:1000018; rev:1;)
# Suspicious PowerShell activity
alert http any any -> any any (msg:"PowerShell download cradle"; http.uri; content:"powershell"; nocase; content:"downloadstring"; nocase; distance:0; sid:1000019; rev:1;)
Custom Rule Sets
bash
# /etc/suricata/rules/malware.rules
# Malware communication patterns
alert tcp any any -> any any (msg:"Malware beacon pattern"; threshold:type both,track by_src,count 10,seconds 300; sid:2000001; rev:1;)
# Known malware domains
alert dns any any -> any any (msg:"Malware domain query"; dns.query; content:"evil-domain.com"; nocase; sid:2000002; rev:1;)
# Suspicious file downloads
alert http any any -> any any (msg:"Suspicious executable download"; http.uri; pcre:"/\.(exe|scr|bat|com|pif)$/i"; http.response_body; content:"MZ"; offset:0; depth:2; sid:2000003; rev:1;)
# C2 communication
alert tcp any any -> any any (msg:"Potential C2 communication"; flow:established; content:"|00 00 00|"; offset:0; depth:3; sid:2000004; rev:1;)
IPS Mode Configuration
Netfilter/IPTables Integration
bash
# Configure iptables for IPS mode
sudo iptables -I FORWARD -j NFQUEUE --queue-num 0
# Configure for specific traffic
sudo iptables -I FORWARD -p tcp --dport 80 -j NFQUEUE --queue-num 0
sudo iptables -I FORWARD -p tcp --dport 443 -j NFQUEUE --queue-num 0
# Save iptables rules
sudo iptables-save > /etc/iptables/rules.v4
# Configure Suricata for IPS mode
cat >> /etc/suricata/suricata.yaml << 'EOF'
nfq:
mode: accept
repeat-mark: 1
repeat-mask: 1
bypass-mark: 1
bypass-mask: 1
route-queue: 2
batchcount: 20
fail-open: yes
EOF
IPS Rule Configuration
bash
# /etc/suricata/rules/ips.rules
# Block known malicious IPs
drop tcp [192.168.1.100,10.0.0.50] any -> any any (msg:"Blocked malicious IP"; sid:3000001; rev:1;)
# Block suspicious user agents
drop http any any -> any any (msg:"Blocked malicious user agent"; http.user_agent; content:"sqlmap"; nocase; sid:3000002; rev:1;)
# Block file downloads
drop http any any -> any any (msg:"Blocked executable download"; http.uri; pcre:"/\.(exe|scr|bat)$/i"; sid:3000003; rev:1;)
# Rate limiting
drop tcp any any -> any 22 (msg:"SSH brute force blocked"; threshold:type both,track by_src,count 5,seconds 60; sid:3000004; rev:1;)
# Block DNS tunneling
drop dns any any -> any any (msg:"DNS tunneling blocked"; dns.query; content:"|00|"; sid:3000005; rev:1;)
Log Analysis
EVE JSON Log Analysis
bash
# View real-time alerts
tail -f /var/log/suricata/eve.json | jq 'select(.event_type=="alert")'
# Extract HTTP events
cat /var/log/suricata/eve.json | jq 'select(.event_type=="http")'
# Find high-severity alerts
cat /var/log/suricata/eve.json | jq 'select(.event_type=="alert" and .alert.severity<=2)'
# Analyze DNS queries
cat /var/log/suricata/eve.json | jq 'select(.event_type=="dns") | .dns.rrname' | sort | uniq -c | sort -nr
# Extract TLS information
cat /var/log/suricata/eve.json | jq 'select(.event_type=="tls") | {timestamp: .timestamp, src_ip: .src_ip, dest_ip: .dest_ip, sni: .tls.sni}'
# File transfer analysis
cat /var/log/suricata/eve.json | jq 'select(.event_type=="fileinfo") | {filename: .fileinfo.filename, size: .fileinfo.size, md5: .fileinfo.md5}'
Fast Log Analysis
bash
# View recent alerts
tail -f /var/log/suricata/fast.log
# Count alerts by signature
cat /var/log/suricata/fast.log | awk -F'\\[' '{print $2}' | awk -F'\\]' '{print $1}' | sort | uniq -c | sort -nr
# Find top source IPs
cat /var/log/suricata/fast.log | awk '{print $5}' | awk -F':' '{print $1}' | sort | uniq -c | sort -nr | head -10
# Find top destination IPs
cat /var/log/suricata/fast.log | awk '{print $7}' | awk -F':' '{print $1}' | sort | uniq -c | sort -nr | head -10
# Analyze by time
cat /var/log/suricata/fast.log | awk '{print $1, $2}' | sort | uniq -c
Statistics and Performance
bash
# View Suricata statistics
sudo suricata-sc -c stats
# Dump statistics to file
sudo suricata-sc -c dump-counters
# Monitor performance
watch -n 5 'sudo suricata-sc -c stats | grep -E "(packets|dropped|invalid)"'
# Check rule performance
sudo suricata --engine-analysis | grep -A 10 "Rule performance"
Integration and Automation
ELK Stack Integration
bash
#!/bin/bash
# suricata-to-elasticsearch.sh
SURICATA_LOG="/var/log/suricata/eve.json"
ELASTICSEARCH_URL="http://localhost:9200"
INDEX_NAME="suricata-$(date +%Y.%m.%d)"
# Send Suricata logs to Elasticsearch
tail -F "$SURICATA_LOG" | while read line; do
# Add index metadata
echo "{\"index\":{\"_index\":\"$INDEX_NAME\",\"_type\":\"_doc\"}}"
echo "$line"
done | curl -s -H "Content-Type: application/x-ndjson" \
-X POST "$ELASTICSEARCH_URL/_bulk" \
--data-binary @-
Splunk Integration
bash
# /opt/splunk/etc/apps/suricata/local/inputs.conf
[monitor:///var/log/suricata/eve.json]
disabled = false
sourcetype = suricata:json
index = security
[monitor:///var/log/suricata/fast.log]
disabled = false
sourcetype = suricata:fast
index = security
SIEM Integration Script
python
#!/usr/bin/env python3
# suricata-siem-integration.py
import json
import time
import requests
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
class SuricataLogHandler(FileSystemEventHandler):
def __init__(self, siem_endpoint, api_key):
self.siem_endpoint = siem_endpoint
self.api_key = api_key
self.last_position = 0
def on_modified(self, event):
if event.src_path.endswith('eve.json'):
self.process_eve_log(event.src_path)
def process_eve_log(self, log_path):
"""Process Suricata EVE JSON log"""
try:
with open(log_path, 'r') as f:
f.seek(self.last_position)
for line in f:
if line.strip():
try:
log_entry = json.loads(line.strip())
self.send_to_siem(log_entry)
except json.JSONDecodeError:
continue
self.last_position = f.tell()
except Exception as e:
print(f"Error processing log: {e}")
def send_to_siem(self, log_entry):
"""Send log entry to SIEM"""
# Enrich log entry
enriched_entry = {
'source': 'suricata',
'timestamp': log_entry.get('timestamp'),
'event_type': log_entry.get('event_type'),
'severity': self.calculate_severity(log_entry),
'raw_log': log_entry
}
try:
response = requests.post(
self.siem_endpoint,
json=enriched_entry,
headers={
'Content-Type': 'application/json',
'Authorization': f'Bearer {self.api_key}'
},
timeout=5
)
response.raise_for_status()
except requests.RequestException as e:
print(f"Error sending to SIEM: {e}")
def calculate_severity(self, log_entry):
"""Calculate severity based on event type and content"""
if log_entry.get('event_type') == 'alert':
alert_severity = log_entry.get('alert', {}).get('severity', 3)
if alert_severity <= 1:
return 'HIGH'
elif alert_severity <= 2:
return 'MEDIUM'
else:
return 'LOW'
return 'INFO'
def main():
log_directory = "/var/log/suricata"
siem_endpoint = "https://your-siem.com/api/events"
api_key = "your-api-key"
event_handler = SuricataLogHandler(siem_endpoint, api_key)
observer = Observer()
observer.schedule(event_handler, log_directory, recursive=False)
observer.start()
print(f"Monitoring Suricata logs in {log_directory}")
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()
if __name__ == "__main__":
main()
Automated Response System
bash
#!/bin/bash
# suricata-auto-response.sh
SURICATA_LOG="/var/log/suricata/eve.json"
BLOCKED_IPS_FILE="/tmp/suricata_blocked_ips.txt"
ALERT_THRESHOLD=5
# Function to block IP address
block_ip() {
local ip="$1"
local reason="$2"
echo "$(date): Blocking IP $ip - $reason" >> /var/log/suricata-response.log
# Add to iptables
sudo iptables -I INPUT -s "$ip" -j DROP
# Add to blocked IPs file
echo "$ip" >> "$BLOCKED_IPS_FILE"
# Send notification
echo "ALERT: Blocked IP $ip due to $reason" | \
mail -s "Suricata Auto-Response" admin@example.com
}
# Function to analyze alerts
analyze_alerts() {
local src_ip="$1"
local alert_count=$(grep "\"src_ip\":\"$src_ip\"" "$SURICATA_LOG" | \
grep "\"event_type\":\"alert\"" | \
tail -n 100 | wc -l)
if [ "$alert_count" -ge "$ALERT_THRESHOLD" ]; then
if ! grep -q "$src_ip" "$BLOCKED_IPS_FILE" 2>/dev/null; then
block_ip "$src_ip" "Multiple alerts ($alert_count)"
fi
fi
}
# Monitor Suricata logs
tail -F "$SURICATA_LOG" | while read line; do
# Extract alert events
if echo "$line" | jq -e '.event_type == "alert"' >/dev/null 2>&1; then
src_ip=$(echo "$line" | jq -r '.src_ip')
severity=$(echo "$line" | jq -r '.alert.severity')
# Immediate block for high severity
if [ "$severity" -eq 1 ]; then
if ! grep -q "$src_ip" "$BLOCKED_IPS_FILE" 2>/dev/null; then
block_ip "$src_ip" "High severity alert"
fi
else
# Analyze for repeated alerts
analyze_alerts "$src_ip"
fi
fi
done
Performance Tuning
Multi-threading Configuration
yaml
# suricata.yaml - Threading optimization
threading:
set-cpu-affinity: yes
cpu-affinity:
- management-cpu-set:
cpu: [ 0 ]
- receive-cpu-set:
cpu: [ 1, 2 ]
- worker-cpu-set:
cpu: [ 3, 4, 5, 6 ]
- verdict-cpu-set:
cpu: [ 7 ]
detect-thread-ratio: 1.5
# Worker threads
runmode: workers
Memory Optimization
yaml
# Memory settings
stream:
memcap: 64mb
checksum-validation: yes
inline: auto
reassembly:
memcap: 256mb
depth: 1mb
toserver-chunk-size: 2560
toclient-chunk-size: 2560
# Flow settings
flow:
memcap: 128mb
hash-size: 65536
prealloc: 10000
emergency-recovery: 30
Network Interface Optimization
bash
# Optimize network interface
sudo ethtool -G eth0 rx 4096 tx 4096
sudo ethtool -K eth0 gro off lro off tso off gso off
sudo ethtool -A eth0 rx off tx off
# Set interrupt affinity
echo 2 | sudo tee /proc/irq/24/smp_affinity
echo 4 | sudo tee /proc/irq/25/smp_affinity
# Increase buffer sizes
echo 'net.core.rmem_max = 134217728' >> /etc/sysctl.conf
echo 'net.core.wmem_max = 134217728' >> /etc/sysctl.conf
echo 'net.core.netdev_max_backlog = 5000' >> /etc/sysctl.conf
sysctl -p
Monitoring and Maintenance
Health Monitoring Script
python
#!/usr/bin/env python3
# suricata-health-monitor.py
import subprocess
import json
import time
from datetime import datetime, timedelta
class SuricataHealthMonitor:
def __init__(self):
self.log_file = "/var/log/suricata/eve.json"
self.stats_file = "/var/log/suricata/stats.log"
def check_process_status(self):
"""Check if Suricata process is running"""
try:
result = subprocess.run(['pgrep', 'suricata'],
capture_output=True, text=True)
return len(result.stdout.strip()) > 0
except Exception:
return False
def check_log_freshness(self):
"""Check if logs are being generated"""
try:
import os
if not os.path.exists(self.log_file):
return False, "Log file not found"
mtime = datetime.fromtimestamp(os.path.getmtime(self.log_file))
if datetime.now() - mtime > timedelta(minutes=5):
return False, "Logs appear stale"
return True, "Logs are fresh"
except Exception as e:
return False, f"Error checking logs: {e}"
def check_packet_drops(self):
"""Check for packet drops"""
try:
result = subprocess.run(['suricata-sc', '-c', 'dump-counters'],
capture_output=True, text=True)
# Parse counters (simplified)
if 'decoder.pkts' in result.stdout and 'capture.kernel_drops' in result.stdout:
return True, "Packet statistics available"
return False, "Unable to get packet statistics"
except Exception as e:
return False, f"Error checking packet drops: {e}"
def get_alert_rate(self):
"""Calculate recent alert rate"""
try:
# Count alerts in last hour
one_hour_ago = datetime.now() - timedelta(hours=1)
alert_count = 0
with open(self.log_file, 'r') as f:
for line in f:
try:
log_entry = json.loads(line.strip())
if log_entry.get('event_type') == 'alert':
log_time = datetime.fromisoformat(
log_entry['timestamp'].replace('Z', '+00:00')
)
if log_time > one_hour_ago:
alert_count += 1
except (json.JSONDecodeError, KeyError, ValueError):
continue
return alert_count
except Exception:
return 0
def run_health_check(self):
"""Run comprehensive health check"""
print(f"Suricata Health Check - {datetime.now()}")
print("=" * 50)
# Process status
if self.check_process_status():
print("✓ Suricata process is running")
else:
print("✗ Suricata process is not running")
# Log freshness
log_status, log_message = self.check_log_freshness()
if log_status:
print(f"✓ {log_message}")
else:
print(f"✗ {log_message}")
# Packet drops
drop_status, drop_message = self.check_packet_drops()
if drop_status:
print(f"✓ {drop_message}")
else:
print(f"✗ {drop_message}")
# Alert rate
alert_rate = self.get_alert_rate()
print(f"ℹ Alert rate: {alert_rate} alerts/hour")
print()
def main():
monitor = SuricataHealthMonitor()
while True:
try:
monitor.run_health_check()
time.sleep(300) # Check every 5 minutes
except KeyboardInterrupt:
print("Monitoring stopped")
break
except Exception as e:
print(f"Monitoring error: {e}")
time.sleep(60)
if __name__ == "__main__":
main()
Rule Management Script
bash
#!/bin/bash
# suricata-rule-management.sh
RULE_DIR="/etc/suricata/rules"
BACKUP_DIR="/var/backups/suricata-rules"
CONFIG_FILE="/etc/suricata/suricata.yaml"
# Function to backup current rules
backup_rules() {
local backup_name="rules-backup-$(date +%Y%m%d_%H%M%S)"
mkdir -p "$BACKUP_DIR"
tar -czf "$BACKUP_DIR/$backup_name.tar.gz" -C "$RULE_DIR" .
echo "Rules backed up to $BACKUP_DIR/$backup_name.tar.gz"
}
# Function to update rules
update_rules() {
echo "Updating Suricata rules..."
# Backup current rules
backup_rules
# Update rules
sudo suricata-update --reload-command="sudo systemctl reload suricata"
# Test configuration
if suricata -T -c "$CONFIG_FILE"; then
echo "Rule update successful"
sudo systemctl reload suricata
else
echo "Rule update failed - configuration test failed"
return 1
fi
}
# Function to add custom rule
add_custom_rule() {
local rule="$1"
local rule_file="$RULE_DIR/local.rules"
echo "Adding custom rule: $rule"
echo "$rule" >> "$rule_file"
# Test configuration
if suricata -T -c "$CONFIG_FILE"; then
echo "Custom rule added successfully"
sudo systemctl reload suricata
else
echo "Custom rule failed - removing"
sed -i '$d' "$rule_file"
return 1
fi
}
# Function to disable rule
disable_rule() {
local sid="$1"
local disable_file="$RULE_DIR/disable.conf"
echo "$sid" >> "$disable_file"
echo "Rule $sid disabled"
sudo systemctl reload suricata
}
# Main script
case "$1" in
update)
update_rules
;;
backup)
backup_rules
;;
add)
if [ -z "$2" ]; then
echo "Usage: $0 add \"rule_text\""
exit 1
fi
add_custom_rule "$2"
;;
disable)
if [ -z "$2" ]; then
echo "Usage: $0 disable SID"
exit 1
fi
disable_rule "$2"
;;
*)
echo "Usage: $0 {update|backup|add|disable}"
echo " update - Update rules from sources"
echo " backup - Backup current rules"
echo " add \"rule\" - Add custom rule"
echo " disable SID - Disable rule by SID"
exit 1
;;
esac
Best Practices
Security Configuration
yaml
# Security hardening
app-layer:
protocols:
tls:
detection-ports:
dp: 443
ja3-fingerprints: yes
http:
libhtp:
default-config:
personality: IDS
request-body-limit: 100kb
response-body-limit: 100kb
request-body-minimal-inspect-size: 32kb
request-body-inspect-window: 4kb
response-body-minimal-inspect-size: 40kb
response-body-inspect-window: 16kb
http-body-inline: auto
swf-decompression:
enabled: yes
type: both
compress-depth: 0
decompress-depth: 0
Log Rotation
bash
# /etc/logrotate.d/suricata
/var/log/suricata/*.log /var/log/suricata/*.json {
daily
missingok
rotate 30
compress
delaycompress
sharedscripts
postrotate
/bin/kill -HUP `cat /var/run/suricata.pid 2> /dev/null` 2> /dev/null || true
endscript
}
Performance Monitoring
bash
#!/bin/bash
# suricata-performance-monitor.sh
# Monitor key performance metrics
watch -n 5 '
echo "=== Suricata Performance Monitor ==="
echo "Process Status:"
ps aux | grep suricata | grep -v grep
echo -e "\nMemory Usage:"
cat /proc/$(pgrep suricata)/status | grep -E "VmRSS|VmSize"
echo -e "\nPacket Statistics:"
sudo suricata-sc -c dump-counters | grep -E "decoder.pkts|capture.kernel_drops|detect.alert"
echo -e "\nCPU Usage:"
top -p $(pgrep suricata) -n 1 -b | tail -n 1
'
Troubleshooting
Common Issues
bash
# Issue: High packet drops
# Check interface buffer sizes
cat /proc/net/dev
ethtool -S eth0 | grep drop
# Increase buffer sizes
sudo ethtool -G eth0 rx 4096
# Issue: High memory usage
# Check memory configuration
grep -E "memcap|prealloc" /etc/suricata/suricata.yaml
# Monitor memory usage
cat /proc/$(pgrep suricata)/status | grep Vm
# Issue: Rules not loading
# Test rule syntax
suricata -T -c /etc/suricata/suricata.yaml
# Check rule file permissions
ls -la /etc/suricata/rules/
# Issue: No alerts generated
# Check rule configuration
grep -E "rule-files|default-rule-path" /etc/suricata/suricata.yaml
# Test with known bad traffic
curl -A "sqlmap" http://example.com
Debug Mode
bash
# Enable debug logging
sudo suricata -c /etc/suricata/suricata.yaml -i eth0 -vvv
# Check specific component
sudo suricata -c /etc/suricata/suricata.yaml -i eth0 --set logging.outputs.1.console.level=debug
# Analyze engine performance
sudo suricata --engine-analysis
# Dump configuration
sudo suricata --dump-config
Resources
- Suricata Official Documentation
- Suricata GitHub Repository
- Emerging Threats Rules
- Suricata Community
- OISF Training
This cheat sheet provides comprehensive guidance for deploying and managing Suricata for network intrusion detection and prevention. Regular rule updates and proper tuning are essential for effective threat detection.