Skip to content

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


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.