# 只允許已授權的 HTTP 方法:用 Nginx 以 405/444 封鎖雜訊請求 在運營過程中 tail 伺服器日誌時,偶爾會遇到這樣的情況。 * 我以為只使用 `GET / POST / PUT / DELETE`, * 日誌中卻出現了我從未見過的請求方法。 例如 PROPFIND 這類 WebDAV 方法可能會出現在日誌中。雖然應用程式會把它視為「不支援的方法」來處理,但重點是: **是否真的需要讓辛苦開發的應用程式去處理這些雜訊?** 答案通常是「不需要」。因此,**只允許已授權的方法,將其餘在 Nginx 前端即時切斷**,是一個乾淨的做法。 --- ## 為什麼要在 Nginx 先行攔截? {#sec-76d5b3dc5dd8} 可以在應用層攔截,但當請求已到達應用時,成本已產生: * WSGI/ASGI 進入點 * 中介層/日誌/認證邏輯部分執行 * 應用日誌被雜訊污染,真正的問題被掩蓋 * 流量增加時,無用負載也隨之累積 相反地,在 Nginx 先行攔截: * **最前端即時終止** → 成本最小 * **應用日誌保持乾淨** → 運維更輕鬆 * **攻擊面縮小** → 直接移除不必要的方法 一句話總結: > **應用程式負責產生產品,Nginx 則扮演門衛角色。** --- ## 日誌中偶爾出現的陌生方法大多不是「正常使用」 {#sec-a63d4a503b7b} `PROPFIND` 這類 DAV 方法是「看起來合理」的代表案例。 * 可能是掃描者隨意測試 WebDAV 是否開啟 * 若設定失誤,`PUT/MKCOL` 等方法被開啟,接著嘗試進一步操作 * User-Agent 可能為空,或像 HTTP/1.0 那樣隨意發送 核心點是: **如果我們的服務不使用該方法,則它幾乎不可能是正常流量。** 此時就不需要把請求送到應用層,友善回應也不必要。 --- ## 策略很簡單:以 Allowlist(允許清單)運營 {#sec-ab569a60bc61} ![nginx 這位安全衛士管理出入口的圖像](/media/editor_temp/6/e09dd4fc-f987-43bf-b38f-9ac6c4c594f6.png) 原則是「只開啟必要的,其他全部關閉」。 * 通用網頁/靜態資源:通常只需要 `GET`、`HEAD` * API:僅對必要的端點允許 `POST/PUT/PATCH/DELETE` 其餘方法(如 `PROPFIND`、`MKCOL`、`LOCK` 等) **若我們不使用,全部封鎖**,這是最方便的運營方式。 --- ## 405 vs 444:選擇哪種回應來切斷? {#sec-d11c50f6f713} 封鎖方式主要有兩種。 ### 1) 405 Method Not Allowed {#sec-e4e35f1834d8} * 標準且易於理解 * 正常客戶端使用錯誤方法時,明確告知「不允許」 ### 2) 444(Nginx 專用:無回應即斷開連線) {#sec-1ce8d337ee47} * 直接斷開,無任何訊息 * 減少掃描器/機器人得到線索 * 運維角度更安靜、乾淨(「把雜訊藏起來」) 實務上常見的做法: * **對公開網頁中無意義的方法**:使用 444 靜默切斷 * **對正常客戶端可能犯錯的路徑**:使用 405 明確回應 --- ## Nginx 設定範例:兩種「允許方法以外即切斷」的模式 {#sec-1d8728d2da1a} 以下範例提供「直接複製貼上」的格式。 ### 模式 A) 基本只允許 GET/HEAD,API 只允許必要方法 {#sec-36240c2c30f2} ```nginx server { # ... listen/server_name 等 ... # 1) 基本:網頁/靜態只允許 GET/HEAD location / { if ($request_method !~ ^(GET|HEAD)$) { return 444; } # 或 405 proxy_pass http://app; } # 2) API:僅允許必要方法 location /api/ { if ($request_method !~ ^(GET|HEAD|POST|PUT|PATCH|DELETE|OPTIONS)$) { return 444; } proxy_pass http://app; } } ``` * `/` 主要是頁面瀏覽,通常只開啟 `GET/HEAD` 就足夠。 * `/api/` 由於 CORS 可能需要 `OPTIONS`,因此一併允許。 ### 模式 B) 只挑選「陌生方法」明確封鎖(輕量起步) {#sec-6ac9467a2c6e} ```nginx location / { if ($request_method ~ ^(PROPFIND|PROPPATCH|MKCOL|COPY|MOVE|LOCK|UNLOCK)$) { return 444; } proxy_pass http://app; } ``` * 先從運營中常見的雜訊方法切斷。 * 長期來看,**Allowlist(模式 A)** 更安全、易於管理。 > 參考:雖然 Nginx 的 `if` 句子在某些情況下被警告為危險,但 > 這種「即時 return 的簡單條件」在實務中相當常見。 > 若想更嚴格,可使用 `limit_except`。 --- ## 結論:只允許已授權的方法讓運維更輕鬆 {#sec-2548f5cc7a8c} 重點很簡單: * 陌生方法大多不是正常流量 * 把請求送到應用層會產生成本,且日誌會被污染 * **因此在 Nginx 只保留允許的方法,其他以 405/444 切斷** 只要套用這個模式: * 應用資源消耗減少 * 日誌更乾淨 * 運維更順暢