PHP 获取客户端真实IP地址

 更新时间:2023年12月24日 15:39:08   作者:轶哥  
PHP获取客户端真实IP地址,只要根据实际部署情况选择相对应的代码获取访客IP地址,是可以确保程序不被假IP欺骗的

PHP获取客户端真实IP地址,需要根据具体的服务器环境来确定使用哪种方法。目前搜索到的方法,大多是直接贴代码,没有针对不同情况作出说明,有可能导致系统被假IP骗过(IP欺骗)。

很多文章都提到“无法保证获取到的访客IP地址100%准确”,是否意味着PHP获取访客IP一定有漏洞可钻呢?

只要根据实际部署情况选择相对应的代码获取访客IP地址,是可以确保程序不被假IP欺骗的。

PHP的运行方式

PHP支持非常多的运行方式,例如php-cgi、php-fpm、swoole、php-cli、php-mod等。其中,php-fpm是php的fast-cgi的进程管理器。php-mod通常配合Apache使用,而php-fpm通常配合Nginx使用。从PHP5.4开始,PHP甚至可以以内置PHP服务(Buid-in web server)方式运行。逐渐的,PHP形成了很多经典搭配,例如LAMP、LNMP、LNMPA、IIS+PHP。

无论采用哪种PHP运行方式,分清是谁传递IP给PHP程序即可。这里对几种常见环境进行分析。

无代理层(PHP内置服务器/swoole)

由于客户端IP数据是从TCP/IP协议层传递过来的,因此在没有中间代理(客户端和服务器直连)的情况下,可以直接通过标准方法REMOTE_ADDR获得与PHP直接通讯的IP地址。

例如$_SERVER['REMOTE_ADDR']getenv("REMOTE_ADDR")

而在swoole中,可以通过$request->server['remote_addr']获得客户端IP地址。

在这种情况下,REMOTE_ADDR不可以显式的伪造,获取到的是实际与服务器连接的IP地址,是可靠的。

Nginx代理(Nginx + php-fpm / Nginx + swoole)

常见的LNMP方案,属于Nginx反向代理。Nginx与php的通讯,无论unix socket方式还是tcp socket方式,都跟Nginx的Header配置有关系。

proxy_http_version 1.1;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

可以在第一层nginx代理设置 proxy_set_header X-Forwarded-For $remote_addr

其他层nginx代理设置proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for

这样就可以通过X-Forwarded-For获取客户端真实IP地址。

如果设置了X-Real-IP $remote_addr,则通过X-Real-IP获取客户端IP地址。

PHP代码:

// php-fpm等
$_SERVER['HTTP_X_FORWARDED_FOR']);

// swoole
$this->http_input->header('x-real-ip');

总结来说,当有Nginx代理的情况下,需要根据具体配置来选择获取的Header,从而正确获取客户端IP地址,此时PHP中的的REMOTE_ADDR可能是最后一级代理的IP地址。

Apache代理(Apache + php_mod / Apache + php-fpm)

通常在Apache + PHP方案中,获取IP地址取决于Apache配置信息。

绝大部分情况可以使用$_SERVER["REMOTE_ADDR"]获取到真实客户端IP地址。

如果Apache上级存在Nginx,那么可以在Apache中使用mod_rpaf模块将客户端IP地址传递到X-Forwarded-For头中。

PAFheader X-Forwarded-For

负载均衡/云虚拟机/Serverless

在负载均衡条件下,需要查阅对应负载均衡程序的文档,来决定使用哪种方法获取真实客户端IP地址。

在大部分虚拟主机、负载均衡及无服务器中,可以通过HTTP_CLIENT_IPHTTP_X_FORWARDED_FORX-REAL-IP其一得知客户端IP地址。但是不建议对多种来源进行空值判断,这样容易被伪造者利用,从而实现IP欺骗。

目前并未有标准规定将客户端IP地址放入名为CLIENT_IP的环境变量,但是有不少老虚拟主机供应商这样做。新的提供商都不再使用该环境变量。网上大量的PHP文章中都是优先获取HTTP_CLIENT_IP的值,因此导致网上存在大量的服务器可以被伪造IP欺骗。

可能有该漏洞的代码:

<?php
if(!empty($_SERVER['HTTP_CLIENT_IP'])) {
    $ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) {
    $ip = $_SERVER['REMOTE_ADDR'];
}

IIS + PHP

这种情况下直接使用$_SERVER['REMOTE_ADDR']方法即可。

总结

无论是哪种情况,如果用户使用匿名代理访问服务器,只能获取到代理服务器的IP地址,其IP地址仍然具有参考意义。

获取客户端真实IP地址,此事需要查阅相关资料根据具体情况选用某一个方法,而不是复制粘贴

部分方法获取到的值可能是一个数组。

不建议对获取到的IP地址进行正则过滤,有可能你获取到的是一个IPv6地址。

以上就是PHP 获取客户端真实IP地址的详细内容,更多关于PHP 获取客户端真实IP地址的资料请关注脚本之家其它相关文章!

相关文章

  • Laravel如何同时连接多个数据库详解

    Laravel如何同时连接多个数据库详解

    这篇文章主要给大家介绍了关于Laravel如何同时连接多个数据库的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Laravel具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-08-08
  • laravel5.1框架model类查询的实现方法

    laravel5.1框架model类查询的实现方法

    今天小编就为大家分享一篇laravel5.1框架model类查询的实现方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-10-10
  • 浅谈PHP各环境下的伪静态配置

    浅谈PHP各环境下的伪静态配置

    这篇文章主要介绍了PHP各环境下的伪静态配置,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-03-03
  • Ecshop 后台添加新功能栏目及管理权限设置教程

    Ecshop 后台添加新功能栏目及管理权限设置教程

    这篇文章主要介绍了Ecshop 后台添加新功能栏目及管理权限设置教程,需要的朋友可以参考下
    2017-11-11
  • PHP微信开发之模板消息回复

    PHP微信开发之模板消息回复

    这篇文章主要为大家详细介绍了PHP微信开发之简单实现模板消息回复 的相关资料,感兴趣的小伙伴们可以参考一下
    2016-06-06
  • Yii2.0多文件上传实例说明

    Yii2.0多文件上传实例说明

    本文通过实例代码给大家介绍了Yii2.0多文件上传实例说明,非常不错,具有参考借鉴价值,需要的朋友参考下吧
    2017-07-07
  • php array_keys 返回数组的键名

    php array_keys 返回数组的键名

    php中array_keys函数用于返回包含数组中所有键名的一个新数组。本文章向大家详细介绍PHP array_keys函数使用方法。需要的码农可以参考一下
    2016-10-10
  • PHP编实现程动态图像的创建代码

    PHP编实现程动态图像的创建代码

    只要安装一些第三方的库文件并具有一定的几何知识,就可以利用PHP来创建和处理图像了。利用PHP创建动态图像是相当容易的一件事情。下面,笔者将详细介绍如何实现。
    2008-09-09
  • PHP实现赛邮SUBMAIL简单易用短信通知实例

    PHP实现赛邮SUBMAIL简单易用短信通知实例

    这篇文章主要介绍了使用PHP实现赛邮SUBMAIL的简单易用短信通知实例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-10-10
  • CodeIgniter错误mysql_connect(): No such file or directory解决方法

    CodeIgniter错误mysql_connect(): No such file or directory解决方法

    这篇文章主要介绍了CodeIgniter错误mysql_connect(): No such file or directory解决方法,需要的朋友可以参考下
    2014-09-09

最新评论