Reverse Proxies & Ingress Guide
In production environments, Django Hurricane typically operates behind an edge reverse proxy, CDN, or Kubernetes Ingress Controller (such as Nginx, Traefik, AWS ALB, or Cloudflare).
This guide covers configuring proxy headers, resolving real client IPs for the Rate Limiter, and optimizing Fast-404 defense shields.
Client IP Resolution & Trusted Headers
Hurricane's Token-Bucket Rate Limiter tracks request frequency per client IP address. When operating behind a reverse proxy, the direct socket connection (REMOTE_ADDR) belongs to the proxy rather than the end user.
To prevent all users from sharing a single proxy rate-limit bucket, configure RATE_LIMIT_PROXY_HEADER to match your infrastructure provider:
| Infrastructure Provider | Recommended Proxy Header | Hurricane Setting |
|---|---|---|
| Standard Reverse Proxy (Nginx, Traefik) | X-Forwarded-For (first IP) | RATE_LIMIT_PROXY_HEADER = "X-Forwarded-For" |
| Cloudflare | CF-Connecting-IP | RATE_LIMIT_PROXY_HEADER = "CF-Connecting-IP" |
| Nginx (Direct) | X-Real-IP | RATE_LIMIT_PROXY_HEADER = "X-Real-IP" |
| AWS Application Load Balancer (ALB) | X-Forwarded-For | RATE_LIMIT_PROXY_HEADER = "X-Forwarded-For" |
| Google Cloud Load Balancer (GCLB) | X-Forwarded-For | RATE_LIMIT_PROXY_HEADER = "X-Forwarded-For" |
Configuration Example
In your settings.py:
# Cloudflare example:
RATE_LIMIT_PROXY_HEADER = "CF-Connecting-IP"
# Or via environment variable:
# HURRICANE_RATE_LIMIT_PROXY_HEADER="CF-Connecting-IP"
Hurricane automatically normalizes header formats—whether you specify "CF-Connecting-IP" or "HTTP_CF_CONNECTING_IP", it correctly locates the value in WSGI/ASGI request headers.
Production Nginx Configuration
Below is an optimal Nginx configuration proxying traffic to Hurricane on port 8000 while maintaining real client headers and supporting WebSockets:
upstream hurricane_upstream {
server 127.0.0.1:8000;
keepalive 32;
}
server {
listen 80;
server_name example.com;
client_max_body_size 50M;
location / {
proxy_pass http://hurricane_upstream;
proxy_http_version 1.1;
# WebSocket support
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
# Real Client IP and Host headers
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Timeouts and buffer sizes
proxy_connect_timeout 5s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
}
}
Kubernetes Ingress Configuration
When deploying inside Kubernetes with ingress-nginx, ensure snippet or annotation settings pass real client IPs:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: django-app-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
nginx.ingress.kubernetes.io/proxy-read-timeout: "60"
nginx.ingress.kubernetes.io/proxy-send-timeout: "60"
spec:
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: django-app-service
port:
number: 80
Tuning Fast-404 Behind Reverse Proxies
Hurricane's Fast-404 Security Shield blocks scanner probes and malicious paths before they reach Django. Choose the optimal strategy based on your routing architecture:
1. auto Strategy (Default)
Inspects Django's root urls.py. If a root catch-all pattern is detected (e.g. Wagtail, CMS, or dynamic routing), it operates in Signature-only mode to avoid dropping legitimate dynamic pages. Otherwise, it operates in high-performance Prefix mode.
2. prefix Strategy
Ideal for dedicated APIs, microservices, and applications with explicit URL prefixes. Any path that does not match a known Django URL prefix is dropped immediately with an instant 404.
FAST_404 = "prefix"
FAST_404_EXTRA_PREFIXES = ["api", "auth", "v1", "v2"]
3. signature Strategy
Strictly checks incoming paths against known malicious exploit patterns (.php, .env, /wp-admin/, phpmyadmin, etc.). Legitimate non-matching paths continue to Django. Recommended when running CMS or dynamic multi-tenant routes.
FAST_404 = "signature"
