
網頁伺服器的安全性設定
先做的三件事
- 隱藏版本資訊
- 關閉目錄瀏覽
- 限制上傳目錄的執行權限
這三項成本極低,卻能擋掉相當比例的自動化探測與攻擊。
一、隱藏版本與伺服器資訊
Nginx
server_tokens off;
Apache
ServerTokens Prod ServerSignature Off
PHP
expose_php = Off
攻擊的第一步通常是探測版本,再去找對應的已知漏洞。隱藏不能防止攻擊,但能減少被自動化工具鎖定的機會。
二、關閉目錄瀏覽
Nginx
autoindex off;
Nginx 預設就是關閉的,但若曾為了除錯開啟,記得關回去。
Apache
Options -Indexes
三、限制上傳目錄執行程式
這是最重要的一項。 能阻止上傳的惡意檔案被當成程式執行。
Nginx
location ^~ /uploads/ {
location ~ \.php$ { deny all; }
}
Apache
<Directory /var/www/example/public/uploads>
php_admin_flag engine off
<FilesMatch "\.(php|phar|phtml)$">
Require all denied
</FilesMatch>
</Directory>
表單上傳的相關防護見表單的防灌水與資安。
四、阻擋敏感檔案
# Nginx
location ~ /\.(?!well-known) { deny all; }
location ~* \.(env|ini|log|bak|sql|sh|conf)$ { deny all; }
location ~ composer\.(json|lock)$ { deny all; }
注意排除 .well-known,否則憑證的自動續期驗證會失敗。
Apache 對應的寫法:
<FilesMatch "^\.|\.(env|ini|log|bak|sql|conf)$">
Require all denied
</FilesMatch>
五、安全性標頭
add_header X-Content-Type-Options "nosniff" always; add_header X-Frame-Options "SAMEORIGIN" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always; add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
Nginx 的 add_header 有一個陷阱
子區塊中若出現任何 add_header,會覆蓋掉父區塊的所有 add_header。
也就是說:在 server 層設了標頭,但某個 location 中又加了別的 add_header,那個 location 就會失去 server 層的標頭。
處理方式:把共用的標頭抽成獨立檔案,在每個需要的區塊 include 一次。
另外always 參數很重要——沒有加的話,錯誤回應(例如 404、500)不會帶上這些標頭。
六、內容安全政策
效果最強,但也最容易設錯——設太嚴會讓地圖、影片、分析工具、社群外掛全部失效。
建議的導入方式
# 第一階段:僅回報,不阻擋
add_header Content-Security-Policy-Report-Only
"default-src 'self'; report-uri /csp-report" always;
收集一段時間,確認所有正常來源都已納入後,再改為實際執行。
語法上的注意事項
- 指令名稱後面接空格,不是冒號
- 各指令之間用分號區隔
- 特定關鍵字需要單引號——如
'self'、'none'、'unsafe-inline' - 網域來源不需要引號
更多語法細節可參考我們既有的NGINX 檔頭相關設定。
七、強制加密的宣告
add_header Strict-Transport-Security
"max-age=31536000; includeSubDomains" always;
導入前務必確認:
- 所有子網域都有有效憑證(若加了 includeSubDomains)
- 自動續期確實運作
- 一旦生效,在有效期內無法回退到 http
建議先設較短的 max-age 測試,例如 300 秒,確認一切正常再延長。
完整說明見加密之外的傳輸安全設定。
八、加密協定與套件
ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers off; ssl_session_cache shared:SSL:10m; ssl_session_timeout 1d; ssl_stapling on; ssl_stapling_verify on;
建議用線上的伺服器加密檢測工具驗證,並每年複測——評判標準會隨新弱點的發現而調整。
九、限制請求頻率
對登入等敏感路徑加上頻率限制,可有效阻擋自動化嘗試:
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
location = /admin/login.php {
limit_req zone=login burst=5 nodelay;
}
Apache 可使用 mod_ratelimit 或第三方模組。
十、限制管理路徑的來源
location ^~ /admin/ {
allow 203.0.113.0/24;
deny all;
}
在反向代理或 CDN 後方時要注意——直接用 $remote_addr 會取到代理的位址。需先正確設定 real_ip 相關指令。
套用後的檢查
- 語法測試通過
- 用開發者工具確認回應標頭都有出現
- 確認錯誤頁面也帶有安全性標頭(驗證 always 有生效)
- 確認嵌入的地圖、影片、分析工具仍正常
- 確認憑證續期的驗證路徑未被阻擋
整體的防護原則見主機層與存取控制的防護設定。
本文的設定範例以常見的環境為例,實際的路徑、模組名稱與指令可能因作業系統、版本與安裝方式而異。套用前請先在測試環境驗證,並確實備份原設定檔。