如何追踪IP地址以封锁恶意用户?
如何追踪IP地址以封锁恶意用户?
以下是获取用户IP的几种理论:
理论1:如果您不使用负载均衡器,请使用REMOTE_ADDR。如果您使用负载均衡器,请使用负载均衡器使用的方法。在99%的情况下,似乎是HTTP_X_FORWARDED_FOR。所以:
function get_ip_address(){ $id = ''; if (isset($_SERVER['REMOTE_ADDR'])) $ip = $_SERVER['REMOTE_ADDR']; else if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) $ip = $_SERVER['HTTP_X_FORWARDED_FOR']; else $ip = 'UNKNOWN'; return $ip; }
理论2:还有一些其他的HTTP头信息(即$_SERVER['HTTP_...']),可能包含IP地址。所以:
function get_ip_address(){ foreach (array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR') as $key){ if (array_key_exists($key, $_SERVER) === true){ foreach (explode(',', $_SERVER[$key]) as $ip){ $ip = trim($ip); // 为安全起见 if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false){ return $ip; } } } } }
理论3:存储$_SERVER['HTTP_...']和$_SERVER['REMOTE_ADDR']中的一个。所以有两个变量:
function get_ip_address(){ foreach (array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED') as $key){ if (array_key_exists($key, $_SERVER) === true){ foreach (explode(',', $_SERVER[$key]) as $ip2){ $ip2 = trim($ip2); // 为安全起见 if (filter_var($ip2, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false){ $ip1 = $_SERVER['REMOTE_ADDR']; return array($ip2, ip1); } } } } }
坦白说,我有点困惑。我需要在数据库中存储多少列来存储用户的IP?我的意思是,我应该同时存储REMOTE_ADDR和HTTP_...吗?还是只存储其中一个?
实际上,我有一个查询,在每次页面加载时将用户的IP插入数据库中。所以每次在加载页面之前都会执行这个查询。显然,每个请求和每个用户的INSERT查询都是有成本的。所以我不想这个查询是无用的。我的意思是,我希望存储一个正确/真实的IP,或者至少我希望尽可能做到最好来检测用户的IP*。
*当用户使用像HSS这样的代理时,检测他将是不可能的。这就是为什么我说“至少”。
好的,哪个理论是最好的呢?
如何跟踪IP以阻止恶意用户?
当存储IP时,您需要决定是否信任发送X-FORWARDED-FOR
地址的远程地址。如果是的话,那么您存储转发的地址,否则您存储远程地址。代码如下:
$load_balancer = '10.20.30.40'; $ip = $_SERVER['REMOTE_ADDR']; if (isset($_SERVER['X_FORWARDED_FOR']) && $ip == $load_balancer) { $ip = $_SERVER['X_FORWARDED_FOR']; }
然后将$ip
记录在数据库中。没有必要将负载均衡器IP也存储在数据库中。在处理数据库数据时进行信任检查需要另外一个表来记录不同时间段内负载均衡器的IP。
关于为什么不考虑其他情况,例如HTTP_CLIENT_IP
,HTTP_X_FORWARDED
等,以及IP 10.20.30.40
是什么,负载均衡器是什么的问题,可以通过以下对话来解答:
问:为什么不考虑其他情况?
答:因为代理服务器和负载均衡器没有共同实现的标准,所以它们发送不同的头部信息。如果要处理所有不同的代理服务器,你必须查找所有这些信息。
问:IP 10.20.30.40
是什么?
答:这是负载均衡器的IP地址。
问:负载均衡器是什么?
答:负载均衡器是运行集群服务器时使用的反向代理服务器。客户端连接到负载均衡器,它将连接转发到实际的服务器。如果您不使用负载均衡器,您不需要担心这些东西,只需使用REMOTE_ADDR
。
问:如果用户使用类似HSS的代理服务器会发生什么?
答:您不能信任您不管理的代理服务发送的头部。所以当用户使用这样的公共代理时,请使用REMOTE_ADDR
。
问:总体上我必须使用REMOTE_ADDR
作为IP。那么当$_SERVER['REMOTE_ADDR']
为空时会发生什么?
答:如果PHP在服务器上运行,那么$_SERVER['REMOTE_ADDR']
不可能为空。
问:根据你的解释,我只需要存储REMOTE_ADDR
。我想知道为什么大多数回答都在谈论其他事情,比如HTTP_CLIENT_IP, HTTP_X_FORWARDED_FOR, HTTP_X_FORWARDED
?
答:因为代理服务器和负载均衡器没有常见实现的标准,所以它们发送不同的头部。如果您想处理所有不同的代理服务器,您必须查找所有这些信息。
问:关于“他们发送不同的头部”,“他们”是指什么?
答:我指的是像HSS这样的代理服务器。
问:代理服务器是指我的网站服务器还是我的网站用户的服务器?
答:我指的是像HSS这样的代理服务器。
问:好的,你在说“他们发送不同的头部”,“他们”是指什么?总体上你是在说我的网站服务器还是我的网站用户的服务器?
答:我是在说像HSS这样的代理服务器。
问:当用户使用像(HotSpotShield)这样的代理时,连接是来自HSS的,并且它会发送包含有关用户IP的HTTP头。1)这个头部确切是什么?2)在这种情况下,REMOTE_ADDR
包含什么?
答:在这种情况下,REMOTE_ADDR
是代理的地址。我不知道HSS发送的是哪个头部,可能是你列出的其中一个。但是,正如我一遍又一遍地说过,您不能信任您不控制的代理发送的头部。
问:根据您的描述,头部根本不安全。而且REMOTE_ADDR
是代理的地址。那么真正的用户IP在哪里?我猜当用户使用代理时,他是无法被检测到的。我说得对吗?
答:真正的用户IP在像X-FORWARDED-FOR
这样的头部中。除非代理服务器不发送它,或者发送一个虚假的头部,或者用户使用一连串的代理服务器。这就是为什么如果您不管理代理,就不能信任头部的原因,没有任何强制代理提供正确信息的机制。
问:总之,我明白了。显然代理不会提供正确的头部信息,这是它的工作。最后一个问题:“如果您不管理代理”,您所说的“管理”是什么意思?我应该做些什么吗?
答:您不需要做任何事情。如果它是您自己运行的机器,那么您知道它提供有效的信息,或者它超出您的控制,您无法信任它。例如,如果您拥有自己的负载均衡器,您可以管理它并相信它的X-FORWARDED-FOR
头部。但如果有人从公共代理服务器访问您的网站,那就超出您的职权范围了。