Nginx 安全注入签名需用 proxy_set_header 显式设置,配合来源控制、上下文完整性与防篡改机制;静态注入适用于内网可信调用,透传需 map 限源,动态签名应通过 auth_request 模块实现,并配套 Host 锁定、IP 重置等加固措施。

在 Nginx 中向请求头注入安全校验签名并转发,核心是用 proxy_set_header 显式设置可信签名头,但必须配合来源控制、上下文完整性与防篡改机制——签名本身不安全,可控的注入方式才安全。
静态注入固定签名(适用于内部可信调用)
若后端服务完全处于内网、调用方可信(如管理后台直连 API),可直接写死签名值:
- 使用单引号包裹含特殊字符的值,避免解析歧义:
proxy_set_header X-Api-Sign 'v1:sha256=abc123...'; - 确保该 header 不被客户端传入覆盖:禁用透传,不写
proxy_set_header X-Api-Sign $http_x_api_sign; - 注意 Nginx 无法计算 HMAC 或 Base64,所以该方式只适合固定密钥+固定格式的场景,不适用于带时间戳或 body hash 的动态签名
透传可信链路的签名头(如 CDN 或前置网关已签好)
当签名由上游可信组件(如自建 API 网关、私有 CDN)生成时,Nginx 可选择性转发,但必须限制来源:
- 用
map预定义透传逻辑,比if更可靠:map $http_x_api_sign $pass_sign { "" ""; default $http_x_api_sign; }
再配:proxy_set_header X-Api-Sign $pass_sign; - 若需按 IP 白名单判断是否透传,可在
map中结合$remote_addr:map "$http_x_api_sign:$remote_addr" $pass_sign { ~^.*:10\.0\.10\..*$ $http_x_api_sign; default ""; } - 务必关闭下划线头丢弃行为(若签名头含下划线):
underscores_in_headers on;(放在http块)
通过 auth_request 动态注入用户级签名上下文
真正需要验证请求合法性(如校验 URL 参数签名、绑定用户身份)时,必须借助 auth_request 模块,由外部服务生成并返回变量:
- 配置子请求验证入口:
location = /auth { internal; proxy_pass http://127.0.0.1:3000/verify; proxy_pass_request_body off; proxy_set_header X-Original-URI $request_uri; } - 在主 location 中调用并捕获响应头:
auth_request /auth;<br>auth_request_set $auth_user $upstream_http_x_auth_user_id;<br>auth_request_set $auth_time $upstream_http_x_auth_timestamp;<br>proxy_set_header X-User-ID $auth_user;<br>proxy_set_header X-Request-Time $auth_time;
- 验证服务(如 Node.js)成功时返回
X-Auth-User-ID和X-Auth-Timestamp,失败则返回 401/403,Nginx 自动拦截
配套必须做的安全加固动作
仅加签名头远远不够,否则可能被绕过或误导后端:
- 锁定 Host 头:
proxy_set_header Host $proxy_host;(禁用$host和$http_host) - 重置真实客户端 IP:
proxy_set_header X-Real-IP $remote_addr;,禁用$proxy_add_x_forwarded_for - 明确协议:
proxy_set_header X-Forwarded-Proto $scheme; - 清除高危头(如 Origin、User-Agent):
proxy_set_header Origin ""; proxy_set_header User-Agent ""; - 验证是否生效:在后端打印所有请求头,或临时加
add_header X-Debug-Sign $http_x_api_sign;查看响应


















