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 NETCAP iptables chain for easy management

  • Dual-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

Requirement
Details

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 Linux

Rules 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

Blocks 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.
Parameter
Type
Default
Description

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

Rejects traffic with an ICMP response (more informative than DROP).

actions:
  - type: iptables_reject
    config:
      target: source
      duration: 1h
Parameter
Type
Default
Description

target

string

"source"

Block source or destination IP

duration

string/int

30m

Block duration

iptables_log

Logs matching traffic (currently logs to stdout, iptables LOG target planned).

actions:
  - type: iptables_log
    config:
      prefix: "SUSPICIOUS: "
Parameter
Type
Default
Description

prefix

string

"NETCAP: "

Log message prefix

iptables_rate_limit

Rate-limits traffic from/to an IP (placeholder - full implementation pending).

actions:
  - type: iptables_rate_limit
    config:
      rate: "10/minute"
      burst: 5
Parameter
Type
Default
Description

rate

string

"10/minute"

Rate limit specification

burst

int

5

Initial burst allowance

Note: Rate limiting requires the hashlimit iptables 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 execute

Safety 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 NETCAP

Dry-Run Mode

Test configurations without modifying firewall:

config := firewall.DefaultManagerConfig()
config.DryRun = true  // Actions are logged but not executed

Graceful Shutdown

On Close():

  1. Cleanup goroutine stopped

  2. All rules flushed

  3. Jump rules removed

  4. Custom chain deleted

Monitoring & Statistics

Available Statistics

stats := manager.GetStats()
Metric
Description

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()
Metric
Description

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

  1. Use Thresholds: Avoid blocking on single events

    # Good - requires multiple matches
    threshold: 10
    threshold_window: 60
    
    # Bad - blocks on first match
    threshold: 1
  2. Set Appropriate Durations: Match severity to block duration

    # Low severity: short blocks
    duration: 15m
    
    # High severity: longer blocks
    duration: 24h
  3. Combine Actions: Use logging with blocking

    actions:
      - type: iptables_block
        config:
          duration: 1h
      - type: iptables_log
        config:
          prefix: "BLOCKED: "

Whitelist Management

  1. Always whitelist critical infrastructure:

    • Gateways and routers

    • DNS servers

    • Management IPs

    • Monitoring systems

  2. Include your own IPs:

    • SSH access IPs

    • Admin workstations

    • CI/CD systems

Testing

  1. Start with dry-run mode:

    config.DryRun = true
  2. Monitor logs during initial deployment:

    config.Verbose = true
  3. Test with known traffic:

    # Generate test traffic
    nmap -sS target_ip
    
    # Verify block was created
    sudo iptables -L NETCAP -n -v

Production Deployment

  1. Monitor statistics regularly

  2. Review blocked IPs periodically

  3. Keep whitelists up to date

  4. Set up alerting for high block rates

  5. Log all firewall actions for audit

Troubleshooting

Manager Creation Fails

Error: failed to initialize iptables (IPv4): ...

Solutions:

  • Verify iptables is installed: which iptables

  • Check permissions: Run as root or with CAP_NET_ADMIN

  • Verify kernel modules: lsmod | grep xt_

Rules Not Blocking

  1. Check firewall manager is set:

    if engine.GetFirewallManager() == nil {
        log.Warn("Firewall manager not configured")
    }
  2. Verify action configuration:

    actions:
      - type: iptables_block  # Not "block" or "iptables-block"
        config:
          target: source      # Not "src" alone at top level
  3. Check whitelist:

    // IP might be whitelisted
    config.Whitelist

Blocks Not Expiring

  1. Verify cleanup is running:

    // Check verbose logs for cleanup messages
    config.Verbose = true
  2. Check 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 NETCAP

Viewing 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

Last updated