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