WebSocket proxying with frame inspection, security controls, and real-time monitoring.
Use Case
- Proxy WebSocket connections to backend services
- Inspect and filter WebSocket frames
- Rate limit connections and messages
- Detect attacks in WebSocket traffic
Configuration
Create sentinel.kdl:
// WebSocket Configuration
// Real-time WebSocket proxying with security
server {
worker-threads 0
graceful-shutdown-timeout-secs 60
}
listeners {
listener "https" {
address "0.0.0.0:8443"
protocol "https"
tls {
cert-file "/etc/sentinel/certs/ws.crt"
key-file "/etc/sentinel/certs/ws.key"
}
}
listener "http" {
address "0.0.0.0:8080"
protocol "http"
}
}
routes {
// Health check
route "health" {
priority 1000
matches { path "/health" }
service-type "builtin"
builtin-handler "health"
}
// WebSocket endpoint
route "websocket" {
priority 200
matches {
path "/ws"
}
upstream "ws-backend"
agents ["ws-inspector"]
websocket {
enabled true
ping-interval-secs 30
ping-timeout-secs 10
max-message-size "1MB"
}
}
// Socket.io endpoint
route "socketio" {
priority 200
matches {
path-prefix "/socket.io/"
}
upstream "ws-backend"
agents ["ws-inspector"]
websocket {
enabled true
}
}
// REST API (same backend)
route "api" {
priority 100
matches {
path-prefix "/api/"
}
upstream "ws-backend"
agents ["auth"]
}
}
upstreams {
upstream "ws-backend" {
targets {
target { address "127.0.0.1:3000" }
}
health-check {
type "http" { path "/health" }
interval-secs 10
}
}
}
agents {
agent "ws-inspector" {
transport "unix_socket" {
path "/var/run/sentinel/ws-inspector.sock"
}
events ["websocket_frame"]
timeout-ms 50
failure-mode "open"
}
agent "auth" {
transport "unix_socket" {
path "/var/run/sentinel/auth.sock"
}
events ["request_headers"]
timeout-ms 50
failure-mode "closed"
}
}
observability {
metrics {
enabled true
address "0.0.0.0:9090"
}
logging {
level "info"
format "json"
}
}
Agent Setup
Install WebSocket Inspector
Start WebSocket Inspector
&
Configuration Options
| Option | Default | Description |
|---|---|---|
--xss-detection | true | Detect XSS in text frames |
--sqli-detection | true | Detect SQL injection |
--command-injection | true | Detect command injection |
--max-message-size | 1048576 | Max message size (bytes) |
--rate-limit-messages | 0 | Messages per second (0=unlimited) |
--block-mode | true | Block or detect-only |
--json-schema | - | Validate JSON against schema |
Testing
Basic WebSocket Connection
# Using websocat
# Or with wscat
Test with JavaScript
;
ws.onopen =;
ws.onmessage =;
ws.onerror =;
Test XSS Detection
|
Expected: Connection closed with code 1008 (Policy Violation)
Test Rate Limiting
// Send 200 messages rapidly
for ; i < 200; i++
// Expect connection closed after rate limit exceeded
Authentication
Token in Query String
routes {
route "websocket" {
matches {
path "/ws"
query-param name="token"
}
agents ["auth" "ws-inspector"]
upstream "ws-backend"
}
}
Client connection:
;
Token in Subprotocol
;
Cookie-Based Auth
routes {
route "websocket" {
matches {
path "/ws"
header name="Cookie"
}
agents ["auth" "ws-inspector"]
upstream "ws-backend"
}
}
Socket.io Support
Sentinel supports Socket.io’s WebSocket transport:
;
;
'connect',;
JSON Schema Validation
Validate WebSocket messages against a JSON Schema:
&
Create /etc/sentinel/ws-schema.json:
Connection Limits
routes {
route "websocket" {
upstream "ws-backend"
websocket {
enabled true
max-connections 1000
max-connections-per-ip 10
idle-timeout-secs 300
}
}
}
Metrics
Key WebSocket metrics:
# Active connections
sentinel_websocket_connections_active
# Messages per second
rate(sentinel_websocket_messages_total[5m])
# Connection duration
histogram_quantile(0.95, sentinel_websocket_connection_duration_seconds_bucket)
# Blocked frames
rate(sentinel_agent_ws_blocked_total[5m])
Multi-Room Chat Example
Complete configuration for a chat application:
routes {
// WebSocket for real-time messages
route "chat-ws" {
priority 200
matches {
path "/chat"
}
upstream "chat-service"
agents ["auth" "ws-inspector"]
websocket {
enabled true
ping-interval-secs 30
max-message-size "64KB"
}
}
// REST API for history, rooms, etc.
route "chat-api" {
priority 100
matches {
path-prefix "/api/chat/"
}
upstream "chat-service"
agents ["auth" "ratelimit"]
}
}
agents {
agent "ws-inspector" {
transport "unix_socket" {
path "/var/run/sentinel/ws-inspector.sock"
}
events ["websocket_frame"]
timeout-ms 20
failure-mode "open"
}
}
Next Steps
- Security - Add WAF protection
- Observability - Monitor connections
- Microservices - Multi-service WebSocket