Suricata & Iptables Forensics Skill
This skill helps you configure and use Suricata (IDS/IPS) and iptables for network security forensics and monitoring.
Quick Start
Iptables Basics
Iptables uses chains to process rules sequentially. Three primary chains are always present:
- INPUT: Incoming connections to the local system
- FORWARD: Traffic passing through (routers, NAT)
- OUTPUT: Outgoing connections from the system
Common Iptables Commands
# Delete all rules
iptables -F
# List all rules
iptables -L
iptables -S
# Block IP addresses
iptables -I INPUT -s 192.168.1.100 -j DROP
iptables -I INPUT -s 10.0.0.5,10.0.0.6 -j DROP
# Block ports
iptables -I INPUT -p tcp --dport 443 -j DROP
iptables -I INPUT -p tcp --dport 8000 -j DROP
# Block specific IP on specific port
iptables -I INPUT -s 192.168.1.100 -p tcp --dport 443 -j DROP
# String-based drop (case sensitive)
iptables -I INPUT -p tcp --dport 80 -m string --algo bm --string 'CTF{' -j DROP
iptables -I OUTPUT -p tcp --sport 80 -m string --algo bm --string 'CTF{' -j DROP
# Default drop, allow specific ports
iptables -P INPUT DROP
iptables -I INPUT -p tcp --dport 80 -j ACCEPT
iptables -I INPUT -p tcp --dport 443 -j ACCEPT
iptables -I INPUT -p tcp --dport 22 -j ACCEPT
Persist Iptables Rules
Debian/Ubuntu:
apt-get install iptables-persistent
iptables-save > /etc/iptables/rules.v4
ip6tables-save > /etc/iptables/rules.v6
iptables-restore < /etc/iptables/rules.v4
RHEL/CentOS:
iptables-save > /etc/sysconfig/iptables
ip6tables-save > /etc/sysconfig/ip6tables
iptables-restore < /etc/sysconfig/iptables
Suricata Setup
Installation
Ubuntu:
add-apt-repository ppa:oisf/suricata-stable
apt-get update
apt-get install suricata
Debian:
echo "deb http://http.debian.net/debian buster-backports main" > /etc/apt/sources.list.d/backports.list
apt-get update
apt-get install suricata -t buster-backports
CentOS:
yum install epel-release
yum install suricata
Get and Configure Rules
# Get rules
suricata-update
suricata-update list-sources
suricata-update enable-source et/open
suricata-update
# Update /etc/suricata/suricata.yaml:
default-rule-path: /var/lib/suricata/rules
rule-files:
- suricata.rules
Run Suricata
# Start service
systemctl suricata start
# Run manually on interface
suricata -c /etc/suricata/suricata.yaml -i eth0
# Validate config
suricata -T -c /etc/suricata/suricata.yaml -v
# Reload rules
suricatasc -c ruleset-reload-nonblocking
Configure as IPS (Inline Mode)
- Edit
/etc/suricata/suricata.yaml- find and uncomment:
drop:
alerts: yes
flows: all
- Forward packets to Suricata queue:
iptables -I INPUT -j NFQUEUE
iptables -I OUTPUT -j NFQUEUE
- Start Suricata in IPS mode:
suricata -c /etc/suricata/suricata.yaml -q 0
Or edit the service:
systemctl edit suricata.service
Add:
[Service]
ExecStart=
ExecStart=/usr/bin/suricata -c /etc/suricata/suricata.yaml --pidfile /run/suricata.pid -q 0 -vvv
Type=simple
Then:
systemctl daemon-reload
systemctl restart suricata
Writing Suricata Rules
Rule Structure
A Suricata rule has three parts:
- Action: What to do when matched (alert, drop, pass, reject)
- Header: Protocol, IPs, ports, direction
- Options: Specific matching criteria
Valid Actions
| Action | Description |
|---|---|
alert |
Generate an alert |
pass |
Stop further inspection |
drop |
Drop packet and generate alert |
reject |
Send RST/ICMP error to sender |
rejectsrc |
Same as reject |
rejectdst |
Send error to receiver |
rejectboth |
Send errors to both sides |
Protocols
tcp,udp,icmp,ip(any/all)- Layer 7:
http,ftp,tls,smb,dns,ssh
IP Address Syntax
| Example | Meaning |
|---|---|
!1.1.1.1 |
Every IP except 1.1.1.1 |
![1.1.1.1, 1.1.1.2] |
Every IP except these two |
$HOME_NET |
Defined in yaml config |
[$EXTERNAL_NET, !$HOME_NET] |
External but not home |
[10.0.0.0/24, !10.0.0.5] |
Subnet except one IP |
Port Syntax
| Example | Meaning |
|---|---|
any |
Any port |
[80, 81, 82] |
Ports 80, 81, 82 |
[80:82] |
Range 80-82 |
[1024:] |
1024 and above |
!80 |
Every port except 80 |
[80:100,!99] |
80-100 except 99 |
Direction
source -> destination (one way)
source <> destination (both ways)
Common Keywords
Meta Keywords:
msg: "description" # Rule description
sid: 123 # Unique rule ID
rev: 1 # Revision number
classtype: bad-unknown # Classification
reference: url, www.info.com # Reference URL
priority: 1 # Priority level
Content Matching:
content: "something" # String match
content: |61 61 61| # Hex: AAA
content: "http|3A|//" # Mixed string/hex
content: "abc"; nocase; # Case insensitive
Replace (IPS mode):
content: "abc"; replace: "def" # Must be same length
Regex:
pcre: "/<regex>/opts"
pcre: "/NICK .*USA.*[0-9]{3,}/i"
Geolocation:
geoip: src,RU # Match source from Russia
ICMP:
itype: <10 # ICMP type less than 10
icode: 0 # ICMP code
Rule Examples
Basic Alert
alert http $HOME_NET any -> $EXTERNAL_NET any (
msg:"HTTP GET Request Containing Rule in URI";
flow:established,to_server;
http.method; content:"GET";
http.uri; content:"rule";
fast_pattern;
classtype:bad-unknown;
sid:123;
rev:1;
)
Drop by Port
drop tcp any any -> any 8000 (
msg:"Block port 8000";
sid:1000;
)
String Detection
alert tcp any any -> any any (
msg:"PHP RCE Attempt";
content:"eval";
nocase;
metadata: tag php-rce;
sid:101;
rev:1;
)
Regex Detection
drop tcp any any -> any any (
msg:"CTF Flag Pattern";
pcre:"/CTF\{[\w]{3,}/i";
sid:10001;
)
Content Replace
alert tcp any any -> any any (
msg:"Flag Replace";
content:"CTF{a6st";
replace:"CTF{u798";
nocase;
sid:100;
rev:1;
)
Common Use Cases
Block CTF Flag Exfiltration
# Iptables
iptables -I OUTPUT -p tcp -m string --algo bm --string 'CTF{' -j DROP
# Suricata
drop tcp any any -> any any (
msg:"CTF Flag Exfiltration";
pcre:"/CTF\{[\w\-]{3,}/i";
sid:20001;
)
Block SQL Injection Attempts
alert http any any -> any any (
msg:"SQL Injection Attempt";
http.method; content:"GET";
http.uri; content:"'"; content:"OR"; nocase;
classtype:web-application-attack;
sid:30001;
)
Allowlist Specific IPs
iptables -P INPUT DROP
iptables -I INPUT -s 192.168.1.0/24 -j ACCEPT
iptables -I INPUT -s 10.0.0.0/8 -j ACCEPT
iptables -I INPUT -p tcp --dport 22 -j ACCEPT
Troubleshooting
Suricata
# Check status
systemctl status suricata
# View logs
tail -f /var/log/suricata/eve.json
# Test config
suricata -T -c /etc/suricata/suricata.yaml -v
# Check rule syntax
suricata -T -c /etc/suricata/suricata.yaml
Iptables
# Count matches
iptables -L -v -n
# Save current rules
iptables-save > /tmp/backup.rules
# Restore from backup
iptables-restore < /tmp/backup.rules
# Flush all rules (careful!)
iptables -F
Best Practices
- Test rules before deploying - Use
alertbeforedropto verify matching - Use descriptive messages - Include context in
msg:field - Set unique SIDs - Avoid conflicts with existing rules
- Document rule purpose - Add comments or metadata
- Monitor false positives - Review alerts before enabling drop actions
- Backup before changes - Save iptables rules before modifying
- Use fast_pattern - For performance on frequently matched content
- Test in staging - Validate IPS rules before production deployment