一个请求经过 nginx 反向代理,到了后端会变成什么样?响应回来又被改了什么?listener、路由、上游三层是怎么一层层选下去的?这篇用一个回显请求的后端和 nginx 1.31.6 把默认行为逐项量出来。
client 发出的请求头: Host: 'shop.example.test', X-Trace: 't-1', Accept-Encoding: 'gzip', X-Empty: '', X_under: 'u1', User-Agent: 'v17-client' 后端看到的请求行(默认配置): GET /hello?a=1 HTTP/1.1 (常见写法): GET /hello?a=1 HTTP/1.1 请求头 | client 发的 | 后端看到的(默认配置) | 后端看到的(常见写法) ----------------+---------------------+--------------+-------------------- Accept-Encoding | 'gzip' | 'gzip' | 'gzip' Host | 'shop.example.test' | 'u' | 'shop.example.test' User-Agent | 'v17-client' | 'v17-client' | 'v17-client' X-Empty | '' | '' | '' X-Forwarded-For | - | (没有) | '127.0.0.1' X-Real-IP | - | (没有) | '127.0.0.1' X-Trace | 't-1' | 't-1' | 't-1' X_under | 'u1' | (没有) | (没有)
Host、X-Forwarded-For 等默认不是你以为的样子;带下划线的请求头被丢弃。
响应头 | 直连后端 | 经过 nginx(默认) | 经过 nginx(hide X-Secret-Internal + pass Server) ------------------+-------------------------------+-------------------------------+----------------------------------------------- connection | (没有) | keep-alive | keep-alive content-length | 106 | 93 | 93 date | Sun, 18 Oct 2026 15:26:26 GMT | Sun, 18 Oct 2026 15:26:26 GMT | Sun, 18 Oct 2026 15:26:26 GMT keep-alive | timeout=5 | (没有) | (没有) server | BaseHTTP/0.6 Python/3.14.8 | nginx/1.31.6 | BaseHTTP/0.6 Python/3.14.8 x-backend | b1 | b1 | b1 x-secret-internal | yes | yes | (没有)
Server 被换掉、逐跳头被去掉、内部头原样泄露。
listener | Host 头 | 路径 | 状态码 | 落到哪里 ---------+--------------+--------------+-----+------------- 端口 P1 | shop.test | /api/users | 200 | b1 端口 P1 | shop.test | /static/a.js | 200 | b2 端口 P1 | shop.test | /other | 200 | shop-default 端口 P1 | unknown.test | /api/users | 404 | no-such-host 端口 P2 | admin.test | /api/users | 200 | b2 端口 P2 | shop.test | /x | 200 | b2 第一层 listener(端口 + server_name 选 server 块)→ 第二层路由(location 选一条规则)→ 第三层上游(upstream 里选一台后端)。Host 对不上任何 server_name 时落到该端口的 default_server;P2 上只有一个 server 块,所以不管 Host 是什么都落到它
listener 选 server 块,路由选 location,上游选后端;Host 对不上落到 default_server。