Web服务器前端有代理服务器或者nginx做了二次转发或CDN时日志中的$remote_addr可能就不是客户端的真实IP了,IP默认会显示为前端代理的IP了,要获取到真实IP,常用的解决方法有以下三种:
1、使用CDN自定义IP头来获取
优点:获取到最真实的用户IP地址,用户绝对不可能伪装IP
缺点:需要CDN厂商提供
CDN厂商使用nginx,那么在nginx上将$remote_addr赋值给你指定的头,方法如下:

proxy_set_header remote-user-ip $remote_addr;

后端将会收到remote_user_ip的http头,直接读取HTTP_REMOTE_USER_IP的内容基是客户端真实IP

2、通过HTTP_X_FORWARDED_FOR获取IP地址
优点:可以获取到用户的IP地址
缺点:程序需要改动,以及用户IP有可能是伪装的
CDN服务器都会传送HTTP_X_FORWARDED_FOR头,这是一个ip串,后端的真实服务器获取HTTP_X_FORWARDED_FOR头,截取字符串第一个不为unkown的IP作为用户真实IP地址, 例如:
120.22.11.11,61.22.22.22,121.207.33.33,192.168.50.121(用户IP,CDN前端IP,CDN中转,公司NGINX代理)
3、使用Nginx自带模块realip获取用户IP地址
优点:程序不需要改动,直接使用remote_addr即可获取IP地址
缺点:ip地址有可能被伪装,而且需要知道所有CDN节点的ip地址或者ip段
安装realip模块:
realip是Nginx内置模块,需要在编译Nginx时加上--with-http_realip_module参数来启用它。
常用的编译参数:

$ ./configure  --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-http_auth_request_module --with-threads --with-stream --with-stream_ssl_module --with-mail --with-mail_ssl_module --with-file-aio --with-ipv6 --with-http_spdy_module --with-cc-opt='-O2 -g'
$ make
$ make install

配置语法(推荐配置在http段)

set_real_ip_from 192.168.1.0/24; #真实服务器上一级代理的IP地址或者IP段,可以写多行。
set_real_ip_from 192.168.2.1;
real_ip_header X-Forwarded-For;  #从哪个header头检索出要的IP地址。
real_ip_recursive on; #递归的去除所配置中的可信IP。

real_ip_recursive的用途:递归的去除所配置中的可信IP,排除set_real_ip_from里面出现的IP。如果出现了未出现这些IP段的IP,那么这个IP将被认为是用户的IP。

带符号 * 的表示必填项