|
| 1 | +daemon off; |
| 2 | +worker_processes auto; |
| 3 | + |
| 4 | +events { |
| 5 | + worker_connections 1024; |
| 6 | +} |
| 7 | + |
| 8 | +http { |
| 9 | + charset utf-8; |
| 10 | + server_tokens off; |
| 11 | + |
| 12 | + # Security headers (set at http level to apply to all responses) |
| 13 | + add_header X-Frame-Options "SAMEORIGIN" always; |
| 14 | + add_header X-Content-Type-Options "nosniff" always; |
| 15 | + add_header X-XSS-Protection "1; mode=block" always; |
| 16 | + add_header Referrer-Policy "strict-origin-when-cross-origin" always; |
| 17 | + |
| 18 | + # Logs to stdout/stderr for Heroku |
| 19 | + log_format custom '$http_x_forwarded_for - $remote_user [$time_local] ' |
| 20 | + '"$request" $status $body_bytes_sent ' |
| 21 | + '"$http_referer" "$http_user_agent"'; |
| 22 | + access_log /dev/stdout custom; |
| 23 | + error_log /dev/stderr; |
| 24 | + |
| 25 | + # Plausible endpoints |
| 26 | + set $plausible_script_url https://plausible.io/js/pa-PFruVsE_br97UUCRXE_6f.js; |
| 27 | + set $plausible_event_url https://plausible.io/api/event; |
| 28 | + |
| 29 | + # Proxy settings |
| 30 | + proxy_http_version 1.1; |
| 31 | + proxy_buffering on; |
| 32 | + proxy_connect_timeout 5s; |
| 33 | + proxy_send_timeout 5s; |
| 34 | + proxy_read_timeout 10s; |
| 35 | + |
| 36 | + upstream app_server { |
| 37 | + server unix:/tmp/nginx.socket fail_timeout=0; |
| 38 | + } |
| 39 | + |
| 40 | + server { |
| 41 | + listen <%= ENV["PORT"] %>; |
| 42 | + server_name _; |
| 43 | + keepalive_timeout 5; |
| 44 | + client_max_body_size 10m; |
| 45 | + |
| 46 | + # Security: Block known bad user agents |
| 47 | + if ($http_user_agent ~* (nikto|sqlmap|nessus|acunetix|masscan|zgrab|gobuster|dirbuster)) { |
| 48 | + return 444; |
| 49 | + } |
| 50 | + |
| 51 | + # Security: Block common attack paths |
| 52 | + location ~ ^/(\.env|\.git|\.htaccess|\.htpasswd|config\.js|wp-admin|wp-login|xmlrpc\.php|administrator|phpmyadmin|shell|cmd|backdoor|cgi-bin) { |
| 53 | + return 444; |
| 54 | + } |
| 55 | + |
| 56 | + # Plausible: Proxy script.js |
| 57 | + location = /js/script.js { |
| 58 | + proxy_pass $plausible_script_url; |
| 59 | + proxy_set_header Host plausible.io; |
| 60 | + proxy_pass_header Cache-Control; |
| 61 | + proxy_buffering on; |
| 62 | + } |
| 63 | + |
| 64 | + # Plausible: Proxy event API |
| 65 | + location = /api/event { |
| 66 | + client_max_body_size 1m; # Analytics events are tiny |
| 67 | + proxy_pass $plausible_event_url; |
| 68 | + proxy_set_header Host plausible.io; |
| 69 | + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; |
| 70 | + proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto; |
| 71 | + proxy_set_header X-Forwarded-Host $host; |
| 72 | + proxy_buffering on; |
| 73 | + } |
| 74 | + |
| 75 | + # Rails: All other requests |
| 76 | + location / { |
| 77 | + proxy_pass http://app_server; |
| 78 | + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; |
| 79 | + proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto; |
| 80 | + proxy_set_header Host $http_host; |
| 81 | + proxy_redirect off; |
| 82 | + } |
| 83 | + } |
| 84 | +} |
0 commit comments