Nginx之自定义header(proxy_set_header)
一、概述
proxy_set_header是Nginx配置中用于设置代理请求HTTP头部的指令。当Nginx作为反向代理时,它允许自定义从客户端接收到的请求或添加新的请求头,然后将其转发到后端服务器。这对于维护HTTP协议的连贯性、安全性和功能性至关重要。
proxy_set_header指令的语法如下:
proxy_set_header  <HeaderName>   <HeaderValue>;
- HeaderName:需设置的请求头名称(如
Host、X-Real-IP)。 - HeaderValue:请求头的值,可以是静态字符串、
Nginx内置变量(如\(host、\)remote_addr)或两者的组合 
二、核心机制
- 
HTTP 协议上下文传递
反向代理场景下,Nginx默认会覆盖部分请求头(如Host),导致后端服务丢失原始客户端信息。通过proxy_set_header可重建完整的请求上下文。- Host $host:保留客户端请求的原始域名,避免虚拟主机路由错误。
 - X-Real-IP $remote_addr:直接传递客户端真实IP。
 - X-Forwarded-For $proxy_add_x_forwarded_for:记录代理链IP列表,适用于多级代理环境。
 
 - 
动态变量支持
指令支持使用Nginx内置变量动态生成值,例如$scheme(协议类型)、$http_user_agent(设备信息)等,为后端提供精准的请求元数据。 
三、核心参数解析
3.1 设置Host头
- 
作用:指定后端服务器的主机名。确保后端服务器接收到的
Host头与客户端请求一致,避免因Host不匹配导致的400/404错误。若未设置,默认传递代理服务器的主机名。 - 
配置示例:
proxy_set_header Host $host; # 传递客户端请求的原始 Host proxy_set_header Host $http_host; # 优先使用请求头中的 Host(若存在) proxy_set_header Host backend.example.com; # 强制指定固定值 - 
场景:当后端应用依赖
Host头进行路由或生成绝对URL时需配置。 - 
示例对比:
 
1). 未设置proxy_set_header Host
GET / HTTP/1.1
Host: backend.example.com  # 默认由proxy_pass决定
2). 设置proxy_set_header Host $host:
GET / HTTP/1.1
Host: nginx.example.com    # 与客户端请求的Host一致
3.2 客户端真实IP传递
3.2.1 X-Real-IP
在代理环境中,上游服务器无法直接获取客户端的真实IP地址。为了让上游服务器能够识别客户端的真实IP地址,可以使用proxy_set_header指令传递客户端IP地址。
proxy_set_header X-Real-IP $remote_addr;
- X-Real-IP是一个自定义的请求头字段,用于存储客户端的真实IP地址。
 - 上游服务器可以通过读取X-Real-IP字段获取客户端的IP地址。
 
作用:将客户端真实IP写入X-Real-IP头,供后端服务器读取。
3.2.2 X-Forwarded-For
在多级代理环境中,上游服务器可能需要了解请求经过了哪些代理服务器。可以使用proxy_set_header指令传递代理信息。
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
X-Forwarded-For是一个标准的请求头字段,用于存储客户端IP地址和所有代理服务器的IP地址,以逗号分隔。- 上游服务器可以通过读取
X-Forwarded-For字段获取所有代理服务器的IP地址。 
作用:在原有X-Forwarded-For头的基础上追加客户端IP(支持多级代理)
3.3 协议与安全头
3.3.1 X-Forwarded-Proto
proxy_set_header X-Forwarded-Proto $scheme;
作用:传递原始请求协议(HTTP/HTTPS),用于后端生成正确链接。
2.3.2 安全头
proxy_set_header X-Frame-Options "SAMEORIGIN";  # 防点击劫持
proxy_set_header X-XSS-Protection "1; mode=block";  # 防XSS攻击
3.4 禁用或修改特定请求头
3.4.1 禁用请求头:将值设为空字符串。
proxy_set_header User-Agent "";  # 禁用User-Agent头
3.4.2 修改请求头:设置新的值。
proxy_set_header Authorization "Bearer <token>";  # 修改授权头
3.5 支持CORS(跨域资源共享)
在处理跨域请求时,后端服务器需要知道请求的来源。通过设置Origin请求头,后端可以根据需要决定是否允许该请求。
proxy_set_header Origin $http_origin; # 直接传递客户端Origin值
这将确保后端服务器能够接收到正确的来源信息,从而做出相应的CORS响应。
作用:保留客户端原始Origin头(适用于动态域名场景)
3.6 连接控制
proxy_set_header Connection "";
3.6.1 支持HTTP/1.1持久连接
问题:默认情况下,Nginx的Connection: close会强制关闭与后端的连接,导致每次请求都需要重新建立TCP连接,增加延迟。
解决方案:如果后端服务器支持HTTP/1.1的持久连接(Keep-Alive),可以通过以下配置启用:
proxy_set_header Connection "";
proxy_http_version 1.1;
3.6.2 避免Connection头冲突
问题:如果客户端请求中包含Connection: keep-alive,而Nginx默认覆盖为Connection: close,可能导致后端服务器行为异常。
解决方案:通过清空Connection头,保留客户端原始意图:
proxy_set_header Connection "";
3.6.3 WebSocket协议升级
WebSocket特殊需求:WebSocket需要协议升级(Upgrade: websocket),此时必须设置Connection: upgrade:
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
- $http_upgrade 变量获取客户端请求的Upgrade字段的值。
 - 将
Connection字段设置为upgrade,表示请求升级为WebSocket协议 
注意:此时不能清空
Connection头,否则握手失败。
3.7 自定义头传递
使用proxy_set_header指令添加其他自定义的请求头信息,例如:
proxy_set_header X-Custom-Header "DynamicValue";
X-Custom-Header是一个自定义的请求头字段,用于存储自定义信息。- 上游服务器可以通过读取
X-Custom-Header字段获取自定义信息。 
作用:传递业务标识、灰度发布标记等自定义信。
3.8 缓存控制
proxy_set_header Cache-Control "no-cache, no-store";
作用:强制后端禁用缓存,适用于动态内容。
3.9 请求头删除
proxy_set_header Accept-Encoding "";  # 禁用后端压缩
- 优点:
避免后端服务器进行压缩处理,减少CPU开销。 - 缺点:
响应内容未压缩,可能导致传输数据量增加,影响网络性能(尤其对大文件或高并发场景)。 
四、注意事项
4.1 下划线
Nginx对header的名字字符做了限制,若自定义头含下划线(如X-My_Header)则忽略掉,后端服务就获取不到该请求头,需在配置中开启:
underscores_in_headers on;
4.2 指令位置
proxy_set_header必须放在location或server块中,否则无效。
4.3 空值处理
设置proxy_set_header field "";会从请求中移除该头。若值包含变量且变量为空,头字段会被移除,这样就能阻止它们被传递。
下面是一个完整的配置示例,它会禁用所有默认头,仅传递必要的客户端信息:
server {
    listen 80;
    server_name example.com;
    location / {
        proxy_pass http://backend;
        
        # 禁用默认传递的头
        proxy_set_header Host "";
        proxy_set_header Connection "";
        proxy_set_header User-Agent "";
        proxy_set_header Accept "";
        proxy_set_header Accept-Encoding "";
        
        # 仅传递必要的头
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        
        # 若需要授权头
        proxy_set_header Authorization $http_authorization;
    }
}
五、总结
proxy_set_header指令是Nginx反向代理服务器中一个非常重要的指令,为反向代理配置提供了强大的灵活性。它允许我们自定义请求头信息,传递客户端IP地址、代理信息、WebSocket协议信息等,从而实现更灵活的代理功能。在使用proxy_set_header指令时,需要根据实际情况选择合适的变量和值,以确保上游服务器能够正确识别和处理请求信息。

                
            
        
浙公网安备 33010602011771号