RATE LIMITING - nself-org/cli GitHub Wiki
Comprehensive guide to rate limiting, DDoS protection, and abuse prevention in nself.
- Overview
- Quick Start
- Configuration
- Rate Limit Zones
- DDoS Protection Layers
- CLI Commands
- Monitoring & Alerts
- Whitelist & Blacklist
- Best Practices
- Troubleshooting
nself provides comprehensive rate limiting and DDoS protection out of the box using nginx's powerful rate limiting capabilities combined with PostgreSQL-based tracking and monitoring.
- Multi-zone rate limiting - Different limits for different endpoint types
- Token bucket algorithm - Smooth rate limiting with burst handling
- Connection limits - Prevent connection exhaustion
- Request size limits - Protect against large payload attacks
- Timeout protection - Defend against slowloris and slow POST attacks
- IP whitelist/blacklist - Bypass or block specific IPs
- Real-time monitoring - Track violations and identify attackers
- Automatic alerting - Detect suspicious patterns
- Grafana dashboards - Visualize rate limit metrics
# Initialize rate limiting database tables
nself auth rate-limit init# View current rate limits
nself auth rate-limit list
# Check rate limiting status
nself auth rate-limit status# Set GraphQL API limit to 200 requests per minute
nself auth rate-limit set graphql_api 200r/m
# Set auth endpoint limit to 5 requests per minute (stricter)
nself auth rate-limit set auth 5r/m
# Apply changes
nself build
nself restart nginx# View recent violations
nself auth rate-limit violations
# Check for alerts
nself auth rate-limit alerts
# Analyze nginx logs
nself auth rate-limit analyzeConfigure rate limits in your .env file:
# Rate Limit Configuration
RATE_LIMIT_GENERAL_RATE=10r/s # General API endpoints
RATE_LIMIT_GRAPHQL_RATE=100r/m # GraphQL API (Hasura)
RATE_LIMIT_AUTH_RATE=10r/m # Authentication endpoints
RATE_LIMIT_UPLOAD_RATE=5r/m # File uploads
RATE_LIMIT_STATIC_RATE=1000r/m # Static assets (CSS/JS/images)
RATE_LIMIT_WEBHOOK_RATE=30r/m # Webhooks
RATE_LIMIT_FUNCTIONS_RATE=50r/m # Serverless functions
RATE_LIMIT_USER_RATE=1000r/m # Per-user (authenticated requests)
# Connection Limits
CLIENT_MAX_BODY_SIZE=10M # Max request body size
CLIENT_HEADER_BUFFER_SIZE=1k # Header buffer size
LARGE_CLIENT_HEADER_BUFFERS=8k # Large header buffer
CLIENT_BODY_BUFFER_SIZE=16k # Body buffer size
# Timeout Protection
CLIENT_BODY_TIMEOUT=12s # Body read timeout
CLIENT_HEADER_TIMEOUT=12s # Header read timeout
KEEPALIVE_TIMEOUT=15s # Keep-alive timeout
SEND_TIMEOUT=10s # Send timeout-
r/s- Requests per second (e.g.,10r/s= 10 requests per second) -
r/m- Requests per minute (e.g.,100r/m= 100 requests per minute)
nself implements 8 different rate limiting zones:
Default: 10 requests/second
Purpose: Default rate limit for all API endpoints
Variable: RATE_LIMIT_GENERAL_RATE
nself auth rate-limit set general 20r/sDefault: 100 requests/minute
Purpose: Hasura GraphQL endpoint
Variable: RATE_LIMIT_GRAPHQL_RATE
Burst: 20 requests
Applied to: api.${BASE_DOMAIN}
nself auth rate-limit set graphql_api 200r/mDefault: 10 requests/minute
Purpose: Login, signup, password reset (prevents brute force)
Variable: RATE_LIMIT_AUTH_RATE
Burst: 5 requests
Applied to: auth.${BASE_DOMAIN}
nself auth rate-limit set auth 5r/mDefault: 5 requests/minute
Purpose: File upload endpoints (prevents storage abuse)
Variable: RATE_LIMIT_UPLOAD_RATE
Burst: 2 requests
Applied to: MinIO S3 API (storage.${BASE_DOMAIN})
nself auth rate-limit set uploads 10r/mDefault: 1000 requests/minute
Purpose: CSS, JavaScript, images (high throughput)
Variable: RATE_LIMIT_STATIC_RATE
Burst: 50 requests
Applied to: Static file routes
nself auth rate-limit set static 2000r/mDefault: 30 requests/minute
Purpose: Incoming webhooks
Variable: RATE_LIMIT_WEBHOOK_RATE
Burst: 10 requests
Applied to: webhooks.${BASE_DOMAIN}
nself auth rate-limit set webhooks 50r/mDefault: 50 requests/minute
Purpose: Serverless function invocations
Variable: RATE_LIMIT_FUNCTIONS_RATE
Burst: 15 requests
Applied to: functions.${BASE_DOMAIN}
nself auth rate-limit set functions 100r/mDefault: 1000 requests/minute
Purpose: Per-user rate limiting (requires authentication)
Variable: RATE_LIMIT_USER_RATE
Based on Authorization header instead of IP address.
nself auth rate-limit set user_api 2000r/mnself implements a multi-layer DDoS protection strategy:
Prevents connection exhaustion attacks by limiting concurrent connections.
Configuration:
-
limit_conn_per_ip: Max concurrent connections per IP (default: 10) -
limit_conn_server: Max total server connections
Applied to:
- GraphQL API: 10 connections per IP
- Auth endpoints: 5 connections per IP
- Uploads: 5 connections per IP
- Webhooks: 10 connections per IP
- Functions: 10 connections per IP
Protects against memory exhaustion from large payloads.
Configuration:
CLIENT_MAX_BODY_SIZE=10M # Default body size
CLIENT_HEADER_BUFFER_SIZE=1k # Header buffer
LARGE_CLIENT_HEADER_BUFFERS=8k # Large headers
CLIENT_BODY_BUFFER_SIZE=16k # Body bufferPer-endpoint overrides:
- Storage/uploads: 1000M (1GB)
- Webhooks: 10M
- General API: 10M (default)
Defends against slowloris and slow POST attacks.
Configuration:
CLIENT_BODY_TIMEOUT=12s # Slow POST protection
CLIENT_HEADER_TIMEOUT=12s # Slowloris protection
KEEPALIVE_TIMEOUT=15s # Connection timeout
SEND_TIMEOUT=10s # Response timeoutSmooths request rates and prevents burst attacks.
- Each zone has independent token bucket
- Burst handling allows temporary spikes
- Refill rate maintains sustainable throughput
# List all rate limit zones and their settings
nself auth rate-limit list
# Check rate limiting status
nself auth rate-limit status# Set rate limit for a zone
nself auth rate-limit set <zone> <rate>
# Examples
nself auth rate-limit set graphql_api 200r/m
nself auth rate-limit set auth 5r/m
nself auth rate-limit set uploads 10r/m
# Apply changes
nself build && nself restart nginx# Reset rate limits for a specific IP
nself auth rate-limit reset 192.168.1.100# View violations in last 24 hours
nself auth rate-limit violations
# View violations in last 6 hours
nself auth rate-limit violations 6
# Check for suspicious patterns
nself auth rate-limit alerts
# Analyze nginx error logs
nself auth rate-limit analyze# Add IP to whitelist (bypass rate limits)
nself auth rate-limit whitelist add 10.0.0.1 "Internal server"
# List whitelisted IPs
nself auth rate-limit whitelist list
# Remove from whitelist
nself auth rate-limit whitelist remove 10.0.0.1
# Apply changes
nself build && nself restart nginx# Block IP permanently
nself auth rate-limit block add 1.2.3.4 "Brute force attack"
# Block IP for 1 hour (3600 seconds)
nself auth rate-limit block add 1.2.3.4 "Suspicious activity" 3600
# Remove block
nself auth rate-limit block remove 1.2.3.4
# Apply changes
nself build && nself restart nginxAll rate limit decisions are logged to PostgreSQL:
-- View recent violations
SELECT * FROM rate_limit.log
WHERE allowed = false
ORDER BY requested_at DESC
LIMIT 100;
-- Top violating IPs
SELECT
SPLIT_PART(key, ':', 2) as ip,
COUNT(*) as violations
FROM rate_limit.log
WHERE allowed = false
AND requested_at >= NOW() - INTERVAL '1 hour'
GROUP BY ip
ORDER BY violations DESC;The system checks for:
- High violators: IPs with >100 violations/hour
- Spike detection: 5x increase in violations
- Potential DDoS: >10,000 requests in 5 minutes
# Check for alerts
nself auth rate-limit alertsIf monitoring is enabled (MONITORING_ENABLED=true), rate limiting metrics are available in Grafana:
- Request rate over time
- Violation rate trend
- Top violating IPs
- Active rate limit buckets
Access: https://grafana.${BASE_DOMAIN}
Metrics exported for Prometheus:
-
nself_rate_limit_requests_total- Total tracked requests -
nself_rate_limit_violations_total- Total violations -
nself_rate_limit_violation_rate- Violation rate (0-1) -
nself_rate_limit_active_buckets- Number of active buckets
Trusted IPs bypass all rate limiting.
Use cases:
- Internal servers
- Monitoring services
- Trusted partners
- CI/CD systems
Storage: rate_limit.whitelist table in PostgreSQL
# Add internal server
nself auth rate-limit whitelist add 10.0.0.1 "Internal API server"
# Add monitoring
nself auth rate-limit whitelist add 203.0.113.50 "UptimeRobot"Blocked IPs are denied all access.
Use cases:
- Known attackers
- Abusive bots
- Brute force attempts
- DDoS sources
Storage: rate_limit.blacklist table in PostgreSQL
Features:
- Temporary or permanent blocks
- Auto-expiry support
- Reason tracking
# Permanent block
nself auth rate-limit block add 198.51.100.10 "DDoS attack"
# Temporary block (1 hour)
nself auth rate-limit block add 198.51.100.20 "Brute force" 3600# Lenient limits for local development
RATE_LIMIT_GENERAL_RATE=100r/s
RATE_LIMIT_GRAPHQL_RATE=1000r/m
RATE_LIMIT_AUTH_RATE=50r/m# Production-like limits for realistic testing
RATE_LIMIT_GENERAL_RATE=20r/s
RATE_LIMIT_GRAPHQL_RATE=200r/m
RATE_LIMIT_AUTH_RATE=15r/m# Strict limits for security
RATE_LIMIT_GENERAL_RATE=10r/s
RATE_LIMIT_GRAPHQL_RATE=100r/m
RATE_LIMIT_AUTH_RATE=10r/m # Prevent brute force
RATE_LIMIT_UPLOAD_RATE=5r/m # Prevent storage abuse-
Enable rate limiting in production
# Verify in .env.prod nself doctor -
Monitor violations regularly
# Daily check nself auth rate-limit violations 24 -
Set up alerts
# Add to cron (every hour) 0 * * * * nself auth rate-limit alerts
-
Whitelist known good IPs
# Internal infrastructure nself auth rate-limit whitelist add 10.0.0.0/8 "Internal network"
-
Block repeat offenders
# Check top violators nself auth rate-limit violations # Block if needed nself auth rate-limit block add <ip> "Repeated violations"
-
Customize per environment
# .env.dev - lenient # .env.staging - realistic # .env.prod - strict
- Burst handling: Allow temporary spikes while preventing sustained abuse
- Token buckets: More efficient than fixed windows
-
Database cleanup: Regularly clean old logs
DELETE FROM rate_limit.log WHERE requested_at < NOW() - INTERVAL '7 days';
# Generate configuration
nself build
# Restart nginx
nself restart nginx# Identify top violators
nself auth rate-limit violations
# Check if legitimate traffic
# If attack, block the IP
nself auth rate-limit block add <ip> "Abuse"
# If legitimate, increase limits or whitelist
nself auth rate-limit set <zone> <higher-rate>
# OR
nself auth rate-limit whitelist add <ip> "Legitimate high traffic"# Option 1: Increase zone limit
nself auth rate-limit set graphql_api 500r/m
# Option 2: Whitelist the IP
nself auth rate-limit whitelist add <ip> "High-volume user"
# Option 3: Reset their limits
nself auth rate-limit reset <ip># Rebuild and restart
nself build
nself restart nginx
# Verify
nself auth rate-limit status# Initialize/reinitialize rate limiting
nself auth rate-limit init
# Check PostgreSQL
nself status postgres# View nginx errors
nself logs nginx
# Check rate limit config syntax
docker exec nself_nginx nginx -tEdit .env to add custom zones:
# Custom zone for admin endpoints
RATE_LIMIT_ADMIN_RATE=5r/mThen modify nginx/includes/rate-limits.conf (after build) to use it.
Requires ngx_http_geoip2_module (not included by default).
Already implemented via user_api zone. Uses Authorization header instead of IP.
For issues or questions:
- GitHub Issues: https://github.com/nself-org/cli/issues
- Documentation: https://docs.nself.org
- Security: [email protected]