Nginx proxy_set_header 理解

Posted by Sunday on 2018-07-04

server_name=www.sundayhk.com ip=192.168.10.100
proxy_name=www.sundayle.com ip=192.168.10.101

Hosts

nginx对于upstream默认使用的是基于IP的转发,因此对于以下配置

1
2
3
4
5
6
7
8
9
10
11
server {
listen 80;
server_name www.sundayhk.com;

location / {
proxy_pass www.sundayle.com:3000;
proxy_set_header Host $proxy_host;
proxy_set_header Connection "";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

当匹配到/时,即Host $proxy_host为192.168.10.101。如果想让Host是www.sundayhk.com,则进行如下设置:

1
proxy_set_header Host www.sundayhk.com;

官方文档谷歌翻译

1
2
3
4
5
Syntax: proxy_set_header field value;
Default:
proxy_set_header Host $proxy_host;
proxy_set_header Connection close;
Context: http, server, location

允许将字段重新定义或附加到传递给代理服务器的请求标头。该值可以包含文本,变量及其组合。当且仅当在当前级别上没有定义proxy_set_header指令时,这些指令才从先前级别继承。默认情况下,只重新定义了两个字段

1
2
3
proxy_set_header Host       $proxy_host;
proxy_set_header Connection close;
即传递给后端的host为 : www.sundayle.com

如果启用了缓存,则标题字段为“If-Modified-Since”,“If-Unmodified-Since”,“If-None-Match”,“If-Match”,“Range”和“If-Range”来自原始请求不会传递给代理服务器。
未更改的“主机”请求标头字段可以像这样传递:

1
2
proxy_set_header Host       $http_host;
即传递给后端的host为 : www.sundayhk.com 或空

但是,如果客户端请求标头中不存在此字段,则不会传递任何内容。在这种情况下,最好使用$ host变量 - 它的值等于“Host”请求头字段中的服务器名称,或者如果此字段不存在则等于主服务器名称:

1
2
proxy_set_header Host       $host;
即传递给后端的host为 : www.sundayhk.com

此外,服务器名称可以与代理服务器的端口一起传递:

1
2
proxy_set_header Host       $host:$proxy_port;
即传递给后端的host为 : www.sundayhk.com:3000

如果标头字段的值为空字符串,则此字段将不会传递给代理服务器:

1
proxy_set_header Accept-Encoding "";

X-Forwarded-For

一般来说,X-Forwarded-For是用于记录代理信息的,每经过一级代理(匿名代理除外),代理服务器都会把这次请求的来源IP追加在X-Forwarded-For中

来自4.4.4.4的一个请求,header包含这样一行

X-Forwarded-For: 1.1.1.1, 2.2.2.2, 3.3.3.3
代表 请求由1.1.1.1发出,经过三层代理,第一层是2.2.2.2,第二层是3.3.3.3,而本次请求的来源IP4.4.4.4是第三层代理

而X-Real-IP,没有相关标准,上面的例子,如果配置了X-Read-IP,可能会有两种情况

1
2
3
4
// 最后一跳是正向代理,可能会保留真实客户端IP
X-Real-IP: 1.1.1.1
// 最后一跳是反向代理,比如Nginx,一般会是与之直接连接的客户端IP
X-Real-IP: 3.3.3.3

所以 ,如果只有一层代理,这两个头的值就是一样的
http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_set_header
https://imququ.com/post/x-forwarded-for-header-in-http.html