Firewall Response Actions
NETCAP can automatically execute firewall actions (like blocking IPs) when detection rules match. This enables automated incident response by integrating with the Linux iptables firewall subsystem.
Table of Contents
Overview
Features
Automated Blocking: Automatically block IPs based on detection rules
Time-based Expiration: Blocks automatically expire after configurable durations
Whitelist Protection: Prevent blocking of critical infrastructure
Custom Chain: Uses dedicated
NETCAPiptables chain for easy managementDual-Stack Support: Works with both IPv4 and IPv6
Dry-Run Mode: Test configurations without modifying firewall
Statistics Tracking: Monitor block counts, expirations, and errors
Graceful Cleanup: All rules removed on shutdown
Architecture
┌─────────────────────────────────────────────────────────────────────┐
│ NETCAP │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────┐ ┌──────────────────────────────────┐ │
│ │ Rules Engine │─────────│ Detection Rules │ │
│ │ (rules/) │ │ (YAML with expressions) │ │
│ └────────┬─────────┘ └──────────────────────────────────┘ │
│ │ │
│ │ on match + alert generated │
│ ▼ │
│ ┌──────────────────┐ ┌──────────────────────────────────┐ │
│ │ Action Executor │─────────│ Response Actions │ │
│ │ │ │ - iptables_block │ │
│ └────────┬─────────┘ │ - iptables_reject │ │
│ │ │ - iptables_rate_limit │ │
│ ▼ │ - iptables_log │ │
│ ┌──────────────────┐ └──────────────────────────────────┘ │
│ │ Firewall Manager │◄──── github.com/coreos/go-iptables │
│ │ (firewall/) │ │
│ └────────┬─────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ Linux iptables │ │
│ │ ┌──────────────────────────────────────────────────────┐ │ │
│ │ │ NETCAP Chain (custom) │ │ │
│ │ │ -s 192.168.1.100 -j DROP -m comment "NETCAP: ..." │ │ │
│ │ │ -s 10.0.0.50 -j REJECT -m comment "NETCAP: ..." │ │ │
│ │ └──────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ INPUT ──► -j NETCAP │ │
│ │ FORWARD ──► -j NETCAP │ │
│ │ OUTPUT ──► -j NETCAP │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘Requirements
Operating System
Linux (iptables required)
Privileges
Root or CAP_NET_ADMIN capability
iptables
iptables and/or ip6tables installed
Kernel Modules
xt_comment module for rule comments
Non-Linux Platforms
On non-Linux platforms (macOS, Windows), the firewall manager returns an error:
firewall management is only supported on LinuxRules with firewall response actions will be skipped with a warning.
Configuration
Firewall Manager Configuration
config := &firewall.ManagerConfig{
// Custom chain name (default: "NETCAP")
ChainName: "NETCAP",
// Enable IPv4 iptables (default: true)
EnableIPv4: true,
// Enable IPv6 ip6tables (default: true)
EnableIPv6: true,
// How often to check for expired blocks (default: 1 minute)
CleanupInterval: 1 * time.Minute,
// Default block duration if not specified (default: 30 minutes)
DefaultDuration: 30 * time.Minute,
// IPs/CIDRs that should never be blocked
Whitelist: []string{
"127.0.0.0/8",
"::1/128",
"192.168.1.1", // Gateway
},
// Preview mode - log actions without executing
DryRun: false,
// Enable verbose logging
Verbose: true,
}
manager, err := firewall.NewManager(config)Rule Configuration with Response Actions
Add an actions array to detection rules:
rules:
- name: Block SSH Brute Force
description: Block hosts after multiple SSH attempts
type: SSH
expression: DstPort == 22
severity: high
threshold: 10
threshold_window: 300
actions:
- type: iptables_block
config:
target: source # "source" or "destination"
duration: 2h # Block duration
enabled: true
tags: ["ssh", "brute-force", "block"]Response Action Types
iptables_block
iptables_blockBlocks traffic by adding a DROP rule to iptables.
actions:
- type: iptables_block
config:
target: source # "source" or "destination"
duration: 30m # Duration: 30m, 1h, 24h, etc.target
string
"source"
Block source (source/src) or destination (destination/dst) IP
duration
string/int
30m
Block duration. String ("30m", "2h") or int (minutes)
iptables_reject
iptables_rejectRejects traffic with an ICMP response (more informative than DROP).
actions:
- type: iptables_reject
config:
target: source
duration: 1htarget
string
"source"
Block source or destination IP
duration
string/int
30m
Block duration
iptables_log
iptables_logLogs matching traffic (currently logs to stdout, iptables LOG target planned).
actions:
- type: iptables_log
config:
prefix: "SUSPICIOUS: "prefix
string
"NETCAP: "
Log message prefix
iptables_rate_limit
iptables_rate_limitRate-limits traffic from/to an IP (placeholder - full implementation pending).
actions:
- type: iptables_rate_limit
config:
rate: "10/minute"
burst: 5rate
string
"10/minute"
Rate limit specification
burst
int
5
Initial burst allowance
Note: Rate limiting requires the
hashlimitiptables module and is not fully implemented.
Rule Examples
Port Scanning Detection & Block
- name: Block Port Scanner
description: Block hosts performing port scans
type: TCP
expression: |
SYN && !ACK && PayloadSize == 0
severity: high
threshold: 50
threshold_window: 10
actions:
- type: iptables_block
config:
target: source
duration: 1h
enabled: true
mitre: ["T1046"]
tags: ["scanning", "recon", "block"]SSH Brute Force Protection
- name: Block SSH Brute Force
description: Block hosts after 10 SSH connection attempts in 5 minutes
type: TCP
expression: DstPort == 22 && SYN && !ACK
severity: high
threshold: 10
threshold_window: 300
actions:
- type: iptables_block
config:
target: source
duration: 2h
enabled: true
mitre: ["T1110"]
tags: ["ssh", "brute-force", "block"]DNS Tunneling Detection
- name: Block DNS Tunneling
description: Block hosts using DNS tunneling for data exfiltration
type: DNS
expression: |
len(Questions) > 0 &&
len(Questions[0].Name) > 100
severity: high
threshold: 20
threshold_window: 60
actions:
- type: iptables_block
config:
target: source
duration: 4h
- type: iptables_log
config:
prefix: "DNS_TUNNEL: "
enabled: true
mitre: ["T1071.004", "T1048"]
tags: ["dns", "tunneling", "exfiltration", "block"]Web Attack Detection
- name: Block SQL Injection Attempts
description: Block hosts attempting SQL injection
type: HTTP
expression: |
MatchesPattern(URL, "(?i)(union.*select|insert.*into|drop.*table)")
severity: critical
threshold: 3
threshold_window: 60
actions:
- type: iptables_block
config:
target: source
duration: 24h
enabled: true
mitre: ["T1190"]
tags: ["sql-injection", "web-attack", "block"]SYN Flood Protection
- name: Block SYN Flood Source
description: Block hosts generating SYN flood attacks
type: TCP
expression: SYN && !ACK && PayloadSize == 0
severity: critical
threshold: 100
threshold_window: 5
actions:
- type: iptables_block
config:
target: source
duration: 6h
- type: iptables_log
config:
prefix: "SYN_FLOOD: "
enabled: true
mitre: ["T1498"]
tags: ["dos", "syn-flood", "block"]Firewall Manager API
Creating a Manager
import "github.com/dreadl0ck/netcap/firewall"
// Create with default config
manager, err := firewall.NewManager(nil)
// Create with custom config
config := firewall.DefaultManagerConfig()
config.Whitelist = append(config.Whitelist, "10.0.0.1")
config.Verbose = true
manager, err := firewall.NewManager(config)Blocking IPs
// Block an IP
err := manager.BlockIP("192.168.1.100", &firewall.BlockConfig{
Target: "source",
Duration: 30 * time.Minute,
Action: "DROP",
RuleName: "manual-block",
Reason: "Port scanning detected",
})
// Block a CIDR range
err := manager.BlockCIDR("10.0.0.0/24", &firewall.BlockConfig{
Target: "source",
Duration: 1 * time.Hour,
Action: "DROP",
RuleName: "network-block",
})Unblocking IPs
// Unblock an IP
err := manager.UnblockIP("192.168.1.100")
// Unblock a CIDR
err := manager.UnblockCIDR("10.0.0.0/24")Querying State
// Check if IP is blocked
if manager.IsBlocked("192.168.1.100") {
fmt.Println("IP is blocked")
}
// Get all active blocks
blocks := manager.GetActiveBlocks()
for _, block := range blocks {
fmt.Printf("Blocked: %s (expires: %v)\n", block.IP, block.ExpiresAt)
}
// Get statistics
stats := manager.GetStats()
fmt.Printf("Blocks created: %d\n", stats["blocks_created"])
fmt.Printf("Active blocks: %d\n", stats["active_blocks"])Whitelist Management
// Add to whitelist
manager.AddToWhitelist("192.168.1.1")
manager.AddToWhitelist("10.0.0.0/8")
// Remove from whitelist
manager.RemoveFromWhitelist("192.168.1.1")Cleanup
// Flush all rules (but keep chain)
err := manager.Flush()
// Close manager (flushes rules, removes chain, stops goroutines)
err := manager.Close()Integration with Rules Engine
import (
"github.com/dreadl0ck/netcap/firewall"
"github.com/dreadl0ck/netcap/rules"
)
// Create firewall manager
fwManager, err := firewall.NewManager(nil)
if err != nil {
log.Fatal(err)
}
defer fwManager.Close()
// Create rules engine
engine, err := rules.NewEngine("rules/", alertWriter)
if err != nil {
log.Fatal(err)
}
// Connect firewall manager to rules engine
engine.SetFirewallManager(fwManager)
// Now response actions in rules will automatically executeSafety Features
Whitelist Protection
IPs/CIDRs in the whitelist are never blocked:
config := firewall.DefaultManagerConfig()
config.Whitelist = []string{
"127.0.0.0/8", // Localhost
"::1/128", // IPv6 localhost
"192.168.1.1", // Gateway
"10.0.0.0/8", // Internal network
}Automatic Expiration
All blocks expire automatically:
Configurable per-rule duration
Default: 30 minutes
Background cleanup every minute
Zero duration = permanent until restart
Custom Chain Isolation
All rules are placed in a dedicated NETCAP chain:
# View NETCAP chain rules
sudo iptables -L NETCAP -n -v
# Manually flush if needed
sudo iptables -F NETCAPDry-Run Mode
Test configurations without modifying firewall:
config := firewall.DefaultManagerConfig()
config.DryRun = true // Actions are logged but not executedGraceful Shutdown
On Close():
Cleanup goroutine stopped
All rules flushed
Jump rules removed
Custom chain deleted
Monitoring & Statistics
Available Statistics
stats := manager.GetStats()blocks_created
Total blocks created since start
blocks_removed
Blocks manually removed
blocks_expired
Blocks removed due to expiration
duplicates_skip
Duplicate block requests skipped
whitelist_skip
Block requests skipped due to whitelist
errors
Total errors encountered
active_blocks
Currently active blocks
Action Statistics (Rules Engine)
actionStats := engine.GetActionStats()actions_executed
Total response actions executed
actions_success
Successful actions
actions_failed
Failed actions
ips_blocked
Total IPs blocked
Viewing Active Blocks
blocks := manager.GetActiveBlocks()
for _, b := range blocks {
fmt.Printf("IP: %s\n", b.IP)
fmt.Printf(" Rule: %s\n", b.RuleName)
fmt.Printf(" Reason: %s\n", b.Reason)
fmt.Printf(" Created: %v\n", b.CreatedAt)
fmt.Printf(" Expires: %v\n", b.ExpiresAt)
fmt.Printf(" Action: %s\n", b.Action)
}Best Practices
Rule Design
Use Thresholds: Avoid blocking on single events
# Good - requires multiple matches threshold: 10 threshold_window: 60 # Bad - blocks on first match threshold: 1Set Appropriate Durations: Match severity to block duration
# Low severity: short blocks duration: 15m # High severity: longer blocks duration: 24hCombine Actions: Use logging with blocking
actions: - type: iptables_block config: duration: 1h - type: iptables_log config: prefix: "BLOCKED: "
Whitelist Management
Always whitelist critical infrastructure:
Gateways and routers
DNS servers
Management IPs
Monitoring systems
Include your own IPs:
SSH access IPs
Admin workstations
CI/CD systems
Testing
Start with dry-run mode:
config.DryRun = trueMonitor logs during initial deployment:
config.Verbose = trueTest with known traffic:
# Generate test traffic nmap -sS target_ip # Verify block was created sudo iptables -L NETCAP -n -v
Production Deployment
Monitor statistics regularly
Review blocked IPs periodically
Keep whitelists up to date
Set up alerting for high block rates
Log all firewall actions for audit
Troubleshooting
Manager Creation Fails
Error: failed to initialize iptables (IPv4): ...Solutions:
Verify iptables is installed:
which iptablesCheck permissions: Run as root or with
CAP_NET_ADMINVerify kernel modules:
lsmod | grep xt_
Rules Not Blocking
Check firewall manager is set:
if engine.GetFirewallManager() == nil { log.Warn("Firewall manager not configured") }Verify action configuration:
actions: - type: iptables_block # Not "block" or "iptables-block" config: target: source # Not "src" alone at top levelCheck whitelist:
// IP might be whitelisted config.Whitelist
Blocks Not Expiring
Verify cleanup is running:
// Check verbose logs for cleanup messages config.Verbose = trueCheck expiration time:
blocks := manager.GetActiveBlocks() for _, b := range blocks { fmt.Printf("Expires: %v (in %v)\n", b.ExpiresAt, time.Until(b.ExpiresAt)) }
Rules Persist After Shutdown
If rules remain after unclean shutdown:
# Manually flush NETCAP chain
sudo iptables -F NETCAP
sudo ip6tables -F NETCAP
# Remove jump rules
sudo iptables -D INPUT -j NETCAP
sudo iptables -D FORWARD -j NETCAP
sudo iptables -D OUTPUT -j NETCAP
# Delete chain
sudo iptables -X NETCAPViewing iptables Rules
# List NETCAP chain with details
sudo iptables -L NETCAP -n -v --line-numbers
# List all chains showing NETCAP jumps
sudo iptables -L -n -v | grep -A5 NETCAP
# Watch for changes
watch -n1 'sudo iptables -L NETCAP -n'Next Steps
Review RULES_ENGINE.md for detection rule syntax
See FILTERING.md for expression syntax
Check example rules in configs/firewall-rules.yml
Explore injection rules for real-time packet actions
Last updated