Complete security configuration with WAF, authentication, rate limiting, and security headers.
Use Case
- Protect against OWASP Top 10 attacks
- Authenticate and authorize requests
- Rate limit to prevent abuse
- Add security headers
Architecture
┌─────────────────┐
│ Sentinel │
└────────┬────────┘
│
┌────────────────────────┼────────────────────────┐
│ │ │
▼ ▼ ▼
┌───────────┐ ┌───────────┐ ┌───────────┐
│ WAF │ │ Auth │ │Rate Limit │
│ Agent │ │ Agent │ │ Agent │
└───────────┘ └───────────┘ └───────────┘
Configuration
Create sentinel.kdl:
// Security Configuration
// WAF, authentication, and rate limiting
server {
worker-threads 0
graceful-shutdown-timeout-secs 30
}
listeners {
listener "https" {
address "0.0.0.0:8443"
protocol "https"
tls {
cert-file "/etc/sentinel/certs/api.crt"
key-file "/etc/sentinel/certs/api.key"
min-version "1.2"
ciphers [
"TLS_AES_256_GCM_SHA384"
"TLS_CHACHA20_POLY1305_SHA256"
"TLS_AES_128_GCM_SHA256"
]
}
}
listener "http" {
address "0.0.0.0:8080"
protocol "http"
redirect-https true
}
}
routes {
// Health check - no security
route "health" {
priority 1000
matches { path "/health" }
service-type "builtin"
builtin-handler "health"
}
// Public endpoints - WAF only, no auth
route "public" {
priority 500
matches {
path-prefix "/public/"
}
agents ["waf" "ratelimit"]
upstream "backend"
policies {
response-headers {
set {
"X-Content-Type-Options" "nosniff"
"X-Frame-Options" "DENY"
"X-XSS-Protection" "1; mode=block"
"Strict-Transport-Security" "max-age=31536000; includeSubDomains"
"Content-Security-Policy" "default-src 'self'"
"Referrer-Policy" "strict-origin-when-cross-origin"
"Permissions-Policy" "geolocation=(), microphone=(), camera=()"
}
remove "Server" "X-Powered-By"
}
}
}
// API endpoints - full security
route "api" {
priority 200
matches {
path-prefix "/api/"
}
agents ["waf" "auth" "ratelimit"]
upstream "backend"
service-type "api"
policies {
timeout-secs 30
max-body-size "10MB"
buffer-requests true // Required for WAF body inspection
response-headers {
set {
"X-Content-Type-Options" "nosniff"
"X-Frame-Options" "DENY"
"Cache-Control" "no-store"
}
remove "Server" "X-Powered-By"
}
}
error-pages {
default-format "json"
}
}
// Admin endpoints - strict security
route "admin" {
priority 300
matches {
path-prefix "/admin/"
}
agents ["waf" "auth" "ratelimit-strict"]
upstream "backend"
policies {
failure-mode "closed"
request-headers {
set { "X-Admin-Request" "true" }
}
}
}
}
upstreams {
upstream "backend" {
targets {
target { address "127.0.0.1:3000" }
}
health-check {
type "http" { path "/health" }
interval-secs 10
}
}
}
agents {
// Web Application Firewall
agent "waf" {
transport "unix_socket" {
path "/var/run/sentinel/waf.sock"
}
events ["request_headers" "request_body"]
timeout-ms 100
failure-mode "closed"
}
// Authentication
agent "auth" {
transport "unix_socket" {
path "/var/run/sentinel/auth.sock"
}
events ["request_headers"]
timeout-ms 50
failure-mode "closed"
}
// Standard rate limiting
agent "ratelimit" {
transport "unix_socket" {
path "/var/run/sentinel/ratelimit.sock"
}
events ["request_headers"]
timeout-ms 20
failure-mode "open"
}
// Strict rate limiting for admin
agent "ratelimit-strict" {
transport "unix_socket" {
path "/var/run/sentinel/ratelimit-strict.sock"
}
events ["request_headers"]
timeout-ms 20
failure-mode "closed"
}
}
observability {
metrics {
enabled true
address "0.0.0.0:9090"
}
logging {
level "info"
format "json"
}
}
Agent Setup
Install Agents
Start WAF Agent
&
Start Auth Agent
# JWT authentication
&
Start Rate Limit Agents
# Standard: 100 req/min
&
# Strict: 10 req/min for admin
&
Testing
Test WAF - SQL Injection
Expected response:
HTTP/1.1 403 Forbidden
X-WAF-Blocked: true
X-WAF-Rule: 942100
{"error": "Request blocked by WAF"}
Test WAF - XSS
Expected response:
HTTP/1.1 403 Forbidden
X-WAF-Blocked: true
X-WAF-Rule: 941100
Test Authentication
# Without token - should fail
# With valid token
TOKEN=
Test Rate Limiting
# Send 150 requests rapidly
for; do
done | |
Expected output shows 429 responses after limit.
Test Security Headers
Expected headers:
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Content-Security-Policy: default-src 'self'
Advanced Configurations
OWASP ModSecurity CRS
For full OWASP CRS support, use the ModSecurity agent:
# Install ModSecurity agent
# Download OWASP CRS
# Start ModSecurity agent
&
API Key Authentication
&
Create /etc/sentinel/api-keys.json:
IP-Based Rate Limiting
&
IP Denylist
&
Security Metrics
Key security metrics to monitor:
# WAF blocks per rule
sum by (rule) (rate(sentinel_agent_waf_blocks_total[5m]))
# Auth failures
rate(sentinel_agent_auth_failures_total[5m])
# Rate limit hits
rate(sentinel_agent_ratelimit_limited_total[5m])
# Blocked requests (all agents)
sum(rate(sentinel_requests_total{blocked="true"}[5m]))
Incident Response
Block Specific IP
# Add to denylist
# Reload denylist agent
Enable Detect-Only Mode
For investigating false positives without blocking:
& # Detect only, don't block
Check logs for X-WAF-Detected headers.
Next Steps
- Observability - Monitor security events
- API Gateway - Complete API management
- Microservices - Secure service mesh