最安全清晰的方式是直接在 location 块中用 limit_except GET POST { deny all; },自动返回标准 405 响应并可配 add_header Allow "GET, POST";,语义明确、无 if 陷阱、支持嵌套。

直接在 location 块中用 limit_except 指令限制只允许 GET 和 POST,是最安全、清晰且无需额外模块的方式。它能明确拒绝 PUT、DELETE、TRACE、OPTIONS 等非必要方法,返回标准的 405 响应,不暴露服务细节,也避免了 if 的潜在陷阱。
推荐做法:用 limit_except 精准控制
该指令专为 HTTP 方法限制设计,语义明确,支持嵌套 location,适合接口、API 或特定路径的精细化管控。
- 写法简洁:在目标 location 内添加
limit_except GET POST { deny all; } - 自动返回 405 Method Not Allowed,符合 HTTP 规范
- 可搭配
add_header Allow "GET, POST";,让客户端清楚知道允许哪些方法 - 示例(保护 /api 路径):
location /api {
limit_except GET POST { deny all; }
add_header Allow "GET, POST";
# 其他 proxy_pass 或 fastcgi 配置
}
快速统一拦截:用 if + $request_method
适合需要全局或批量生效的场景,但必须放在 location 块内,不能用于 server 或 http 顶层。
- 使用正则精确匹配:
if ($request_method !~ ^(GET|POST)$) { return 403; } - 返回 403 更隐蔽(比 405 少透露服务端逻辑),适合对外接口
- 若需兼容健康检查,可扩展为
^(GET|HEAD|POST)$,并同步更新 Allow 头 - 注意:该方式不适用于 rewrite 或 proxy_pass 后续逻辑中依赖 method 的场景
集中管理白名单:用 map + if
当多个 location 共享同一套方法策略(如所有 API 都只许 GET/POST),用 map 可提升可维护性。
- 在 http 块中定义映射:
map $request_method $is_allowed {
default 0;
GET 1;
POST 1;
} - 各 location 中复用:
if ($is_allowed = 0) { return 405; } - 后续增删允许方法只需改 map,无需逐个修改 location
- 配合
add_header Allow "GET, POST";,响应头自动对齐
配套加固建议
单靠限制方法不够,需叠加基础防护形成纵深防御:
- 隐藏 Nginx 版本:设置
server_tokens off; - 上传目录单独处理,例如
location /uploads { limit_except GET { deny all; } },防止非读取操作 - 静态资源路径(如 .js/.css)建议只允 GET 和 HEAD:
limit_except GET HEAD { deny all; } - 若有 ModSecurity,可补充规则拦截非法方法:
SecRule REQUEST_METHOD "!^(?:GET|POST)$" "phase:1,id:2049,deny" - 定期查看 access log 中的 403/405 记录,识别扫描行为


















