From 52b09b886c3a14a39807704e9704f6d2f0ecf80b Mon Sep 17 00:00:00 2001 From: Nik Afiq Date: Tue, 30 Sep 2025 14:37:46 +0900 Subject: [PATCH] cleaned watch-party --- watch-party.conf | 66 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 47 insertions(+), 19 deletions(-) diff --git a/watch-party.conf b/watch-party.conf index 5bde062..291b60f 100644 --- a/watch-party.conf +++ b/watch-party.conf @@ -1,5 +1,6 @@ -# /etc/nginx/sites-available/watch-party (CLEAN) +# /etc/nginx/sites-available/watch-party +# WebSocket upgrade helper map $http_upgrade $connection_upgrade { default upgrade; '' close; @@ -9,17 +10,17 @@ map $http_upgrade $connection_upgrade { # HTTP: ACME + Redirect ############################ server { - listen 80; # IPv4 only + listen 80; server_name nik4nao.xyz; - # Let’s Encrypt HTTP-01 challenge lives on HTTP + # Let's Encrypt HTTP-01 challenge location ^~ /.well-known/acme-challenge/ { root /var/www/html; default_type "text/plain"; allow all; } - # Serve /robots.txt from disk regardless of proxying + # Serve /robots.txt from disk on HTTP location = /robots.txt { alias /var/www/html/robots.txt; default_type text/plain; @@ -35,21 +36,43 @@ server { # HTTPS: Proxy /watch-party/ ############################ server { - listen 443 ssl; + listen 443 ssl http2; server_name nik4nao.xyz; - # --- Certbot-managed TLS files (must exist) --- + # --- Certbot-managed TLS files --- ssl_certificate /etc/letsencrypt/live/nik4nao.xyz/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/nik4nao.xyz/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; + + # --- Security & indexing headers --- + add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always; + add_header X-Content-Type-Options "nosniff" always; + add_header Referrer-Policy "no-referrer" always; + add_header Permissions-Policy "geolocation=(), camera=(), microphone=()" always; + add_header X-Frame-Options "DENY" always; add_header X-Robots-Tag "noindex, nofollow, noimageindex, nosnippet, noarchive" always; - # Enforce trailing slash - location = /watch-party { return 301 /watch-party/; } - location = / { return 302 /watch-party/; } + # (Optional) Block noncompliant AI bots (requires $block_ai map in nginx.conf) + if ($block_ai) { return 403; } - # IMPORTANT: no URI on proxy_pass so upstream receives /watch-party/ prefix + # Serve /robots.txt on HTTPS + location = /robots.txt { + alias /var/www/html/robots.txt; + default_type text/plain; + } + + # Enforce trailing slash for subpath and land / on /watch-party/ + location = /watch-party { return 301 /watch-party/; } + location = / { return 302 /watch-party/; } + + # Cache versioned static assets aggressively (adjust path if needed) + location ^~ /watch-party/assets/ { + proxy_pass http://192.168.7.96:3000; + add_header Cache-Control "public, max-age=31536000, immutable"; + } + + # Main app proxy (keep /watch-party/ prefix) location /watch-party/ { proxy_pass http://192.168.7.96:3000; proxy_set_header Host $host; @@ -62,22 +85,27 @@ server { proxy_set_header Connection $connection_upgrade; } - # NEW: forward API to the same frontend (which then forwards to backend) + # API proxy with basic abuse controls location /api/ { - proxy_pass http://192.168.7.96:3000; # hits container's /api + proxy_pass http://192.168.7.96:3000; # upstream /api 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; + + # Limits (zones defined in nginx.conf) + limit_req zone=api_rps burst=20 nodelay; + limit_conn perip 20; + + # Timeouts & body limits + client_max_body_size 10m; + client_body_timeout 15s; + proxy_connect_timeout 5s; + proxy_send_timeout 60s; + proxy_read_timeout 60s; } - # Serve /robots.txt on HTTPS - location = /robots.txt { - alias /var/www/html/robots.txt; - default_type text/plain; - } - - # Don’t serve anything else + # Deny anything unexpected location / { return 404; }