上了反向代理之后访客来源地址记不准,该补哪个请求头
站点套上反向代理后,后台记录的访客地址和域名不对,需要在代理层补哪些请求头?要补的是两项:Host 与 X-Forwarded-For。代理模块的文档写得很明确,默认情况下原始请求的 Host 与 Connection 头不会传递给被代理服务器,因此后端看到的是代理机的地址与代理配置里的服务名;访客来源地址要还原,就得把客户端地址追加进 X-Forwarded-For,把原始域名用变量传给 Host。
先看程序拿到的是哪个地址
排查从日志开始,而不是从配置开始。看后端访问日志里记录的客户端地址:如果所有请求的地址都指向同一台内网机器,说明程序读到的是与代理之间的连接地址,而不是真实访客地址。
同样先确认域名。后台记录里的域名如果显示为服务名或代理域名,而不是访客实际访问的域名,说明 Host 没有按原始请求传递。这两个现象常常一起出现,但成因是两处配置,分别处理。
默认不传递的字段有哪些
代理模块默认不透传原始 Host,也不透传 Connection。前者的后果是后端不知道访客请求的是哪个域名,多站点按域名分流时尤其致命;后者的默认处理反而是好事,因为连接复用与关闭信号应当由代理层自己管理。
需要注意的是 Host 的取值方式有两种写法。原样传递客户端请求里的 Host 头是一种做法,但如果请求里根本没有这个头,就什么都传不过去;文档因此建议用 $host 变量——它的值在有请求头时等于请求头里的服务名,缺失时回落到配置里的主服务名。对公网站点来说,后者更稳。
| 请求头 | 默认是否透传 | 缺失后的现象 | 代理层写法要点 |
|---|---|---|---|
| Host | 不透传 | 后端认错域名,多站点跳错站 | 用变量传递原始域名,缺失时回落 |
| X-Forwarded-For | 需自行设置 | 访客地址全部记成代理机 | 把客户端地址追加到已有列表之后 |
| Connection | 不透传 | 一般无需关心 | 由代理层管理连接行为 |
| 协议标识 | 需自行设置 | HTTPS 被识别成 HTTP,跳转循环 | 与证书卸载方式保持一致 |
两行配置的写法
X-Forwarded-For 用模块提供的组合变量:$proxy_add_x_forwarded_for 的含义是把客户端地址以逗号追加到请求原有的 X-Forwarded-For 之后,如果请求本来没有这个头,其值就等于客户端地址本身。这个设计对多级代理很关键——直接覆盖会把上游已经写入的地址链丢掉,追加才是保留完整链路。
Host 的写法按上面的建议,用变量传原始域名。两处都配好后,后端读到访客来源地址、原始域名与协议,站内的访问统计、评论记录与按域名分流的逻辑才会一致。
还要提醒一件事:不要相信来自访客侧的 X-Forwarded-For。多层入口时,只有可信代理链上的追加值才有效,外部请求自带的伪造值要在最外层入口覆盖或清理,否则来源地址统计可以被人为操控。
多站点共用一个入口时要注意什么
多站点场景下 Host 的作用被放大。AnQiCMS 支持在同一后台管理多个独立站点,适用于多品牌与多主题网站,同一套服务往往按域名把请求分到不同站点。此时 Host 缺失或传成代理名,轻则认错站点、日志混淆,重则把访客路由到错误的品牌站。
端口映射也要一并记录。AnQiCMS 默认监听 8001 端口,部署方式支持 Docker 镜像、宝塔面板与常规环境部署,代理层指向的是这个服务端口。建议在部署文档里写清三件事:外部入口端口、代理转发目标端口、以及证书在哪一层卸载。这三项一旦缺失,故障表现就是「后台看不到真实来源」与「跳转循环」交替出现,排查成本很高。
反向代理本身还有另一层收益:静态资源与页面输出在代理层做缓存,可以显著缓解高并发下的响应压力。AnQiCMS 的页面加载速度相比传统 PHP 类 CMS 有显著提升,官方口径是单机可承载约 500 万 PV 的访问量,加上代理缓存后,源站承受的请求量还能进一步下降。
常见问题
只补 X-Forwarded-For 不补 Host 会怎样? 访客来源地址正确,但后端仍不知道原始域名,多站点按域名分流会失效,日志里的站点归属也不可靠。
后台能不能直接解析这个头? 能读,但要限定可信代理范围。无判断地信任头里的第一个地址,等于把来源地址交给访客自己填。
HTTPS 站点为什么出现跳转循环? 通常是证书在代理层卸载,转发给后端时协议信息没有一并传过去,后端以为自己收到的是明文请求而强制跳转。补上协议标识即可。
改完配置需要重启吗? 修改代理配置后按正常流程重载入口服务,再抽查日志确认地址与域名两项都已还原。