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.
This commit is contained in:
Ryan Malloy 2025-12-07 20:40:11 -07:00
parent f76946fc41
commit f03ac453e0

478
README.md
View File

@ -1,15 +1,41 @@
# Caddy SIP Guardian
A custom Caddy module that provides SIP-aware rate limiting, IP banning, and attack detection at Layer 4.
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**: Track failed attempts per IP with configurable windows
- **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.)
- **Attack Detection**: Detect common SIP scanning tools (SIPVicious, friendly-scanner, etc.)
- **CIDR Whitelisting**: Whitelist trusted networks
- **Admin API**: RESTful API for managing bans and viewing stats
- **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
@ -17,27 +43,26 @@ A custom Caddy module that provides SIP-aware rate limiting, IP banning, and att
Internet
┌─────────────────────────────────────┐
│ Caddy SIP Guardian (Layer 4) │
│ ┌─────────────────────────────────┐│
│ │ SIP Matcher ││
│ │ - Detects SIP methods ││
│ │ - Matches REGISTER, INVITE, etc ││
│ └─────────────────────────────────┘│
│ ┌─────────────────────────────────┐│
│ │ SIP Handler ││
│ │ - Check banned IPs ││
│ │ - Check whitelists ││
│ │ - Detect attack patterns ││
│ │ - Record failures ││
│ └─────────────────────────────────┘│
└─────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 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 │
│ (Protected from scanners)
└─────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────
│ FreePBX / Asterisk / Kamailio
│ (Protected from scanners, enumeration, and topology leaks)
└─────────────────────────────────────────────────────────────
```
## Quick Start
@ -51,32 +76,252 @@ make run
# View logs
make logs
# Run tests
make test
```
## Configuration
### Complete Caddyfile Example
```caddyfile
{
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_UPSTREAM_TLS_PORT` | `5061` | Upstream SIP TLS 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 |
### Caddyfile Directives
## Feature Details
### Extension Enumeration Detection
Protects against tools like SIPVicious `svwar` that scan for valid extensions:
```caddyfile
sip_guardian {
max_failures 5 # Ban after 5 failures
find_time 10m # Within 10 minute window
ban_time 1h # Ban for 1 hour
whitelist 10.0.0.0/8 192.168.0.0/16
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:
```caddyfile
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:
```caddyfile
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
@ -89,11 +334,23 @@ curl http://localhost:2020/api/sip-guardian/bans
curl http://localhost:2020/api/sip-guardian/stats
```
Response:
```json
{
"total_requests": 15234,
"blocked_requests": 423,
"active_bans": 12,
"enumeration_detections": 5,
"validation_failures": 89,
"rate_limited": 156
}
```
### Manually Ban IP
```bash
curl -X POST http://localhost:2020/api/sip-guardian/ban/192.168.1.100 \
-H "Content-Type: application/json" \
-d '{"reason": "manual_ban"}'
-d '{"reason": "manual_ban", "duration": "24h"}'
```
### Unban IP
@ -101,15 +358,51 @@ curl -X POST http://localhost:2020/api/sip-guardian/ban/192.168.1.100 \
curl -X DELETE http://localhost:2020/api/sip-guardian/unban/192.168.1.100
```
### View Enumeration Stats
```bash
curl http://localhost:2020/api/sip-guardian/enumeration/stats
```
### View Validation Stats
```bash
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** - Popular SIP scanning tool
- **friendly-scanner** - Another common scanner
- **sipcli** - SIP command line tool
- **sip-scan** - Generic SIP scanners
- Common test extensions (100, 1000)
- **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
@ -117,19 +410,116 @@ The module automatically detects and flags:
# Using xcaddy
xcaddy build \
--with github.com/mholt/caddy-l4 \
--with github.com/mholt/caddy-ratelimit \
--with github.com/ryanmalloy/caddy-sip-guardian
--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
```
## Integration with FreePBX
## Testing
This module is designed to sit in front of FreePBX/Asterisk:
```bash
# Run all unit tests
make test
1. All SIP traffic hits Caddy first
2. Malicious traffic is blocked at the edge
3. Only legitimate traffic reaches your PBX
4. FreePBX doesn't need its own fail2ban for SIP
# 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
```caddyfile
{
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)
```caddyfile
{
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
```caddyfile
{
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.
## Related Projects
- [caddy-l4](https://github.com/mholt/caddy-l4) - Layer 4 proxy for Caddy
- [Caddy](https://caddyserver.com/) - The HTTP/2 web server with automatic HTTPS
- [SIPVicious](https://github.com/EnableSecurity/sipvicious) - SIP security testing tools