惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Jina AI
Jina AI
V
Vulnerabilities – Threatpost
Security Latest
Security Latest
AI
AI
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
量子位
H
Help Net Security
Attack and Defense Labs
Attack and Defense Labs
The GitHub Blog
The GitHub Blog
L
LINUX DO - 最新话题
A
Arctic Wolf
博客园_首页
S
Securelist
S
Secure Thoughts
Google DeepMind News
Google DeepMind News
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
T
Tailwind CSS Blog
Apple Machine Learning Research
Apple Machine Learning Research
酷 壳 – CoolShell
酷 壳 – CoolShell
Stack Overflow Blog
Stack Overflow Blog
N
Netflix TechBlog - Medium
Cyberwarzone
Cyberwarzone
小众软件
小众软件
T
Threatpost
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Blog — PlanetScale
Blog — PlanetScale
N
News and Events Feed by Topic
NISL@THU
NISL@THU
Forbes - Security
Forbes - Security
博客园 - 聂微东
F
Fortinet All Blogs
Simon Willison's Weblog
Simon Willison's Weblog
H
Heimdal Security Blog
罗磊的独立博客
S
Security @ Cisco Blogs
B
Blog
T
Troy Hunt's Blog
Engineering at Meta
Engineering at Meta
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
The Hacker News
The Hacker News
The Last Watchdog
The Last Watchdog
Hacker News - Newest:
Hacker News - Newest: "LLM"
I
Intezer
T
Threat Research - Cisco Blogs
C
Cybersecurity and Infrastructure Security Agency CISA
The Cloudflare Blog
S
Schneier on Security
月光博客
月光博客
L
LINUX DO - 热门话题
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org

轶哥博客

blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog blog
blog
2020-08-14 · via 轶哥博客

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地址。