HTTP & WebSocket Protocol Guard (http)
The HTTP Protocol Guard plugin provides high-performance Layer 7 request inspection for HTTP/1.x streams. It validates the Host header, filters malicious vulnerability scanners via User-Agent patterns, blocks sensitive path traversal and file probing (.env, .git, /admin), and seamlessly upgrades connections to full-duplex transparent proxying when WebSocket headers (Upgrade: websocket) are detected.
Capabilities & Threat Defense
| Threat / Attack Vector | Defense Mechanism | Action Taken |
|---|---|---|
| Vulnerability Scanners | Regex matching on User-Agent (sqlmap, nikto, masscan) | Connection terminated with 403 Forbidden |
| Sensitive File Probing | Regex path inspection (\.(env|git|bak|sql)$, ^/admin) | Immediate 403 Forbidden response |
| Host Header Injection | Host header whitelist validation | Rejection with 400 Bad Request |
| WebSocket Connections | Detects Upgrade: websocket and 101 Switching Protocols | Upgrades stream to zero-copy bidirectional pipe |
Installation
Install the plugin via CLI or declaratively:
# Install using short nametcp-warden plugins install http# Or install via Git repository URLtcp-warden plugins install https://github.com/routewarden/plugins/httpConfiguration Reference
Add an HTTP guard service to tcp-warden.yaml:
services: web_guard: listen: ":8081" upstream: "127.0.0.1:80" protocol: "http" rate_limit: connections_per_minute: 120 burst: 20 plugin_config: allowed_hosts: - "api.example.com" - "app.example.com" blocked_paths: - "^/admin(/.*)?$" - "\.(env|git|bak|sql|config)$" - "/wp-admin" blocked_headers: User-Agent: "(?i)(sqlmap|nikto|acunetix|masscan|zgrab)" X-Forwarded-Host: ".*"Configuration Options
| Field | Type | Default | Description |
|---|---|---|---|
listen | string | ":8081" | Local proxy listen address and port. |
upstream | string | "127.0.0.1:80" | Target HTTP server address and port. |
protocol | string | "http" | Must be set to "http". |
plugin_config.allowed_hosts | []string | [] | Optional list of allowed Host headers. If set, unlisted hosts are rejected. |
plugin_config.blocked_paths | []string | [...] | List of regular expressions matching forbidden request URIs. |
plugin_config.blocked_headers | map[string]string | {...} | Map of header names to regex patterns that trigger instant rejection. |
Network & Deployment Architecture
Option A: Kernel Firewall Redirection (nftables / iptables)
Redirect incoming external traffic on port 80 to RouteWarden port 8081:
# Redirect incoming external traffic on port 80 to RouteWarden port 8081sudo nft add rule ip routewarden_nat prerouting iifname "eth0" tcp dport 80 redirect to :8081Option B: Docker Compose Network Isolation
Run the web server inside an isolated container network, exposing web traffic (HTTP :80 and HTTPS :443) only through RouteWarden:
services: routewarden: image: ghcr.io/routewarden/tcp-warden:latest ports: - "80:8081" # Map host HTTP port 80 to RouteWarden - "443:8443" # Map host HTTPS port 443 to RouteWarden - "9091:9091" # Management API volumes: - ./tcp-warden.yaml:/etc/routewarden/tcp-warden.yaml:ro depends_on: - web web: image: nginx:alpine # Do NOT publish host ports (80/443); keep internal to bridge networkTesting & Verification
Verify requests, check User-Agent filtering, and test path protection:
# Verify legitimate HTTP requestcurl -I -H "Host: api.example.com" http://127.0.0.1:8081/health# Returns: HTTP/1.1 200 OK