What is RhinoWAF?
RhinoWAF is a self-hosted web application firewall written in Go. It protects applications at the application layer (L7) from common attacks, bot traffic, and abuse.
Important Notes
Layer 7 Protection: RhinoWAF handles application-layer (L7) protection including SQL injection, XSS, bot detection, and rate limiting. For volumetric network DDoS attacks (100gbps+ floods at L3/L4), you need upstream mitigation like Cloudflare or ISP-level protection.
Key Features
- DDoS protection with rate limiting and Slowloris detection
- Browser fingerprinting for bot network detection
- Challenge system (JavaScript, Proof-of-Work, hCaptcha, Turnstile)
- HTTP smuggling detection (17 violation types)
- CSRF protection with multiple patterns
- Full IPv6 support with dual-stack operation
- Advanced IP management (119+ config fields)
- GeoIP and ASN-based blocking
Installation
Build from Source
git clone https://github.com/1rhino2/RhinoWAF.git
cd RhinoWAF
make build
./rhinowaf
Or Download Source Release
curl -LO https://github.com/1rhino2/RhinoWAF/archive/refs/tags/v1.1.0.tar.gz
tar -xzf v1.1.0.tar.gz
cd RhinoWAF-1.1.0
make build
./rhinowaf
Docker
docker build -t rhinowaf .
docker run -d -p 8080:8080 \
-v $(pwd)/config:/app/config \
-v $(pwd)/logs:/app/logs \
--name rhinowaf \
rhinowaf
Kubernetes
See installation guide for Kubernetes deployment examples.
Create /etc/systemd/system/rhinowaf.service:
[Unit]
Description=RhinoWAF Web Application Firewall
After=network.target
[Service]
Type=simple
User=rhinowaf
WorkingDirectory=/opt/rhinowaf
ExecStart=/usr/local/bin/rhinowaf
Restart=on-failure
[Install]
WantedBy=multi-user.target
sudo systemctl enable rhinowaf
sudo systemctl start rhinowaf
sudo systemctl status rhinowaf
Configuration
Configuration Files
config/features.json- Main feature toggles and WAF policiesconfig/ip_rules.json- IP whitelist/blacklist rulesconfig/geoip.json- GeoIP database for country blocking
Main Configuration
Edit cmd/rhinowaf/main.go for core settings:
// Challenge System
challengeConfig := challenge.Config{
Enabled: true,
DefaultType: challenge.TypeJavaScript,
Difficulty: 5,
WhitelistPaths: []string{"/static/"},
}
// Fingerprinting
fingerprintConfig := fingerprint.Config{
Enabled: true,
MaxIPsPerFingerprint: 5,
BlockOnExceed: true,
RequireClientData: true,
}
IP Rules
Example config/ip_rules.json:
{
"banned_ips": [
{
"ip": "203.0.113.42",
"type": "ban",
"reason": "Repeated attacks"
}
],
"whitelisted_ips": [
{
"ip": "10.0.0.1",
"type": "whitelist",
"whitelist_override": true
}
],
"global_rules": {
"max_requests_per_ip": 100,
"max_connections_per_ip": 10,
"block_tor": true,
"block_proxies": true
}
}
Feature Documentation
Challenge System
Multiple verification methods to ensure legitimate users:
- JavaScript Challenge: Basic bot filtering with 2-second delay
- Proof-of-Work: Computational puzzle (configurable difficulty 1-6)
- hCaptcha: Privacy-focused CAPTCHA (requires API keys)
- Turnstile: Cloudflare's invisible challenge
Setup hCaptcha/Turnstile:
export HCAPTCHA_SITE_KEY="your-site-key"
export HCAPTCHA_SECRET="your-secret"
export TURNSTILE_SITE_KEY="your-site-key"
export TURNSTILE_SECRET="your-secret"
Browser Fingerprinting
Detects bot networks by tracking browser characteristics:
- Canvas fingerprint (unique rendering signature)
- WebGL fingerprint (GPU vendor and renderer)
- Font detection via canvas measurement
- Hardware info (CPU cores, memory, screen)
- Blocks when multiple IPs share fingerprints
Configuration:
fingerprintConfig := fingerprint.Config{
MaxIPsPerFingerprint: 5, // Max IPs per fingerprint
SuspiciousThreshold: 3, // Flag at 3+ IPs
BlockOnExceed: true, // Block when exceeded
RequireClientData: true, // Require canvas/WebGL
}
HTTP Smuggling Detection
Detects 17 types of smuggling attacks:
- CL.TE and TE.CL conflicts
- Multiple Content-Length headers
- Obfuscated headers
- Invalid protocol versions
Automatic protection enabled by default.
CSRF Protection
Two protection patterns available:
- Server-side validation: Tokens stored in memory
- Double-submit cookie: Stateless pattern
Get CSRF token: GET /csrf/token
IPv6 Support
Full dual-stack operation:
- IPv6 address parsing and validation
- CIDR matching for IPv6 ranges
- Private range detection (ULA, link-local)
- IPv6-aware rate limiting
- Performance: 43.98ns per IPv6 check
IP Management
Advanced control with 119+ fields per IP:
- Time-based restrictions (business hours, specific days)
- Path and method controls (allow/block endpoints)
- Request pattern matching (query params, headers)
- Content controls (file types, sizes)
- Protocol requirements (HTTPS, TLS versions)
GeoIP Blocking
Country-based access control:
{
"geo_rules": [
{
"country_code": "KP",
"action": "block",
"reason": "Sanctioned country"
},
{
"country_code": "CN",
"action": "challenge",
"throttle_percent": 40
}
]
}
Production Setup
Pre-Deployment Checklist
- Review configuration in main.go
- Configure CAPTCHA API keys if using hCaptcha/Turnstile
- Set geo rules for country blocking
- Test challenge pages in browser
- Ensure log directory is writable
- Load test under expected traffic
Security Best Practices
- Use HTTPS (put WAF behind nginx/caddy with TLS)
- Rotate CAPTCHA keys periodically
- Implement log rotation
- Set up monitoring and alerts
- Regular backups of configs
- Keep RhinoWAF updated
Monitoring
Built-in Prometheus metrics at /metrics:
curl http://localhost:8080/metrics | grep rhinowaf
Check fingerprint statistics:
curl http://localhost:8080/fingerprint/stats
Performance Tuning
For high-traffic sites:
fingerprintConfig := fingerprint.Config{
MaxAgeForReuse: 72 * time.Hour, // Longer expiry
MaxIPsPerFingerprint: 20, // More lenient
}
Troubleshooting
Legitimate users being blocked
Solution: Reduce strictness
MaxIPsPerFingerprint: 10 // Increase from 5
BlockOnExceed: false // Just monitor
Bots still getting through
Solution: Increase strictness
MaxIPsPerFingerprint: 3 // Decrease
RequireClientData: true // Require canvas/WebGL
DefaultType: challenge.TypeHCaptcha // Upgrade
High CPU usage
Solution: Reduce challenge difficulty
Difficulty: 3 // Down from 5-6
DefaultType: challenge.TypeJavaScript // Lighter
CAPTCHA not working
Solution: Verify API keys
echo $HCAPTCHA_SITE_KEY
echo $HCAPTCHA_SECRET
# Restart WAF after setting keys
Port already in use
sudo lsof -i :8080
# Change port or kill conflicting process
Cannot connect to backend
curl http://localhost:3000 # Verify backend running
sudo iptables -L # Check firewall rules