diff --git a/README.md b/README.md
index f1bd434..3b4fbc9 100644
--- a/README.md
+++ b/README.md
@@ -1,73 +1,103 @@
# 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.
+[](https://go.dev/)
+[](https://caddyserver.com/)
+[](LICENSE)
+[](https://git.supported.systems/rsp2k/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.
+
+---
+
+## Why SIP Guardian?
+
+Traditional SIP security (like fail2ban) parses logs *after* attacks reach your PBX. SIP Guardian operates at **Layer 4**, blocking threats *before* they touch your infrastructure:
+
+| Traditional Approach | SIP Guardian |
+|---------------------|--------------|
+| Log parsing delay | Real-time blocking |
+| Regex-based detection | Protocol-aware analysis |
+| Separate fail2ban config | Single Caddyfile |
+| No topology protection | Full B2BUA-lite hiding |
+| Manual IP management | Auto-ban with API control |
+
+---
## 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
+### 🛡️ 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
+### 🔍 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
+### ✅ 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
+### 🔒 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
+### 📊 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) │
-└─────────────────────────────────────────────────────────────┘
+ 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, topology leaks) │
+└──────────────────────────────────────────────────────────────────┘
```
+---
+
## Quick Start
```bash
+# Clone the repository
+git clone https://git.supported.systems/rsp2k/caddy-sip-guardian.git
+cd caddy-sip-guardian
+
# Build the custom Caddy image
make build
@@ -77,13 +107,38 @@ make run
# View logs
make logs
-# Run tests
+# Run tests (60 tests)
make test
```
+---
+
## Configuration
-### Complete Caddyfile Example
+### Minimal Configuration
+
+```caddyfile
+{
+ layer4 {
+ udp/:5060 {
+ @sip sip
+ route @sip {
+ sip_guardian {
+ max_failures 5
+ ban_time 1h
+ whitelist 10.0.0.0/8 192.168.0.0/16
+ }
+ proxy udp/asterisk:5060
+ }
+ }
+ }
+}
+```
+
+### Full Configuration
+
+
+Click to expand complete Caddyfile example
```caddyfile
{
@@ -201,6 +256,8 @@ make test
}
```
+
+
### Environment Variables
| Variable | Default | Description |
@@ -211,6 +268,8 @@ make test
| `SIP_GUARDIAN_FIND_TIME` | `10m` | Time window for counting failures |
| `SIP_GUARDIAN_BAN_TIME` | `1h` | Ban duration |
+---
+
## Feature Details
### Extension Enumeration Detection
@@ -230,9 +289,14 @@ enumeration {
```
**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
+
+| Method | Trigger | Use Case |
+|--------|---------|----------|
+| **Count Threshold** | 20+ unique extensions | Catches slow scanners |
+| **Sequential Pattern** | 5+ consecutive numbers | Detects `svwar` immediately |
+| **Rapid Fire** | 10+ in 30 seconds | Catches fast automated scans |
+
+---
### SIP Message Validation
@@ -250,23 +314,29 @@ validation {
```
**Validation Modes:**
-- **Permissive**: Log violations, only block critical attacks
-- **Strict**: Enforce RFC 3261 required headers
-- **Paranoid**: Additional heuristics for edge cases
+
+| Mode | Behavior |
+|------|----------|
+| **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 |
+| `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
@@ -281,60 +351,87 @@ sip_topology_hider {
# 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
+ rewrite_via # Add proxy Via, remove on response
+ rewrite_contact # Replace internal Contact URIs
+ strip_headers P-Preferred-Identity P-Asserted-Identity Server User-Agent
+ hide_private_ips # Replace RFC 1918 addresses
+ # anonymize_call_id # Optional: randomize Call-IDs
}
```
**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
+
+| Header/Field | Before | After |
+|--------------|--------|-------|
+| Via | `192.168.1.100:5060` | `proxy.example.com:5060` |
+| Contact | `` | `` |
+| Server | `Asterisk PBX 18.x` | *(removed)* |
+| P-Asserted-Identity | `` | *(removed)* |
**Request Flow:**
```
-External UA → Caddy → Asterisk
- │
- └─ Adds Via: SIP/2.0/UDP proxy.example.com;branch=z9hG4bK...
- └─ Rewrites Contact:
- └─ Strips: Server, P-Asserted-Identity
+External UA ──────► Caddy ──────► Asterisk
+ │
+ ├─ Adds Via: SIP/2.0/UDP proxy.example.com;branch=z9hG4bK...
+ ├─ Rewrites Contact:
+ └─ Strips: Server, P-Asserted-Identity
```
**Response Flow:**
```
-Asterisk → Caddy → External UA
- │
- └─ Removes top Via (proxy's)
- └─ Dialog state routes response correctly
+Asterisk ──────► Caddy ──────► External UA
+ │
+ ├─ Removes top Via (proxy's)
+ └─ Dialog state routes response correctly
```
+---
+
## Admin API
-### List Banned IPs
+### Endpoints
+
+| Method | Endpoint | Description |
+|--------|----------|-------------|
+| `GET` | `/api/sip-guardian/bans` | List all banned IPs |
+| `GET` | `/api/sip-guardian/stats` | View statistics |
+| `POST` | `/api/sip-guardian/ban/{ip}` | Manually ban an IP |
+| `DELETE` | `/api/sip-guardian/unban/{ip}` | Remove IP from ban list |
+| `GET` | `/api/sip-guardian/enumeration/stats` | Enumeration statistics |
+| `GET` | `/api/sip-guardian/validation/stats` | Validation statistics |
+
+### Examples
+
+
+List Banned IPs
+
```bash
curl http://localhost:2020/api/sip-guardian/bans
```
-### View Stats
+```json
+{
+ "bans": [
+ {
+ "ip": "185.224.128.0",
+ "reason": "scanner_detected",
+ "banned_at": "2024-01-15T10:30:00Z",
+ "expires_at": "2024-01-15T11:30:00Z"
+ }
+ ],
+ "total": 1
+}
+```
+
+
+
+
+View Stats
+
```bash
curl http://localhost:2020/api/sip-guardian/stats
```
-Response:
```json
{
"total_requests": 15234,
@@ -346,31 +443,33 @@ Response:
}
```
-### Manually Ban IP
+
+
+
+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", "duration": "24h"}'
```
-### Unban IP
+
+
+
+Unban IP
+
```bash
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
-```
+```prometheus
# Core metrics
sip_guardian_requests_total{method="REGISTER"}
sip_guardian_blocked_total{reason="banned"}
@@ -392,52 +491,13 @@ sip_guardian_message_size_bytes
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
-
-```bash
-# 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
-
-```bash
-# 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
+
+FreePBX / Asterisk
+
```caddyfile
{
layer4 {
@@ -456,14 +516,21 @@ make test-scanner
}
```
-### With Kamailio (as SBC)
+
+
+
+Kamailio (as SBC)
+
```caddyfile
{
layer4 {
udp/:5060 {
@sip sip
route @sip {
- sip_guardian { ... }
+ sip_guardian {
+ max_failures 5
+ ban_time 1h
+ }
sip_topology_hider {
proxy_host sbc.example.com
proxy_port 5060
@@ -478,7 +545,11 @@ make test-scanner
}
```
-### High Availability Setup
+
+
+
+High Availability Setup
+
```caddyfile
{
layer4 {
@@ -502,24 +573,206 @@ make test-scanner
}
```
+
+
+---
+
+## Troubleshooting
+
+### Common Issues
+
+
+Legitimate users getting banned
+
+**Symptoms:** Users report being unable to connect; they appear in ban list.
+
+**Solutions:**
+1. Add their network to the whitelist:
+ ```caddyfile
+ whitelist 10.0.0.0/8 192.168.0.0/16 YOUR.NETWORK.0.0/16
+ ```
+2. Increase `max_failures` threshold
+3. Check if their client sends malformed packets (validation logs)
+4. Temporarily unban: `curl -X DELETE http://localhost:2020/api/sip-guardian/unban/IP`
+
+
+
+
+SIP traffic not being matched
+
+**Symptoms:** Traffic passes through but SIP Guardian doesn't process it.
+
+**Solutions:**
+1. Verify the matcher syntax:
+ ```caddyfile
+ @sip sip {
+ methods REGISTER INVITE OPTIONS
+ }
+ ```
+2. Check Caddy logs for matcher errors
+3. Ensure traffic is arriving on the correct port (UDP vs TCP)
+4. Test with `tcpdump -i any port 5060` to verify traffic flow
+
+
+
+
+Topology hiding breaks calls
+
+**Symptoms:** Calls connect but audio is one-way or missing.
+
+**Solutions:**
+1. This is usually an RTP/media issue, not SIP signaling
+2. Ensure RTP ports are forwarded through your firewall
+3. Check if `hide_private_ips` is replacing IPs in SDP body
+4. Verify NAT traversal settings on your PBX
+
+
+
+
+High memory usage
+
+**Symptoms:** Caddy process memory grows over time.
+
+**Solutions:**
+1. Dialog/transaction state cleanup runs automatically, but check TTL settings
+2. Reduce `extension_window` to clean up enumeration tracking faster
+3. Check for memory leaks with `go tool pprof`
+4. Ensure cleanup goroutines are running (check logs)
+
+
+
+
+GeoIP database not loading
+
+**Symptoms:** Country blocking not working; errors about mmdb file.
+
+**Solutions:**
+1. Download the database:
+ ```bash
+ wget https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-Country&suffix=tar.gz
+ ```
+2. Verify path in config matches actual file location
+3. Check file permissions (Caddy needs read access)
+4. Ensure you're using GeoLite2-Country, not City database
+
+
+
+### Debug Mode
+
+Enable verbose logging:
+
+```caddyfile
+{
+ debug
+ layer4 {
+ # ... your config
+ }
+}
+```
+
+Check logs:
+```bash
+docker logs caddy-sip-guardian 2>&1 | grep -E "(sip_guardian|topology)"
+```
+
+---
+
+## Building from Source
+
+```bash
+# 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
+```
+
+### Running Tests
+
+```bash
+# Run all unit tests (60 tests)
+make test
+
+# Run with verbose output
+docker run --rm -v $(pwd):/app -w /app golang:1.25 go test -v ./...
+
+# Test specific feature
+go test -v -run TestEnumeration ./...
+go test -v -run TestValidation ./...
+go test -v -run TestTopology ./...
+```
+
+---
+
+## Changelog
+
+### v0.3.0 (2024-12)
+- ✨ **Topology Hiding** — B2BUA-lite functionality for hiding internal infrastructure
+- ✨ **SIP Message Parsing** — Full RFC 3261 compliant parser with header manipulation
+- ✨ **Dialog State Management** — Stateful response routing for topology hiding
+- 🐛 Fixed PRNG overflow in branch generation
+
+### v0.2.0 (2024-12)
+- ✨ **SIP Message Validation** — RFC 3261 compliance checking
+- ✨ **Injection Detection** — NULL byte and binary injection blocking
+- ✨ **Validation Modes** — Permissive, strict, and paranoid modes
+
+### v0.1.0 (2024-12)
+- ✨ **Extension Enumeration Detection** — Sequential pattern and rapid-fire detection
+- ✨ **Per-method Rate Limiting** — Token bucket with configurable burst
+- ✨ **GeoIP Blocking** — Country-based blocking with MaxMind
+- ✨ **Prometheus Metrics** — Comprehensive observability
+- ✨ **Webhook Notifications** — Real-time security alerts
+- ✨ **SQLite Persistence** — Durable ban storage
+
+---
+
## 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
+| Consideration | Recommendation |
+|---------------|----------------|
+| **Whitelist internal networks** | Always add your LAN to prevent self-blocking |
+| **Start permissive** | Begin with permissive validation, tighten after monitoring |
+| **Monitor false positives** | Watch metrics for legitimate traffic being blocked |
+| **Keep GeoIP updated** | Refresh MaxMind databases monthly |
+| **Use webhooks** | Configure alerts for immediate security notification |
+| **Protect admin API** | Don't expose `:2020` to the internet |
+
+---
+
+## Detected Attack Patterns
+
+SIP Guardian automatically detects:
+
+| Pattern | Detection Method |
+|---------|------------------|
+| **SIPVicious** | User-Agent fingerprinting |
+| **friendly-scanner** | User-Agent fingerprinting |
+| **sipcli / sip-scan** | User-Agent fingerprinting |
+| **Sequential scanning** | Extension pattern analysis |
+| **NULL byte injection** | Binary content inspection |
+| **Malformed packets** | RFC 3261 validation |
+
+---
## License
-MIT
+MIT — see [LICENSE](LICENSE) for details.
## Contributing
-Contributions welcome! Please see CONTRIBUTING.md for guidelines.
+Contributions welcome! Please:
+1. Fork the repository
+2. Create a feature branch
+3. Add tests for new functionality
+4. Submit a pull request
## 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
+- [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 (for testing your setup)