Nginx之自定义header(proxy_set_header)

一、概述

proxy_set_headerNginx配置中用于设置代理请求HTTP头部的指令。当Nginx作为反向代理时,它允许自定义从客户端接收到的请求或添加新的请求头,然后将其转发到后端服务器。这对于维护HTTP协议的连贯性、安全性和功能性至关重要。

proxy_set_header指令的语法如下:

proxy_set_header  <HeaderName>   <HeaderValue>;
  • HeaderName:需设置的请求头名称(如HostX-Real-IP)。
  • HeaderValue:请求头的值,可以是静态字符串、Nginx内置变量(如\(host、\)remote_addr)或两者的组合

二、核心机制

  1. HTTP 协议上下文传递
    反向代理场景下,Nginx默认会覆盖部分请求头(如Host),导致后端服务丢失原始客户端信息。通过proxy_set_header可重建完整的请求上下文。

    • Host $host:保留客户端请求的原始域名,避免虚拟主机路由错误。
    • X-Real-IP $remote_addr:直接传递客户端真实IP。
    • X-Forwarded-For $proxy_add_x_forwarded_for:记录代理链IP列表,适用于多级代理环境。
  2. 动态变量支持
    指令支持使用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持久连接

问题:默认情况下,NginxConnection: 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 下划线

Nginxheader的名字字符做了限制,若自定义头含下划线(如X-My_Header)则忽略掉,后端服务就获取不到该请求头,需在配置中开启:

underscores_in_headers on;

4.2 指令位置

proxy_set_header必须放在locationserver块中,否则无效。

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指令时,需要根据实际情况选择合适的变量和值,以确保上游服务器能够正确识别和处理请求信息。

参考

posted @ 2025-09-25 16:19  夏尔_717  阅读(148)  评论(0)    收藏  举报