只允许已授权的 HTTP 方法:用 Nginx 通过 405/444 拦截无效请求

在运维过程中,查看 Web 应用日志时偶尔会遇到这样的情况。

  • 我以为只使用 GET / POST / PUT / DELETE
  • 日志里却出现了我从未见过的请求方法。

例如 PROPFIND 这类 WebDAV 方法会出现在日志中。应用会把它们视为“未支持的方法”来处理,但真正重要的是:

是否真的需要让繁忙的应用去处理这些无用请求? 答案通常是“不要”。因此,只允许已授权的方法,其他在 Nginx 前端直接拦截,更为简洁。


为什么要在 Nginx 层面拦截?

可以在应用层拦截,但请求到达应用时已经产生了成本。

  • WSGI/ASGI 入口
  • 中间件/日志/认证逻辑部分已执行
  • 应用日志被噪声污染,真正的问题被掩盖
  • 流量增大时,额外的无用负载会累积

相反,在 Nginx 层拦截:

  • 最前端立即终止 → 成本最小
  • 应用日志保持干净 → 运营更顺畅
  • 攻击面缩小 → 直接剔除无用方法

一句话总结:

应用负责业务,Nginx 负责守门。


日志中偶尔出现的陌生方法大多不是“正常使用”

PROPFIND 这类 DAV 方法是典型例子。

  • 可能是扫描者粗略探测 WebDAV 是否开启
  • PUT/MKCOL 等方法被误配置为开放,扫描者会继续尝试
  • User-Agent 为空或类似 HTTP/1.0 的简易请求也常见

核心点是:

如果我们的服务不使用该方法,几乎不可能是正常流量。 此时就不必把请求送到应用层,友好响应也无意义。


策略很简单:使用 Allowlist(白名单)

nginx 作为安全门卫的图示

原则是“只开放必要的,关闭其余”。

  • 通用网页/静态资源:通常只需 GETHEAD
  • API:仅在需要的端点上有限制性地允许 POST/PUT/PATCH/DELETE

其余方法(如 PROPFINDMKCOLLOCK 等) 如果我们不使用,全部拦截,是最简洁的运维方式。


405 vs 444:选择哪种响应方式?

拦截有两种常见方式。

1) 405 Method Not Allowed

  • 标准且易于理解
  • 对正常客户端错误方法给出明确提示

2) 444(Nginx 专用:无响应直接关闭连接)

  • 直接断开连接,无任何信息
  • 对扫描器/机器人提供更少线索
  • 运营上更安静、干净(“把噪声掩埋”)

实际操作中常见的组合:

  • 对无意义的公开方法:使用 444 轻松拦截
  • 对可能被正常客户端误用的路径:使用 405 明确告知

Nginx 配置示例:两种“只允许已授权方法”模式

以下示例便于直接复制使用。

模式 A:默认仅允许 GET/HEAD,API 额外开放所需方法

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:仅拦截“陌生方法”(轻量起步)

location / {
    if ($request_method ~ ^(PROPFIND|PROPPATCH|MKCOL|COPY|MOVE|LOCK|UNLOCK)$) { return 444; }
    proxy_pass http://app;
}
  • 立即剔除常见噪声方法。
  • 长期来看,Allowlist(模式 A) 更安全、更易维护。

注:虽然 Nginx 的 if 语句有滥用风险,但“立即 return 的简单条件”在实际中相当常见。若想更严格,可使用 limit_except


结论:只允许已授权方法让运维更轻松

核心要点:

  • 陌生方法大多不是正常流量
  • 送到应用层会产生成本并污染日志
  • 在 Nginx 层只保留已授权方法,其余用 405/444 拦截

只需应用一次此模式:

  • 应用资源消耗更低
  • 日志更干净
  • 运营更高效