# Redirect HTTP to HTTPS server { listen 80; listen [::]:80; server_name api.cashumints.space; location / { return 301 https://$server_name$request_uri; } } # Main HTTPS server server { listen 443 ssl; listen [::]:443 ssl; http2 on; server_name api.cashumints.space; # Certbot-managed SSL ssl_certificate /etc/letsencrypt/live/api.cashumints.space/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/api.cashumints.space/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # HSTS add_header Strict-Transport-Security "max-age=63072000" always; # Security headers add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always; # Logging access_log /var/log/nginx/cashumints-api.access.log; error_log /var/log/nginx/cashumints-api.error.log; # Connection limits (GLOBAL zone) limit_conn cashu_conn_limit 20; # Gzip gzip on; gzip_vary on; gzip_proxied any; gzip_comp_level 6; gzip_types application/json application/javascript text/plain text/css; # Client limits client_max_body_size 1m; client_body_timeout 10s; client_header_timeout 10s; # Proxy defaults 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_connect_timeout 5s; proxy_send_timeout 60s; proxy_read_timeout 60s; # Root → main site location = / { return 301 https://cashumints.space; } # Health (rate-limited like API) location = /health { limit_req zone=cashu_api_limit burst=10 nodelay; proxy_pass http://127.0.0.1:3012; } # Docs location /docs { limit_req zone=cashu_api_limit burst=10 nodelay; proxy_pass http://127.0.0.1:3012; } location = /openapi.json { limit_req zone=cashu_api_limit burst=10 nodelay; proxy_pass http://127.0.0.1:3012; } # Admin (strict) location /admin { limit_req zone=cashu_admin_limit burst=5 nodelay; proxy_pass http://127.0.0.1:3012; } # API endpoints location ~ ^/(stats|reviews|analytics|mints) { limit_req zone=cashu_api_limit burst=50 nodelay; proxy_pass http://127.0.0.1:3012; } location = /favicon.ico { return 204; access_log off; } # Block junk location ~ /\. { deny all; } location ~* \.(git|env|sql|bak|old|tmp)$ { deny all; } }