caddy-sip-guardian/README.md
Ryan Malloy f03ac453e0 Update README with comprehensive Phase 1 documentation
Documents all new features:
- Extension enumeration detection with config examples
- SIP message validation rules and modes
- Topology hiding (B2BUA-lite) with request/response flow diagrams
- Complete Caddyfile configuration reference
- Prometheus metrics reference
- Admin API endpoints
- Integration examples for FreePBX, Kamailio, and HA setups
- Security considerations

Architecture diagram updated to show full processing pipeline.
2025-12-07 20:40:11 -07:00

16 KiB

Caddy SIP Guardian

A comprehensive Caddy module providing SIP-aware security at Layer 4. Protects your VoIP infrastructure with intelligent rate limiting, attack detection, message validation, and topology hiding.

Features

Core Protection

  • Layer 4 SIP Proxying: Handle SIP traffic (UDP/TCP/TLS) before it reaches your PBX
  • Intelligent Rate Limiting: Per-method token bucket rate limiting with burst support
  • Automatic Banning: Ban IPs that exceed failure thresholds
  • Attack Detection: Detect common SIP scanning tools (SIPVicious, friendly-scanner, etc.)
  • CIDR Whitelisting: Whitelist trusted networks
  • GeoIP Blocking: Block traffic by country using MaxMind databases

Extension Enumeration Detection

  • Count-based Detection: Block IPs probing too many unique extensions
  • Sequential Pattern Detection: Detect numeric extension scanning (100, 101, 102...)
  • Rapid-fire Detection: Catch high-speed enumeration attempts
  • Configurable Exemptions: Whitelist common extensions like voicemail

SIP Message Validation

  • RFC 3261 Compliance: Enforce required headers and message structure
  • Injection Prevention: Block NULL bytes and binary injection attacks
  • Content-Length Validation: Detect body/header mismatches
  • Multiple Modes: Permissive, strict, or paranoid validation

Topology Hiding (B2BUA-lite)

  • Via Header Rewriting: Hide internal proxy chain
  • Contact Header Rewriting: Mask internal IP addresses
  • Sensitive Header Stripping: Remove P-Asserted-Identity, Server, etc.
  • Call-ID Anonymization: Prevent dialog correlation attacks
  • Private IP Masking: Automatically hide RFC 1918 addresses

Observability

  • Prometheus Metrics: Comprehensive metrics for monitoring
  • Webhook Notifications: Real-time alerts for security events
  • SQLite Persistence: Durable ban storage across restarts
  • Admin API: RESTful API for management and stats

Architecture

Internet
    │
    ▼
┌─────────────────────────────────────────────────────────────┐
│  Caddy SIP Guardian (Layer 4)                                │
│  ┌─────────────────────────────────────────────────────────┐│
│  │ 1. SIP Matcher         - Identifies SIP traffic         ││
│  │ 2. Ban Check           - Reject banned IPs              ││
│  │ 3. Whitelist Check     - Skip checks for trusted IPs    ││
│  │ 4. GeoIP Check         - Block by country               ││
│  │ 5. Validation          - RFC 3261 compliance            ││
│  │ 6. Pattern Detection   - Scanner fingerprinting         ││
│  │ 7. Enumeration Check   - Extension scanning detection   ││
│  │ 8. Rate Limiting       - Per-method token buckets       ││
│  │ 9. Topology Hiding     - Header rewriting (optional)    ││
│  └─────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────┘
    │
    ▼
┌─────────────────────────────────────────────────────────────┐
│  FreePBX / Asterisk / Kamailio                               │
│  (Protected from scanners, enumeration, and topology leaks)  │
└─────────────────────────────────────────────────────────────┘

Quick Start

# Build the custom Caddy image
make build

# Start the stack
make run

# View logs
make logs

# Run tests
make test

Configuration

Complete Caddyfile Example

{
    layer4 {
        # UDP SIP (standard port)
        udp/:5060 {
            @sip sip {
                methods REGISTER INVITE OPTIONS ACK BYE CANCEL INFO NOTIFY SUBSCRIBE MESSAGE
            }

            route @sip {
                sip_guardian {
                    # Core settings
                    max_failures 5
                    find_time 10m
                    ban_time 1h
                    whitelist 10.0.0.0/8 192.168.0.0/16

                    # GeoIP blocking (optional)
                    geoip_db /etc/caddy/GeoLite2-Country.mmdb
                    blocked_countries CN RU

                    # Per-method rate limiting
                    rate_limit {
                        register 10/s burst 20
                        invite 5/s burst 10
                        options 20/s burst 50
                    }

                    # Extension enumeration detection
                    enumeration {
                        max_extensions 20
                        extension_window 5m
                        sequential_threshold 5
                        rapid_fire_count 10
                        rapid_fire_window 30s
                        ban_time 2h
                        exempt_extensions 100 200 9999
                    }

                    # SIP message validation
                    validation {
                        enabled true
                        mode strict
                        max_message_size 65535
                        ban_on_null_bytes true
                        ban_on_binary_injection true
                    }

                    # Prometheus metrics
                    metrics {
                        enabled true
                    }

                    # Webhook notifications
                    webhooks {
                        url https://hooks.example.com/sip-alerts
                        events ban unban attack enumeration
                    }

                    # SQLite persistence
                    storage {
                        path /var/lib/caddy/sip_guardian.db
                    }
                }

                # Optional: Topology hiding
                sip_topology_hider {
                    proxy_host 203.0.113.1
                    proxy_port 5060
                    upstream udp/192.168.1.100:5060

                    rewrite_via
                    rewrite_contact
                    strip_headers P-Preferred-Identity P-Asserted-Identity Server User-Agent
                    hide_private_ips
                    # anonymize_call_id  # Optional: randomize Call-IDs
                }

                proxy udp/freepbx:5060
            }
        }

        # TCP SIP
        tcp/:5060 {
            @sip sip
            route @sip {
                sip_guardian { ... }
                proxy tcp/freepbx:5060
            }
        }

        # SIP over TLS
        tcp/:5061 {
            @sip tls sni sip.example.com
            route @sip {
                sip_guardian { ... }
                tls
                proxy tcp/freepbx:5060
            }
        }
    }
}

# Admin API
:2020 {
    handle /api/sip-guardian/* {
        sip_guardian_admin
    }

    # Prometheus metrics endpoint
    handle /metrics {
        metrics
    }
}

Environment Variables

Variable Default Description
SIP_UPSTREAM_HOST freepbx Upstream SIP server hostname
SIP_UPSTREAM_PORT 5060 Upstream SIP port
SIP_GUARDIAN_MAX_FAILURES 5 Failures before ban
SIP_GUARDIAN_FIND_TIME 10m Time window for counting failures
SIP_GUARDIAN_BAN_TIME 1h Ban duration

Feature Details

Extension Enumeration Detection

Protects against tools like SIPVicious svwar that scan for valid extensions:

enumeration {
    max_extensions 20        # Ban after 20 unique extensions probed
    extension_window 5m      # Within this time window
    sequential_threshold 5   # Ban if 5+ consecutive extensions (100,101,102...)
    rapid_fire_count 10      # Ban if 10+ extensions in rapid_fire_window
    rapid_fire_window 30s
    ban_time 2h              # Enumeration bans last longer
    exempt_extensions 100 200 9999  # Don't count these (voicemail, etc.)
}

Detection Methods:

  1. Count Threshold: Too many unique extensions from one IP
  2. Sequential Pattern: Consecutive numeric extensions indicate scanning
  3. Rapid Fire: High-speed probing is clearly automated

SIP Message Validation

Enforces RFC 3261 compliance and blocks malformed/malicious packets:

validation {
    enabled true
    mode strict              # permissive, strict, or paranoid
    max_message_size 65535   # Reject oversized messages
    ban_on_null_bytes true   # Immediate ban for NULL byte injection
    ban_on_binary_injection true
    disabled_rules via_invalid_branch  # Skip specific rules
}

Validation Modes:

  • Permissive: Log violations, only block critical attacks
  • Strict: Enforce RFC 3261 required headers
  • Paranoid: Additional heuristics for edge cases

Validation Rules:

Rule Severity Action
null_bytes CRITICAL Immediate ban
binary_injection CRITICAL Immediate ban
missing_via HIGH Count toward ban
missing_from HIGH Count toward ban
missing_to HIGH Count toward ban
missing_call_id HIGH Count toward ban
missing_cseq HIGH Count toward ban
content_length_mismatch HIGH Count toward ban
oversized_message HIGH Count toward ban
invalid_request_uri MEDIUM Reject only

Topology Hiding

Hide your internal infrastructure from external attackers:

sip_topology_hider {
    # Your public-facing address
    proxy_host 203.0.113.1
    proxy_port 5060

    # Internal PBX (never exposed)
    upstream udp/192.168.1.100:5060

    # Enable Via header insertion
    rewrite_via

    # Replace internal Contact URIs with proxy address
    rewrite_contact

    # Remove headers that leak internal info
    strip_headers P-Preferred-Identity P-Asserted-Identity Remote-Party-ID Server User-Agent X-Asterisk-HangupCause

    # Replace RFC 1918 addresses in all headers
    hide_private_ips

    # Optional: Randomize Call-IDs (prevents dialog correlation)
    # anonymize_call_id
}

What It Hides:

  • Internal IP addresses (192.168.x.x, 10.x.x.x, 172.16-31.x.x)
  • Via header chain revealing internal proxies
  • Contact URIs pointing to internal hosts
  • Server/User-Agent revealing software versions
  • P-Asserted-Identity revealing internal extensions

Request Flow:

External UA → Caddy → Asterisk
              │
              └─ Adds Via: SIP/2.0/UDP proxy.example.com;branch=z9hG4bK...
              └─ Rewrites Contact: <sip:proxy.example.com:5060>
              └─ Strips: Server, P-Asserted-Identity

Response Flow:

Asterisk → Caddy → External UA
           │
           └─ Removes top Via (proxy's)
           └─ Dialog state routes response correctly

Admin API

List Banned IPs

curl http://localhost:2020/api/sip-guardian/bans

View Stats

curl http://localhost:2020/api/sip-guardian/stats

Response:

{
  "total_requests": 15234,
  "blocked_requests": 423,
  "active_bans": 12,
  "enumeration_detections": 5,
  "validation_failures": 89,
  "rate_limited": 156
}

Manually Ban IP

curl -X POST http://localhost:2020/api/sip-guardian/ban/192.168.1.100 \
    -H "Content-Type: application/json" \
    -d '{"reason": "manual_ban", "duration": "24h"}'

Unban IP

curl -X DELETE http://localhost:2020/api/sip-guardian/unban/192.168.1.100

View Enumeration Stats

curl http://localhost:2020/api/sip-guardian/enumeration/stats

View Validation Stats

curl http://localhost:2020/api/sip-guardian/validation/stats

Prometheus Metrics

# Core metrics
sip_guardian_requests_total{method="REGISTER"}
sip_guardian_blocked_total{reason="banned"}
sip_guardian_active_bans

# Rate limiting
sip_guardian_rate_limited_total{method="INVITE"}

# Enumeration detection
sip_guardian_enumeration_detections_total{reason="sequential_pattern"}
sip_guardian_enumeration_tracked_ips

# Validation
sip_guardian_validation_violations_total{rule="missing_via"}
sip_guardian_validation_results_total{result="valid"}
sip_guardian_message_size_bytes

# GeoIP
sip_guardian_geoip_blocked_total{country="CN"}

Detected Attack Patterns

The module automatically detects and flags:

  • SIPVicious (sipvicious, friendly-scanner)
  • SIPScan (sip-scan, sipcli)
  • Asterisk scanners (Asterisk PBX)
  • Common test extensions (100, 1000, 9999)
  • Sequential extension probing
  • NULL byte injection
  • Binary payload injection

Building from Source

# Using xcaddy
xcaddy build \
    --with github.com/mholt/caddy-l4 \
    --with git.supported.systems/rsp2k/caddy-sip-guardian

# Or with local development
xcaddy build \
    --with github.com/mholt/caddy-l4 \
    --with git.supported.systems/rsp2k/caddy-sip-guardian=/path/to/local/module

Testing

# Run all unit tests
make test

# Test enumeration detection
make test-enumeration

# Test validation
make test-validation

# Test with SIPVicious (in sandbox)
make sandbox-up
make test-scanner

Integration Examples

With FreePBX/Asterisk

{
    layer4 {
        udp/:5060 {
            @sip sip
            route @sip {
                sip_guardian {
                    max_failures 3
                    ban_time 24h
                    whitelist 10.0.0.0/8
                }
                proxy udp/freepbx:5060
            }
        }
    }
}

With Kamailio (as SBC)

{
    layer4 {
        udp/:5060 {
            @sip sip
            route @sip {
                sip_guardian { ... }
                sip_topology_hider {
                    proxy_host sbc.example.com
                    proxy_port 5060
                    upstream udp/kamailio:5060
                    rewrite_via
                    rewrite_contact
                }
                proxy udp/kamailio:5060
            }
        }
    }
}

High Availability Setup

{
    layer4 {
        udp/:5060 {
            @sip sip
            route @sip {
                sip_guardian {
                    storage {
                        # Shared storage for HA
                        path /shared/sip_guardian.db
                    }
                }
                # Load balance across PBX cluster
                proxy udp/pbx1:5060 udp/pbx2:5060 udp/pbx3:5060 {
                    lb_policy round_robin
                    health_check interval=30s
                }
            }
        }
    }
}

Security Considerations

  1. Whitelist Internal Networks: Always whitelist your internal networks to prevent self-blocking
  2. Start Permissive: Begin with permissive validation mode and tighten after monitoring
  3. Monitor False Positives: Watch metrics for legitimate traffic being blocked
  4. Regular Updates: Keep GeoIP databases current
  5. Webhook Alerts: Configure webhooks for immediate security event notification

License

MIT

Contributing

Contributions welcome! Please see CONTRIBUTING.md for guidelines.

  • caddy-l4 - Layer 4 proxy for Caddy
  • Caddy - The HTTP/2 web server with automatic HTTPS
  • SIPVicious - SIP security testing tools