跳至主要內容
問題與解答
網頁伺服器的安全性設定

網頁伺服器的安全性設定

問:
要做哪些伺服器安全設定? add_header 設了為什麼沒生效? CSP 要怎麼導入才不會壞掉? 上傳目錄要怎麼禁止執行 PHP?
答:

先做的三件事

  1. 隱藏版本資訊
  2. 關閉目錄瀏覽
  3. 限制上傳目錄的執行權限

這三項成本極低,卻能擋掉相當比例的自動化探測與攻擊。

一、隱藏版本與伺服器資訊

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 相關指令。

套用後的檢查

  1. 語法測試通過
  2. 用開發者工具確認回應標頭都有出現
  3. 確認錯誤頁面也帶有安全性標頭(驗證 always 有生效)
  4. 確認嵌入的地圖、影片、分析工具仍正常
  5. 確認憑證續期的驗證路徑未被阻擋

整體的防護原則見主機層與存取控制的防護設定

本文的設定範例以常見的環境為例,實際的路徑、模組名稱與指令可能因作業系統、版本與安裝方式而異。套用前請先在測試環境驗證,並確實備份原設定檔。

發表於2026-08-05   更新於2026-08-20
免費諮詢 · 1 個工作天內回覆

準備好讓網站 開始幫你帶生意了嗎?

不論是要做新網站、救舊網站,還是只想先聊聊方向——先諮詢,不用先付錢,我們照實給你建議。

1 個工作天回覆免費諮詢與報價費用白紙黑字26 年找得到人
免費諮詢
免費諮詢 LINE諮詢 03-4020420 臉書傳訊
免費諮詢 LINE諮詢 03-4020420 臉書傳訊
免費諮詢
免費諮詢 LINE諮詢 03-4020420 臉書傳訊
免費諮詢 LINE諮詢 03-4020420 臉書傳訊