limit_req_zone $binary_remote_addr zone=thoughtstream_oauth_login:10m rate=6r/m; limit_req_zone $binary_remote_addr zone=thoughtstream_oauth_callback:10m rate=12r/m; limit_req_zone $binary_remote_addr zone=thoughtstream_review:10m rate=60r/m; limit_req_zone $binary_remote_addr zone=thoughtstream_course_chat:10m rate=12r/m; limit_req_zone $binary_remote_addr zone=thoughtstream_co_chat:10m rate=180r/m; log_format thoughtstream_no_query '$remote_addr [$time_local] "$request_method $uri $server_protocol" $status $body_bytes_sent'; server { listen 80; listen [::]:80; server_name thought.stream www.thought.stream; access_log /var/log/nginx/thought.stream.access.log thoughtstream_no_query; error_log /dev/null crit; return 308 https://thought.stream$request_uri; } server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name www.thought.stream; ssl_certificate /etc/letsencrypt/live/thought.stream/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/thought.stream/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; access_log /var/log/nginx/thought.stream.access.log thoughtstream_no_query; error_log /dev/null crit; add_header Strict-Transport-Security "max-age=31536000" always; return 308 https://thought.stream$request_uri; } server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name thought.stream; ssl_certificate /etc/letsencrypt/live/thought.stream/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/thought.stream/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; access_log /var/log/nginx/thought.stream.access.log thoughtstream_no_query; add_header Strict-Transport-Security "max-age=31536000" always; location = /oauth/login { client_max_body_size 8k; limit_req zone=thoughtstream_oauth_login burst=2 nodelay; limit_req_status 429; limit_except GET HEAD POST { deny all; } proxy_pass http://127.0.0.1:4319; 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 Connection ""; proxy_buffering off; proxy_read_timeout 30s; proxy_send_timeout 30s; } location = /oauth/callback { access_log off; error_log /dev/null crit; limit_req zone=thoughtstream_oauth_callback burst=4 nodelay; limit_req_status 429; limit_except GET HEAD { deny all; } proxy_pass http://127.0.0.1:4319; 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 Connection ""; proxy_buffering off; proxy_read_timeout 30s; proxy_send_timeout 30s; } location = /oauth/logout { client_max_body_size 8k; limit_except GET HEAD POST { deny all; } proxy_pass http://127.0.0.1:4319; 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 Connection ""; proxy_buffering off; proxy_read_timeout 30s; proxy_send_timeout 30s; } location ~ ^/inspector/api/reviews/[^/]+/decisions$ { client_max_body_size 100k; limit_req zone=thoughtstream_review burst=10 nodelay; limit_req_status 429; limit_except POST { deny all; } proxy_pass http://127.0.0.1:4319; 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 Connection ""; proxy_buffering off; proxy_read_timeout 30s; proxy_send_timeout 30s; } location = /inspector/api/courses/post-training/questions { client_max_body_size 4k; limit_req zone=thoughtstream_course_chat burst=3 nodelay; limit_req_status 429; limit_except POST { deny all; } proxy_pass http://127.0.0.1:4319; 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 Connection ""; proxy_buffering off; proxy_read_timeout 30s; proxy_send_timeout 30s; } # The application admits only its fixed OAuth/Origin/CSRF-checked chat API. # No SDK daemon protocol or arbitrary upstream is forwarded. location ^~ /chat/api/ { access_log off; error_log /dev/null crit; client_max_body_size 32k; limit_req zone=thoughtstream_co_chat burst=12 nodelay; limit_req_status 429; limit_except GET POST { deny all; } proxy_pass http://127.0.0.1:4319; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header Connection ""; proxy_buffering off; proxy_read_timeout 130s; proxy_send_timeout 30s; } location / { client_max_body_size 8k; limit_except GET HEAD { deny all; } proxy_pass http://127.0.0.1:4319; 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 Connection ""; proxy_buffering off; proxy_read_timeout 30s; proxy_send_timeout 30s; } }