diff --git a/cinny/nginx.conf b/cinny/nginx.conf index 8d1a813..68c3376 100644 --- a/cinny/nginx.conf +++ b/cinny/nginx.conf @@ -7,6 +7,17 @@ map $uri $lotus_shell_cache_control { default ""; } +# All traffic arrives through Nginx Proxy Manager (10.10.10.27), so without +# realip every visitor shared ONE chat_limit bucket (20 r/s, keyed by +# $binary_remote_addr = the proxy): a scanner burst got real users 503s. +# Each server block below trusts X-Real-IP from the proxy only (NPM sets it +# to the client address, overwriting anything the client sent). +# +# [matrix #22] Decorations get their own, larger budget: opening the profile +# decoration picker can fetch hundreds of thumbnails, which would otherwise use +# up chat_limit and 503 the app's own files. +limit_req_zone $binary_remote_addr zone=decorations_limit:10m rate=100r/s; + server { listen 80; listen [::]:80; @@ -23,6 +34,8 @@ server { server_tokens off; client_max_body_size 50m; + set_real_ip_from 10.10.10.27; + real_ip_header X-Real-IP; limit_req zone=chat_limit burst=60 nodelay; limit_conn chat_conn 25; index index.html; @@ -113,6 +126,9 @@ server { # can be replaced in place under the same name, so a week, not immutable. location ^~ /decorations/ { alias /var/www/decorations/; + # Replaces the server-level chat_limit here (nginx doesn't inherit + # limit_req into a location that sets its own). + limit_req zone=decorations_limit burst=700 nodelay; include snippets/cinny-security-headers.conf; add_header Cache-Control "public, max-age=604800" always; location ~ /MANIFEST\.sha256$ { return 404; } @@ -151,6 +167,8 @@ server { root /var/www/html; server_tokens off; + set_real_ip_from 10.10.10.27; + real_ip_header X-Real-IP; limit_req zone=chat_limit burst=60 nodelay; limit_conn chat_conn 25;