# 許可されたHTTPメソッドだけを通す:ノイズリクエストはNginxで405/444で切る 運用中にウェブアプリケーションのログを tail していると、時折こんな瞬間が訪れます。 * `GET / POST / PUT / DELETE` だけを使っていると思っていた * ログには初めて見るメソッドがちらりと入っている 例えば `PROPFIND` などの WebDAV メソッドがログに出てきます。アプリは「サポートしていないメソッド」として処理しますが、重要なのはこれです。 **本当にアプリにノイズまで処理させる必要があるのでしょうか?** 答えはたいてい「いいえ」です。そこで**許可したメソッドだけを通し、残りは Nginx の前段で切る** のがきれいです。 --- ## なぜ Nginx でブロックするのか {#sec-b5d4f5f6dfc2} アプリレベルでブロックすることも可能です。しかしリクエストがアプリに届く瞬間にすでにコストが発生します。 * WSGI/ASGI エントリ * ミドルウェア/ロギング/認証ロジックの一部が走る * アプリログが汚れ、真の問題が埋もれる * トラフィックが増えると不要な負荷が蓄積 対照的に Nginx でブロックすると: * **最前段で即座に終了** → コスト最小 * **アプリログがクリーン** → 運用が楽になる * **攻撃面が縮小** → 不要なメソッド自体を除外 一言でまとめると。 > **アプリは製品を作り、Nginxは門番の役割を果たす。** --- ## ログに時折見える奇妙なメソッドはほとんど「正常使用」ではない {#sec-7f5126fc3fdf} `PROPFIND` などの DAV メソッドは「一見すると正規っぽい」代表例です。 * WebDAV 機能が開いているか粗く確認するスキャニング * 設定ミスで `PUT/MKCOL` などが開いていると次のステップへ進もうとする * User-Agent が空、または HTTP/1.0 のように粗く投げるパターンもよく見られる 核心はこれ一つです。 **私たちのサービスがそのメソッドを使わないなら、正常トラフィックである理由はほぼない。** その場合、アプリまで送って親切に応答する必要はありません。 --- ## 戦略はシンプル:Allowlist(許可リスト)で運用する {#sec-84ef31ae1a20} ![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-967ed2222242} ブロックには大きく二つの方法があります。 ### 1) 405 Method Not Allowed {#sec-c79f33550d87} * 標準的で理解しやすい * 正常クライアントが誤ったメソッドで来たときに「だめだ」と明確に知らせる ### 2) 444(Nginx専用:応答なしで接続終了) {#sec-fe4e18cb7c1d} * 何も返さずに切る * スキャナー/ボットにヒントを与えない * 運用観点で静かできれい(「ノイズは消す」) 実戦ではこう使い分けます。 * 公開ウェブで意味のないメソッド:444で静かに切る * 正常クライアントがミスしやすいパス:405で明確に案内 --- ## Nginx 設定例:許可メソッド以外を切る 2 つのパターン {#sec-3c7629273a8a} 以下は「コピー&ペーストで始めやすい」形で示しています。 ### パターン A) 基本は GET/HEAD のみ、API は追加許可 {#sec-42bc13636133} ```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-fa0b2940f799} ```nginx location / { if ($request_method ~ ^(PROPFIND|PROPPATCH|MKCOL|COPY|MOVE|LOCK|UNLOCK)$) { return 444; } proxy_pass http://app; } ``` * 直ちに運用で見られるノイズメソッドを切る方式。 * ただし長期的には **Allowlist(パターン A)** の方が安全で管理しやすい。 > 参考:`if` は Nginx で乱用すると危険だと言われることがありますが、 > こうした「即時 return の単純条件」は実務でかなり頻繁に使われます。 > より厳格にしたい場合は `limit_except` を使う方法もあります。 --- ## 結論:許可したものだけを通すことで運用が楽になる {#sec-35fe67d750b5} 要点はシンプルです。 * 奇妙なメソッドはほとんど正常トラフィックではない * アプリまで送るとコストが発生し、ログが汚れる * **だから Nginx で許可メソッドだけを残し、残りは 405/444 で切る** このパターンを一つ適用するだけで: * アプリリソースが少なくて済む * ログがきれいになる * 運用がずっと楽になる