nginx反向代理,获取客户端ip

一、获取客户端ip代码

php 复制代码
/**
	 * @description: 获取客户端IP
	 * @return string
	 */	
	public static function getClientIp()
	{
        $ip = '';
		if(getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'),'unknown'))
		{
			$ip = getenv('HTTP_CLIENT_IP');
		}
		else if(getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'),'unkown'))
		{
			$ip = getenv('HTTP_X_FORWARDED_FOR');
 
            //线上环境,反向代理,ip会记录前置代理的ip(ip1, ip2, ip3),取第一个真正请求的ip验证
			$ipArr = explode(',',$ip);
			$ip = trim($ipArr[0]);
		}
		else if(getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'),'unkown'))
		{
			$ip = getenv('REMOTE_ADDR');
		}
		else if(isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] &&	strcasecmp(getenv('REMOTE_ADDR'),'unkown'))
		{
			$ip = $_SERVER['REMOTE_ADDR'];
		}
       
        return $ip;
	}

二、遇到的问题

1、通过步骤一中获取客户端ip的方法,ajax请求获取到的客户端的ip是服务端的ip地址;

经最后排查,ajax请求链接在nginx中设置了反向代理

需要在nginx中配置'proxy_set_header X-Forwarded-For proxy_add_x_forwarded_for;'后,在php中使用_SERVER'HTTP_X_FORWARDED_FOR'才能取到代理前的客户端ip

具体nginx配置如下:

php 复制代码
xc.test.com.conf配置内容:
location ^~ /ajax/ {
			proxy_set_header Host www.test.com;
			proxy_pass http://www.test.com;
			proxy_set_header RealHost $http_host;
			proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		}

2、配置完成重启nginx

内网环境$_SERVER'HTTP_X_FORWARDED_FOR'获取到ip是单个ip地址,确实是客户端ip

正式环境$_SERVER'HTTP_X_FORWARDED_FOR'获取到的是ip串,ip之间有**,空格**分隔

复制代码
ip1, ip2, ip3

其中ip1是真实的客户端ip地址,ip2和ip3是代理ip地址,正式环境网关走了几次代理,便会有几个ip拼接,这种情况获取客户端ip,需要取第一个ip1,详见步骤一种的代码处理。

三、延伸

* REMOTE_ADDR 客户端跟服务器"握手"时候的IP。如果使用了"匿名代理",REMOTE_ADDR将显示代理服务器的IP。(这个情况就和我遇到的问题一致,nginx里没有设置HTTP_X_FORWARDED_FOR,_SERVER\['HTTP_X_FORWARDED_FOR'\]为空,便读取了_SERVER'REMOTE_ADDR'的值,即代理服务器的ip)

* HTTP_CLIENT_IP 是代理服务器发送的HTTP头。如果是"超级匿名代理",则返回none值。同样,REMOTE_ADDR也会被替换为这个代理服务器的IP。

* $_SERVER'REMOTE_ADDR'; //访问端(有可能是客户端ip,有可能是代理的ip)IP

* $_SERVER'HTTP_CLIENT_IP'; //代理端的(有可能存在,可伪造)

* $_SERVER'HTTP_X_FORWARDED_FOR'; //用户是在哪个IP使用的代理(有可能存在,也可以伪造)

相关推荐
枫叶轻语6 小时前
【Nginx 从入门到实战 07】root 与 alias:资源路径到底怎样对应?
nginx·全栈
acd120099 小时前
Nginx 反向代理的缓冲区坑:后端响应大时接口偶发 502
java·运维·nginx
Thanks_ks10 小时前
常见 HTTP 状态码的坑:301/302、401/403、500/502 之间差的那一个词
计算机网络·nginx·http·面试·状态码·后端开发·浏览器缓存
Lsetea1 天前
Certbot webroot申请SSL证书总是404:Nginx挑战目录与路径映射检查
运维·nginx·https·ssl证书·certbot
莫晓燚1 天前
双机部署若依 (RuoYi‑Vue) 传统环境部署---实战
linux·运维·数据库·redis·mysql·nginx·ruoyi
山乐191311 天前
麒麟系统,安装Nginx并配置https证书
运维·nginx·https
一直在努力学习的菜鸟1 天前
阿里云SSL证书到期更换指南(Nginx + Typecho)
nginx
雾时之林2 天前
Nginx反向代理与proxy_cache缓存搭建CDN服务器
服务器·nginx·缓存
Linux_cy2 天前
nginx 502 排查手册:九种原因分类、定位命令与检查顺序
linux·运维·服务器·网络·数据库·nginx·ssh
开源必胜2 天前
Socket、异步非阻塞 I/O 与 NGINX、Netty 模型
网络·tcp/ip·nginx