# ============================================================================= # Nginx configuration for findgirl.org – WordPress + FastCGI cache # Optimized & hardened – 2026 Best Practices (GCS Proxy + Local Plugins Split) # File: /etc/nginx/sites-available/findgirl.org # ============================================================================= # ─────────────────────────────────────── # HTTP → HTTPS redirect # ─────────────────────────────────────── server { listen 80; listen [::]:80; server_name findgirl.org www.findgirl.org; # Redirect everything to HTTPS return 301 https://$host$request_uri; } # ─────────────────────────────────────── # Main HTTPS server block – Cloudflare Full (strict) + Authenticated Origin Pulls # ─────────────────────────────────────── server { listen 443 ssl http2; # http2 still useful in 2026 listen [::]:443 ssl http2 ipv6only=on; server_name findgirl.org www.findgirl.org; # 關閉 Nginx 版本號顯示(拒絕洩漏任何系統特徵) server_tokens off; # ─── 動態快取標頭 (2026 精準控制) ────────────────────────── # 自動套用 nginx.conf 計算好的對照表。因為下方有加資安標頭,這裡必須配置 add_header Cache-Control $dynamic_cache_control always; # ─── Large upload support ────────── client_max_body_size 4G; # Allows up to ~4 GB uploads # ─── Document root & index ────────── root /var/www/findgirl.org; index index.php index.html index.htm; # ─── FastCGI cache bypass conditions ────────────────────────────── set $skip_cache 0; # 1. 檢查 Cookie (直接讀取 nginx.conf 高效算出的 $no_cache) if ($no_cache = 1) { set $skip_cache 1; } # 2. 檢查請求方法、參數與特定的 WordPress 機密路徑 if ($request_method = POST) { set $skip_cache 1; } if ($query_string != "") { set $skip_cache 1; } if ($request_uri ~* "(^/wp-(app|cron|login|register|admin|includes|content/plugins|json|xmlrpc)|/xmlrpc.php|/feed/|/comments/|/cart|/checkout|/my-account|/wc-api/|add-to-cart|logout|lost-password)") { set $skip_cache 1; } # ═══════════════════════════════════════════════════════════════ # 🛡️ 優先權最高:強制將外掛動態快取資源留在本地 VM,死活不進 GCS # ═══════════════════════════════════════════════════════════════ # 💡 寫在 GCS 代理區塊上方,利用 Nginx 正則先到先得特性,完美攔截外掛產生的靜態檔 location ~* /(elementor|fonts|houzez-crm|omgf|rank-math|redux|slider[0-9]+|wpallexport|wpallimport|wpo) { try_files $uri =404; expires 30d; access_log off; log_not_found off; add_header Cache-Control "public, no-transform" always; # 保持全站資安標準的一致性 add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header Referrer-Policy "no-referrer-when-downgrade" always; } # ═══════════════════════════════════════════════════════════════ # 🎯 核心:同時支援 /storage/ 與 /wp-content/uploads/ 的 GCS 雲端分流區塊 # ═══════════════════════════════════════════════════════════════ location ~* ^/(wp-content/uploads|storage)/ { # 🛡️ 溫和型防盜連安全防線 valid_referers none blocked *.findgirl.org findgirl.org *.google.com *.google.com.tw *.google.com.hk *.facebook.com *.instagram.com *.twitter.com *.x.com *.line.me *.telegram.org *.whatsapp.com *.pinterest.com; # 🚨 【核心漏洞修正】若判定為盜連,強制覆寫 Cache-Control,徹底阻斷 Cloudflare 快取這個 403 錯誤 if ($invalid_referer) { add_header Cache-Control "no-cache, no-store, must-revalidate" always; return 403; } # 🛡️ A. 路徑遍歷防護 (防止惡意構造請求) if ($request_uri ~* "\.\./|\.%2e/") { return 403; } # 🟢 B. 本地外掛分流已成功上移至獨立區塊攔截,此處直接專注處理雲端圖片代理 # 🌐 C. 上游解析度優化 (確保穩定解析 storage.googleapis.com) resolver 8.8.8.8 1.1.1.1 valid=300s; resolver_timeout 5s; # 🚀 D. 核心反向代理修正:歷史年份圖片直連 Google GCS 官方網域,尾部不加斜槓 proxy_pass https://storage.googleapis.com; # 🔄 E. 內部路徑精準重寫:無論前端被 WP Ghost 改成 /storage/ 還是標準路徑,通通橋接還原成 GCS 上的標準路徑結構 rewrite ^/(wp-content/uploads|storage)/(.*)$ /media.findgirl.org/sites/1/$2 break; # 🏷️ F. 標頭傳遞 (指向 Google GCS 官方端點) proxy_set_header Host storage.googleapis.com; 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; # 🔒 G. 擊碎 503 關鍵修正:強制啟用 TLS SNI 擴充,否則 Google 會拒絕 Nginx 的 HTTPS 握手 proxy_ssl_server_name on; proxy_ssl_name storage.googleapis.com; proxy_ssl_protocols TLSv1.2 TLSv1.3; # 🙈 H. 隱藏 GCS 原廠特徵與伺服器識別標頭(已完美補上 x-guploader 阻擊指令) proxy_hide_header x-goog-hash; proxy_hide_header x-goog-generation; proxy_hide_header x-goog-metageneration; proxy_hide_header x-goog-stored-content-encoding; proxy_hide_header x-goog-stored-content-length; proxy_hide_header x-goog-storage-class; proxy_hide_header Server; proxy_hide_header x-guploader-uploadid; # ⚡ I. 邊緣與瀏覽器快取極致優化 + 生產級安全標頭 (僅在 200 OK 正常狀況下生效) proxy_cache_valid 200 301 302 7d; expires max; add_header Cache-Control "public, max-age=2592000, immutable" always; add_header Vary "Accept-Encoding" always; add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header Referrer-Policy "no-referrer-when-downgrade" always; add_header X-XSS-Protection "0" always; add_header Permissions-Policy "interest-cohort=(), geolocation=(), camera=(), microphone=()" always; # 🩹 J. 容錯機制 (當雲端遭遇異常時,攔截錯誤並導向降級回源邏輯) proxy_intercept_errors on; error_page 502 503 504 = @storage_down; access_log off; log_not_found off; } # ─── PHP handling + FastCGI cache ───────────────────────────────── location ~ [^/]\.php(/|$) { try_files $uri =404; include fastcgi_params; fastcgi_pass unix:/run/php/php8.3-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; # Cache settings (WORDPRESS zone must be defined in nginx.conf http {}) fastcgi_cache WORDPRESS; fastcgi_cache_valid 200 301 302 60m; fastcgi_cache_bypass $skip_cache; fastcgi_no_cache $skip_cache; fastcgi_cache_key "$scheme$request_method$host$request_uri"; fastcgi_cache_use_stale error timeout updating http_500; # 繼承並主動補回因為 location 隔離而被中斷的動態快取與資安標頭 add_header Cache-Control $dynamic_cache_control always; add_header X-FastCGI-Cache $upstream_cache_status always; # 🔒 注入您指定的安全代碼(精準控制 PHP 動態頁面防禦) add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header Referrer-Policy "no-referrer-when-downgrade" always; add_header X-XSS-Protection "0" always; add_header Permissions-Policy "interest-cohort=(), geolocation=(), camera=(), microphone=()" always; } # ─── WordPress pretty permalinks ────────────────────────────────── location / { try_files $uri $uri/ /index.php?$args; } # ─── Static files – aggressive caching ──────────────────────────── # 💡 由於上方核心快取已改用正則,這裡的 location 將服務 uploads 與 storage 之外的靜態資源 location ~* \.(?:jpg|jpeg|png|gif|ico|css|js|svg|woff2?|ttf|eot|otf|webp|avif|pdf)$ { expires 365d; access_log off; log_not_found off; # 覆蓋主伺服器標頭,對靜態檔案套用永久快取 add_header Cache-Control "public, no-transform, immutable" always; # 🔒 注入您指定的安全代碼(靜態資源也一併死守防線) add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header Referrer-Policy "no-referrer-when-downgrade" always; try_files $uri =404; } # ─── Gzip compression ───────────────────────────────────────────── gzip on; gzip_vary on; gzip_proxied any; gzip_comp_level 6; gzip_min_length 256; gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml font/ttf font/opentype; gzip_static on; # ─── Security headers (modern 2025/2026) ────────────────────────── # 🔒 注入您指定的安全代碼(主伺服器全局請求基本防衛線) add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header Referrer-Policy "no-referrer-when-downgrade" always; add_header X-XSS-Protection "0" always; add_header Permissions-Policy "interest-cohort=(), geolocation=(), camera=(), microphone=()" always; # ─── Deny access to sensitive files ─────────────────────────────── location ~ /\. { deny all; return 403; } location ~* \.(htaccess|htpasswd|ini|log|sh|conf|bak|dist|swp|env|env\.example)$ { deny all; return 403; } location ~ ^/wp-content/(?:uploads/)?(.*\.php)$ { deny all; return 403; } location = /xmlrpc.php { deny all; access_log off; return 403; } location ~ ^/wp-admin/install\.php { deny all; return 403; } # ─── Rank Math / Yoast sitemaps ─────────────────────────────────── location ~* ^/sitemap(_index)?\.xml$ { rewrite ^/sitemap_index\.xml$ /index.php?sitemap=1 last; rewrite ^/([^/]+?)-sitemap([0-9]+)?\.xml$ /index.php?sitemap=$1&sitemap_n=$2 last; } # ─── .well-known (ACME + webfinger + others) ───────────────────── location ~ ^/\.well-known/(acme-challenge|webfinger) { allow all; try_files $uri $uri/ =404; } # Webfinger fallback location ~ /.well-known/webfinger { if ($arg_resource = "") { return 400; } rewrite ^ $scheme://$host/?well-known=webfinger$request_uri last; } # ─── Custom includes & logging ──────────────────────────────────── include /var/www/findgirl.org/hidemywp.conf; # WP Ghost 密碼本引入 access_log /var/log/nginx/findgirl.org.access.log main buffer=64k flush=1m; error_log /var/log/nginx/findgirl.org.error.log warn; # ─── 🩹 智能降級備援:當 GCS 故障或離線時,自動還原路徑並尋找本地 VM 實體檔案 ─── location @storage_down { # 如果請求是虛擬的 /storage/,在本地降級尋找實體的 /wp-content/uploads/ 備份 rewrite ^/storage/(.*)$ /wp-content/uploads/$1; try_files $uri =404; expires 30d; add_header Cache-Control "public, no-transform"; } # ─── Cloudflare Origin CA + Full (strict) SSL ───────────────────── ssl_certificate /etc/nginx/ssl/findgirl-fullchain.pem; # origin cert + ECC root chain ssl_certificate_key /etc/nginx/ssl/private/findgirl-origin.key; # ─── Authenticated Origin Pulls – required for Cloudflare AOP ───── ssl_client_certificate /etc/nginx/ssl/authenticated_origin_pull_ca.pem; ssl_verify_client on; # ─── TLS protocol & cipher settings ─────────────────────────────── ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers off; ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256; }
Comparer les annonces
Comparer