Network Security Monitoring with Suricata
If you want to see what is happening on your lab network — exploit attempts, scans, suspicious traffic — you need an IDS. Suricata is fast, flexible, and free. I run it on a dedicated Ubuntu VM that sits between my attack machines and my vulnerable targets.
This is not a comprehensive Suricata deployment guide. This is how I set it up in my lab to learn how network-based detection works.
What Suricata does
Suricata inspects network traffic in real time and matches it against rules. When it sees something that matches a rule (like an Nmap scan or a Metasploit payload), it logs an alert. You can run it in IDS mode (just log) or IPS mode (block the traffic). I run IDS mode because I want to see everything, not block it.
VM requirements
- 4GB RAM — Suricata can use more if you have it, but 4GB works fine for a lab
- 2 vCPUs
- Ubuntu 22.04 LTS (or 24.04 if you are reading this later)
- Two network interfaces — one for management (SSH), one for monitoring
The monitoring interface should be on the same network as your vulnerable VMs. Set it to promiscuous mode so it can see all traffic, not just traffic addressed to it.
Installing Suricata
SSH into your Ubuntu VM and run:
sudo apt update
sudo apt install software-properties-common -y
sudo add-apt-repository ppa:oisf/suricata-stable -y
sudo apt update
sudo apt install suricata jq -y
Check the version:
suricata --version
As of November 2024, the stable PPA has Suricata 7.0.x. That is what I am running.
Configuration
Suricata’s main config is at /etc/suricata/suricata.yaml. It is huge. Most of it you can leave alone.
Set your HOME_NET
Open /etc/suricata/suricata.yaml and find the address-groups section. Set HOME_NET to match your lab network:
vars:
address-groups:
HOME_NET: "[192.168.100.0/24]"
EXTERNAL_NET: "!$HOME_NET"
Replace 192.168.100.0/24 with your actual lab subnet.
Pick your monitoring interface
Find the af-packet section and set the interface to the one you want to monitor:
af-packet:
- interface: ens19
cluster-id: 99
cluster-type: cluster_flow
defrag: yes
Replace ens19 with your monitoring interface name (check with ip link show).
Disable hardware offloading
This tripped me up the first time. Network interface offloading features (TSO, GRO, etc.) can cause Suricata to miss packets. Turn them off:
sudo ethtool -K ens19 gro off lro off
Replace ens19 with your interface. To make it persistent, add the command to /etc/rc.local or create a systemd service.
Rule management
Suricata uses rules to detect threats. The rules are in /etc/suricata/rules/. By default, you get a basic set. To get the Emerging Threats (ET) Open ruleset:
sudo suricata-update
This downloads the latest rules and reloads Suricata. Run it weekly or whenever you want fresh rules.
To enable all the rules (not just the recommended ones), edit /etc/suricata/suricata.yaml and find the rule-files section. Make sure it includes:
rule-files:
- suricata.rules
Then:
sudo suricata-update enable-source et/open
sudo suricata-update
sudo systemctl restart suricata
Running Suricata
Start it:
sudo systemctl start suricata
sudo systemctl enable suricata
Check the logs:
sudo tail -f /var/log/suricata/suricata.log
If you see errors about the interface not being in promiscuous mode, set it manually:
sudo ip link set ens19 promisc on
Testing it
From your Kali box, run an Nmap scan against one of your vulnerable VMs:
nmap -sV 192.168.100.50
Then check Suricata’s alerts:
sudo tail -f /var/log/suricata/fast.log
You should see alerts for the scan. If not, check that:
- Your monitoring interface is on the same network
- Promiscuous mode is enabled
- The rules are loaded (
sudo suricata-update list-enabled-sources)
Viewing alerts with jq
The EVE JSON log (/var/log/suricata/eve.json) is easier to parse than the fast log. Use jq to filter it:
sudo tail -f /var/log/suricata/eve.json | jq 'select(.event_type=="alert")'
This shows only alerts in real time.
What I use Suricata for
- Seeing how attacks look on the wire — run an exploit from Metasploit, then check what Suricata logged
- Testing evasion techniques — if I modify a payload or use fragmentation, does Suricata still catch it?
- Learning rule syntax — I write custom rules and test them against known-bad traffic
What I do not do
- Run it in IPS mode in my lab (I want to see everything, not block it)
- Forward logs to a SIEM (I just read the local logs for now)
- Tune it heavily (default rules are fine for learning)
Resources
If you want to go deeper, set up log forwarding to a SIEM (ELK, Splunk, Wazuh) and build dashboards. For now, watching the logs locally is enough to understand how network detection works.
Previous: Deploying Vulnerable Applications ENIP_CLIENT: “$HOME_NET” ENIP_SERVER: “$HOME_NET”
port-groups: HTTP_PORTS: “80” SHELLCODE_PORTS: “!80” ORACLE_PORTS: 1521 SSH_PORTS: 22 DNP3_PORTS: 20000 MODBUS_PORTS: 502 FILE_DATA_PORTS: ”[$HTTP_PORTS,110,143]” FTP_PORTS: 21 GENEVE_PORTS: 6081 VXLAN_PORTS: 4789 TEREDO_PORTS: 3544
Logging configuration
logging: default-log-level: notice outputs:
- console: enabled: yes
- file: enabled: yes level: info filename: /var/log/suricata/suricata.log
- syslog: enabled: no facility: local5 format: ”[%i] <%d> — “
Output plugins
outputs:
- fast: enabled: yes filename: fast.log append: yes
- eve-log: enabled: yes filetype: regular filename: eve.json types: - alert: payload: yes payload-buffer-size: 4kb payload-printable: yes packet: yes metadata: no http-body: yes http-body-printable: yes tagged-packets: yes - http: extended: yes - dns: query: yes answer: yes - tls: extended: yes - files: force-magic: no - smtp: - ssh - stats: totals: yes threads: no deltas: no - flow
### Step 4: Rule Management
#### Download and Install Rules
```bash
# Install suricata-update
sudo pip3 install suricata-update
# Initialize suricata-update
sudo suricata-update
# Update rules
sudo suricata-update update-sources
sudo suricata-update
# Enable specific rule sources
sudo suricata-update enable-source et/open
sudo suricata-update enable-source oisf/trafficid
sudo suricata-update
Custom Rule Creation
# Create custom rules directory
sudo mkdir -p /etc/suricata/rules/custom
# Example custom rule
echo 'alert tcp any any -> $HOME_NET 22 (msg:"SSH Connection Attempt"; flow:to_server; flags:S; sid:1000001; rev:1;)' | sudo tee /etc/suricata/rules/custom/ssh-monitoring.rules
# Include custom rules in main config
echo 'rule-files:' | sudo tee -a /etc/suricata/suricata.yaml
echo ' - /etc/suricata/rules/custom/ssh-monitoring.rules' | sudo tee -a /etc/suricata/suricata.yaml
Step 5: Log Management and Analysis
Logrotate Configuration
# Configure log rotation
sudo tee /etc/logrotate.d/suricata << EOF
/var/log/suricata/*.log /var/log/suricata/*.json {
daily
missingok
rotate 30
compress
delaycompress
sharedscripts
create 640 suricata suricata
postrotate
/bin/kill -HUP \`cat /var/run/suricata.pid 2>/dev/null\` 2>/dev/null || true
endscript
}
EOF
Real-time Log Monitoring
# Monitor alerts in real-time
sudo tail -f /var/log/suricata/fast.log
# Monitor EVE JSON logs
sudo tail -f /var/log/suricata/eve.json | jq
# Monitor specific event types
sudo tail -f /var/log/suricata/eve.json | jq 'select(.event_type=="alert")'
Integration with SIEM
ELK Stack Integration
Filebeat Configuration
# /etc/filebeat/filebeat.yml
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/suricata/eve.json
json.keys_under_root: true
json.add_error_key: true
fields:
logtype: suricata
fields_under_root: true
output.elasticsearch:
hosts: ["elasticsearch:9200"]
index: "suricata-%{+yyyy.MM.dd}"
setup.template.name: "suricata"
setup.template.pattern: "suricata-*"
Kibana Dashboard Creation
{
"dashboard": {
"id": "suricata-overview",
"title": "Suricata Security Overview",
"visualizations": [
{
"id": "alerts-over-time",
"type": "line",
"query": "event_type:alert"
},
{
"id": "top-signatures",
"type": "data_table",
"query": "event_type:alert",
"aggregation": "terms",
"field": "alert.signature"
},
{
"id": "protocol-distribution",
"type": "pie",
"query": "event_type:flow",
"aggregation": "terms",
"field": "proto"
}
]
}
}
Splunk Integration
Universal Forwarder Configuration
# /opt/splunkforwarder/etc/system/local/inputs.conf
[monitor:///var/log/suricata/eve.json]
disabled = false
index = security
sourcetype = suricata:eve:json
host_segment = 4
[monitor:///var/log/suricata/fast.log]
disabled = false
index = security
sourcetype = suricata:alert
host_segment = 4
Performance Tuning
System Optimization
Kernel Parameters
# /etc/sysctl.conf optimizations
echo 'net.core.rmem_default = 262144' | sudo tee -a /etc/sysctl.conf
echo 'net.core.rmem_max = 16777216' | sudo tee -a /etc/sysctl.conf
echo 'net.core.netdev_max_backlog = 5000' | sudo tee -a /etc/sysctl.conf
# Apply changes
sudo sysctl -p
CPU Affinity
# Pin Suricata to specific CPU cores
echo 'SURICATA_OPTIONS="--cpu-affinity=1-3"' | sudo tee -a /etc/default/suricata
Suricata-Specific Tuning
Worker Thread Configuration
# In suricata.yaml
threading:
set-cpu-affinity: yes
cpu-affinity:
- management-cpu-set:
cpu: [ 0 ]
- receive-cpu-set:
cpu: [ 1 ]
- worker-cpu-set:
cpu: [ 2, 3 ]
mode: "exclusive"
Memory Management
# In suricata.yaml
defrag:
memcap: 32mb
hash-size: 65536
trackers: 65535
max-frags: 65535
prealloc: yes
timeout: 60
flow:
memcap: 128mb
hash-size: 65536
prealloc: 10000
emergency-recovery: 30
Testing and Validation
Generate Test Traffic
# Install nmap for testing
sudo apt install nmap -y
# Generate various types of traffic
nmap -sS 192.168.1.0/24 # SYN scan
nmap -sU 192.168.1.1 # UDP scan
curl -A "BADBOT" http://192.168.1.100/ # User-agent alert
# Test with EICAR string
echo 'X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*' > eicar.txt
python3 -m http.server 8000 # Serve file for download test
Alert Verification
# Check for generated alerts
sudo grep -i "EICAR" /var/log/suricata/fast.log
sudo grep -i "nmap" /var/log/suricata/fast.log
# Verify JSON events
sudo jq '.event_type' /var/log/suricata/eve.json | sort | uniq -c
Advanced Features
File Extraction
# In suricata.yaml
file-store:
version: 2
enabled: yes
dir: /var/log/suricata/files
write-fileinfo: yes
write-meta: yes
include-pid: yes
Protocol Detection
# Enhanced protocol detection
app-layer:
protocols:
tls:
enabled: yes
detection-ports:
dp: 443
http:
enabled: yes
libhtp:
default-config:
personality: IDS
request-body-limit: 100kb
response-body-limit: 100kb
Lua Scripting
-- /etc/suricata/scripts/custom-detection.lua
function init (args)
local needs = {}
needs["http.request_line"] = tostring(true)
return needs
end
function match(args)
local request_line = HttpGetRequestLine()
if request_line then
if string.find(request_line, "admin") then
return 1
end
end
return 0
end
Troubleshooting
Common Issues
High CPU Usage
# Check thread distribution
sudo grep "thread" /var/log/suricata/suricata.log
# Monitor CPU usage per core
htop
# Adjust worker threads
sudo systemctl edit suricata
# Add: Environment="SURICATA_OPTIONS=--runmode=workers --cpu-affinity=1-2"
Packet Drops
# Check interface statistics
sudo ethtool -S eth0 | grep drop
# Monitor Suricata stats
sudo tail -f /var/log/suricata/stats.log
# Increase buffer sizes
echo 'net.core.netdev_max_backlog = 10000' | sudo tee -a /etc/sysctl.conf
Memory Issues
# Monitor memory usage
sudo grep -i memcap /var/log/suricata/suricata.log
# Adjust memory caps in suricata.yaml
# Increase flow.memcap and stream.memcap values
Performance Monitoring
#!/bin/bash
# suricata-stats.sh
while true; do
echo "=== $(date) ==="
sudo grep "Capture.Kernel" /var/log/suricata/stats.log | tail -1
sudo grep "Flow.Memuse" /var/log/suricata/stats.log | tail -1
echo "CPU Usage: $(top -bn1 | grep suricata | awk '{print $9}')%"
echo "Memory: $(ps aux | grep suricata | grep -v grep | awk '{print $6}') KB"
echo ""
sleep 60
done
Security Best Practices
Hardening Guidelines
- Run Suricata as non-root user
- Implement proper file permissions
- Regular rule updates and testing
- Secure log file access
- Network segmentation for monitoring traffic
Maintenance Tasks
- Weekly rule updates
- Monthly performance reviews
- Quarterly signature tuning
- Annual architecture reviews
Conclusion
You now have a fully functional network security monitoring system using Suricata in your home lab. This setup provides:
- Real-time threat detection across your entire network
- Comprehensive logging for forensic analysis
- Flexible rule management for custom detection scenarios
- Integration capabilities with popular SIEM platforms
- Performance optimization for high-throughput environments
Next Steps
- Tune rules based on your specific environment
- Integrate with SIEM for centralized log management
- Implement response automation using SOAR platforms
- Add network forensics capabilities with full packet capture
- Deploy threat hunting workflows and playbooks
This advanced monitoring capability significantly enhances your home lab’s security posture and provides valuable hands-on experience with enterprise-grade security tools.
Continue your home lab journey with Part 4: Incident Response Automation to build automated response capabilities.