1 介绍
PROXY协议使Nginx接收客户端连接信息通过代理服务器和负载均衡器传入,例如HAproxy和亚马逊Elastic负载均衡器(SLB)。
通过PROXY协议传入的是客户端IP地址,代理服务器IP地址和端口号。知道客户端原始IP地址可能对特定语言的网站、保存IP黑名单或只记录和统计目的是有用的。
使用PROXY协议,Nginx能从SSL、HTTP/2、SPDY、WebSocket和TCP学习原始IP地址。
2 使用SSL、HTTP/2、SPDY和WebSocket的PROXY协议
为了使Nginx接收SSL、HTTP/2、SPDY和WebSocket的PROXY协议,在http级别上做以下改变:
-
配置Nginx接收PROXY协议头。添加proxy_protocol参数到listen指令:
server {
listen 80 proxy_protocol;
listen 443 ssl proxy_protocol;
...
}
- 在set_real_ip_from指令,指定IP地址或TCP代理或负载均衡器的CIDR方位地址:
server {
...
set_real_ip_from 192.168.1.0/24;
...
}
- 在real_ip_header指令,添加proxy_protocol参数保存客户端IP地址和端口号:
server {
...
real_ip_header proxy_protocol;
}
- 使用proxy_set_header指令和$proxy_protocol_addr变量从Nginx传入客户端IP地址到upstream服务器:
proxy_set_header X-Real-IP $proxy_protocol_addr;
proxy_set_header X-Forwarded-For $proxy_protocol_addr;
- 添加$proxy_protocol_addr变量到http级别的log_format指令
http {
...
log_format combined '$proxy_protocol_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
}
3 使用PROXY协议和TCP流
Nginx能为TCP流传入PROXY协议数据。
在Nginx配置文件中,在stream级别的server块中包括proxy_protocol指令:
stream {
server {
listen 12345;
proxy_pass example.com:12345;
proxy_protocol on;
}
}
4 完整例子
http {
log_format combined '$proxy_protocol_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
...
server {
server_name localhost;
listen 80 proxy_protocol;
listen 443 ssl proxy_protocol;
ssl_certificate /etc/nginx/ssl/public.example.com.pem;
ssl_certificate_key /etc/nginx/ssl/public.example.com.key;
set_real_ip_from 192.168.1.0/24;
real_ip_header proxy_protocol;
location /app/ {
proxy_pass http://backend1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $proxy_protocol_addr;
proxy_set_header X-Forwarded-For $proxy_protocol_addr;
}
}
}
stream {
...
server {
listen 12345;
proxy_pass example.com:12345;
proxy_protocol on;
}
}