# Gondulf IndieAuth Server - nginx Configuration # TLS termination, reverse proxy, rate limiting, and security headers # Rate limiting zones limit_req_zone $binary_remote_addr zone=gondulf_auth:10m rate=10r/s; limit_req_zone $binary_remote_addr zone=gondulf_token:10m rate=20r/s; limit_req_zone $binary_remote_addr zone=gondulf_general:10m rate=30r/s; # Upstream backend upstream gondulf_backend { server gondulf:8000; keepalive 32; } # HTTP server - redirect to HTTPS server { listen 80; listen [::]:80; server_name auth.example.com; # CHANGE THIS to your domain # Allow Let's Encrypt ACME challenges location /.well-known/acme-challenge/ { root /var/www/certbot; } # Redirect all other HTTP traffic to HTTPS location / { return 301 https://$server_name$request_uri; } } # HTTPS server server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name auth.example.com; # CHANGE THIS to your domain # SSL/TLS configuration ssl_certificate /etc/nginx/ssl/fullchain.pem; ssl_certificate_key /etc/nginx/ssl/privkey.pem; # Modern TLS configuration ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384'; ssl_prefer_server_ciphers off; # SSL session cache ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; # OCSP stapling ssl_stapling on; ssl_stapling_verify on; resolver 8.8.8.8 8.8.4.4 valid=300s; resolver_timeout 5s; # Security headers add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; add_header X-Frame-Options "DENY" always; add_header X-Content-Type-Options "nosniff" always; add_header X-XSS-Protection "1; mode=block" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always; # CSP will be set by the application # Logging access_log /var/log/nginx/gondulf_access.log combined; error_log /var/log/nginx/gondulf_error.log warn; # Client request limits client_max_body_size 1M; client_body_timeout 10s; client_header_timeout 10s; # Authorization endpoint - stricter rate limiting location ~ ^/(authorize|auth) { limit_req zone=gondulf_auth burst=20 nodelay; limit_req_status 429; proxy_pass http://gondulf_backend; proxy_http_version 1.1; 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; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Port $server_port; proxy_set_header Connection ""; # Proxy timeouts proxy_connect_timeout 10s; proxy_send_timeout 30s; proxy_read_timeout 30s; } # Token endpoint - moderate rate limiting location /token { limit_req zone=gondulf_token burst=40 nodelay; limit_req_status 429; proxy_pass http://gondulf_backend; proxy_http_version 1.1; 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; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Port $server_port; proxy_set_header Connection ""; proxy_connect_timeout 10s; proxy_send_timeout 30s; proxy_read_timeout 30s; } # Health check endpoint - no rate limiting, no logging location /health { access_log off; proxy_pass http://gondulf_backend; proxy_http_version 1.1; proxy_set_header Connection ""; } # All other endpoints - general rate limiting location / { limit_req zone=gondulf_general burst=60 nodelay; limit_req_status 429; proxy_pass http://gondulf_backend; proxy_http_version 1.1; 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; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Port $server_port; proxy_set_header Connection ""; proxy_connect_timeout 10s; proxy_send_timeout 30s; proxy_read_timeout 30s; # Buffer settings proxy_buffering on; proxy_buffer_size 4k; proxy_buffers 8 4k; } }