背景信息
当负载均衡收到客户端请求,会选择一台后端服务器建立一个新的TCP连接,然后将客户端数据转发至后端服务器。当负载均衡收到后端服务器响应后,会将响应数据再转发至客户端。由此可见,后端服务器仅可获取经由负载均衡转换后的客户端IP地址,无法从TCP会话信息中获取客户端真实源IP地址。
如图1所示:
图1 负载均衡转发原理

针对七层监听(HTTP/HTTPS协议),若后端服务器希望获取客户端真实源IP地址,可使用X-Forwarded-For(XFF),它是一种HTTP请求头字段,用于记录客户端真实源IP地址,只有通过HTTP代理或负载均衡方式连接客户端时才可添加该字段。常见的代理服务器(包括:IIS 6、IIS 7、Apache、Tomcat、Nginx等)均支持通过解析X-Forwarded-For记录,获取客户端真实源IP地址。
说明: 使用Proxy协议也可实现相同功能,仅需在TCP会话中添加一个头字段,即可方便传递客户端信息,但前提需确保相应后端服务器支持Proxy协议。目前平台考虑到性能影响,暂不支持透明Proxy。
下文以CentOS 7环境下配置Apache、Nginx服务器为例,介绍如何获取客户端真实源IP地址。
配置Apache服务器
- 安装Apache。
# 在CentOS 7环境下,执行安装命令 [root@localhost ~]# yum -y install httpd # 启动http服务,并将http服务设置为开机自动启动 [root@localhost ~]# systemctl start httpd [root@localhost ~]# systemctl enable httpd # 关闭云主机防火墙 [root@localhost ~]# iptables -F - 修改配置。
# 修改配置文件httpd.conf [root@localhost ~]# vi /etc/httpd/conf/httpd.conf # 新增字段并设置 LoadModule remoteip_module modules/mod_remoteip.so //加载mod_remoteip.so模块 RemoteIPHeader X-Forwarded-For //设置RemoteIPHeader头部 RemoteIPInternalProxy <ip_range1> <ip_range2> ... <ip_rangeX> //设置回源IP段(真实IP地址,非负载均衡公网IP地址).若存在多个IP段,必须空格分隔 # 修改日志格式 LogFormat "%a %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined # 重启Apache服务,使配置生效 [root@localhost ~]# systemctl restart httpd如图2所示:

图2 修改配置 - 查看结果。
# 在access_log查看是否获取客户端真实源IP [root@localhost ~]# tail -f /var/log/httpd/access_log如图3所示:
图3 查看结果
配置Nginx服务器
- 安装Nginx。
# 下载安装包并解压 [root@localhost ~]# wget http://nginx.org/download/nginx-1.0.12.tar.gz [root@localhost ~]# tar zxvf nginx-1.0.12.tar.gz [root@localhost ~]# cd nginx-1.0.12 # 安装依赖环境 [root@localhost ~]# yum -y install pcre pcre-devel [root@localhost ~]# yum -y install zlib zlib-devel [root@localhost ~]# yum -y install openssl openssl-devel # 安装启动 # Nginx服务器使用http_realip_module模块解析X-Forwarded-For记录 [root@localhost ~]# ./configure --prefix=/usr/local/nginx --with-http_stub_status_module --without-http-cache --with-http_ssl_module --with-http_realip_module [root@localhost ~]# make [root@localhost ~]# make install # 查看服务状态 [root@localhost ~]# ps -ef | grep nginx # 测试服务是否启动成功 [root@localhost ~]# curl http://IP地址:80 # 关闭云主机防火墙 [root@localhost ~]# iptables -F - 修改配置。
# 修改配置文件nginx.conf [root@localhost ~]# vi /usr.local/nginx/conf/nginx.conf # 新增字段并设置 set_real_ip_from <ip_range1>; set_real_ip_from <ip_range2>; ... set_real_ip_from <ip_rangex>; //设置回源IP段(真实IP地址,非负载均衡公网IP地址).若存在多个IP段,必须分行添加 real_ip_header X-Forwarded-For; # 重启Nginx服务,使配置生效 [root@localhost ~]# ps -ef|grep nginx [root@localhost ~]# kill -9 nginx.pid [root@localhost ~]# cd /root/nginx/sbin [root@localhost ~]# ./nginx -c /usr/local/nginx/conf/nginx.conf如图4所示:
图4 修改配置 - 查看结果。
# 在access.log查看是否获取客户端真实源IP [root@localhost ~]# tail -f /usr/local/nginx/logs/access.log如图5所示:
图5 查看结果