腾讯云CLB会把客户端真实IP存到header中,由后端进行获取,这个header为:http_x_forwarded_for

如果是nginx打印日志,可以使用$http_x_forwarded_for,例如:

1
2
3
log_format  main  '$remote_addr - $remote_user [$time_local] "$request"'
                     '$status $body_bytes_sent "$http_referer"'
                     '"$http_user_agent" "$http_x_forwarded_for"';

如果nginx使用 http_realip_module模块,则在编译时加上参数–with-http_realip_module,–with-stream_realip_module(可选),nginx配置如下:

1
2
3
4
#set_real_ip_from   0.0.0.0/0;
#set_real_ip_from   192.168.3.0/24;
set_real_ip_from   负载均衡的ip或ip网段;
real_ip_header X-Forwarded-For;

而对于阿里云,则是使用X-Real-IP,nginx配置修改如下

1
2
3
4
#set_real_ip_from   0.0.0.0/0;
#set_real_ip_from   192.168.3.0/24;
set_real_ip_from   负载均衡的ip或ip网段;
real_ip_header X-Real-IP;

如果要设置header到X-Real-IP中,nginx配置如下:

1
2
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $http_x_forwarded_for;

关于proxy_add_x_forwarded_for

proxy_add_x_forwarded_for这个字段,会以追加的形式把多级代理的代理ip加起来,以逗号隔开,越靠近客户端的排在前面,越靠近最后服务端的排在后面,但存在被伪造的可能性,比如使用以下命令测试:

1
curl http://localhost -H 'X-Forwarded-For: 1.1.1.1' -H 'X-Real-IP: 2.2.2.2'

日志打印出来的ip可能会是"1.1.1.1, 127.0.0.1, 192.168.100.101, 192.168.100.102",其中1.1.1.1排在最前面,但他不是最真实的客户端ip

对于伪造代ip的处理方法

只需要在第一个代理设置proxy_set_header X-Real-IP $remote_addr;就好了,然后再应用端直接引用$http_x_real_ip就行。

附加说明

根据腾讯云官方文档说明,如果是四层协议则后端是可以直接从源IP获得客户端IP,以下是摘抄信息:

IPv4 CLB 场景下获取客户端真实 IP

负载均衡获取客户端真实 IP 的说明

CLB 的四层(TCP/UDP/TCP SSL)和七层(HTTP/HTTPS)服务均支持直接在后端 CVM 上获取客户端真实 IP,无需进行额外配置。

四层负载均衡,在后端 CVM 上获取的源 IP 即为客户端 IP。

七层负载均衡,您可以通过 X-Forwarded-For 或 remote_addr 字段来直接获取客户端 IP。