只允许已授权的 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(白名单)

原则是“只开放必要的,关闭其余”。
- 通用网页/静态资源:通常只需
GET、HEAD - API:仅在需要的端点上有限制性地允许
POST/PUT/PATCH/DELETE
其余方法(如 PROPFIND、MKCOL、LOCK 等)
如果我们不使用,全部拦截,是最简洁的运维方式。
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 拦截
只需应用一次此模式:
- 应用资源消耗更低
- 日志更干净
- 运营更高效