php阻止ips?这是值得的

时间:2016-07-29 06:38:54

标签: php mysql

这是我的第一篇文章,希望发布正确的内容。

我设计了这段代码,如果之前的连接是在一段时间之前完成的话,它会阻止ips,如果这个顾客重复了x次(在示例代码中:如果你在不到10秒的时间内连接了10次)换句话说,你访问的每个页面花费的时间不到10秒。

问题:

  • 是否值得花时间和计算消耗来检查它?
  • 最终目标是防止可能对我的网站造成损害的机器人(如果我编码错误并且没有意识到某些可能会损坏我的数据库的脚本),但每次连接时机器人都会改变ips到某个地方所以这段代码什么都不做?
  • 我在考虑在每个原始php页面的开头添加此代码,我的意思是那些只在服务器站点中进行更改的代码...所以也许我可以减少跨度和计数器?

希望一切都清楚。 谢谢。

$ip = preg_replace('#[^0-9.]#', '', getenv('REMOTE_ADDR'));
$sql = db_query("SELECT * FROM `protect` WHERE `ip` LIKE '$ip' AND `blocked` LIKE 1 LIMIT 1");
$count = mysqli_num_rows($sql);
if($count != 0){
    echo "Too many connections";
    exit();
}
$sql = db_query("SELECT * FROM `protect` WHERE `ip` LIKE '$ip' LIMIT 1");
$count = mysqli_num_rows($sql);
if($count != 0){
    while ($row = mysqli_fetch_array($sql, MYSQLI_ASSOC)){
        $previousCon=$row["previousCon"];
        $counter = $row["counter"];
    }
    $timeSpan=time()-strtotime($previousCon);
    if($timeSpan>10){
        $sql = db_query("UPDATE `protect` SET `counter`=0,`previousCon`=now() WHERE `ip` LIKE '$ip' LIMIT 1");
        exit();
    }else if($timeSpan<=10){
        $counter++;
        if($counter>=10){
            $sql = db_query("UPDATE `protect` SET `blocked`= '1',`previousCon`=now() WHERE `ip` LIKE '$ip' LIMIT 1");
            exit();
        }else{
            $sql = db_query("UPDATE `protect` SET `counter`='$counter',`previousCon`=now() WHERE `ip` LIKE '$ip' LIMIT 1");
            exit();
        }
    }
}else{
    $sql = db_query("INSERT INTO `protect` (`ip`,`previousCon`) VALUES ('$ip',now())");
    exit();
}

2 个答案:

答案 0 :(得分:4)

  

是否值得花时间和计算消耗来检查它?

绝对不是。

  

最终目标是防止可能对我的网站造成一些损害的机器人(如果我编码错误并且没有意识到,可能会损坏我的数据库的某些脚本),但每次连接到某个地方时机器人会改变ips所以这段代码什么都不做?

这里有不同的问题。

  • 如果您的脚本可能“损坏数据库”,则只有一个查询可以造成损害。防止重复查询将不会执行任何操作。您需要修复代码。 (旁注:我相信你知道,修改数据库的脚本应该通过HTTP POST调用,并且 - 在大多数情况下 - 使用CSRF令牌调用。这有助于防止意外损坏。)
  • 合法机器人(例如索引器)通常使用相同的IP,但通常它们也很好玩,不会每秒数百次请求垃圾邮件(通常),所以他们不应该成为你的问题。另一方面,僵尸网络确实会改变IP地址,所以是的...你的代码没用。

您是否考虑过许多​​请求可能来自同一IP地址的所有合法情况?

  • 例如,单个用户一次打开多个标签。你会禁止用户吗?
  • 代理/ NAT连接背后的许多用户,例如家庭,公共wifi或公司网络。他们都去你的网站,打开几个标签......然后被禁止?
  

我正考虑在每个原始php页面的开头添加此代码,我的意思是那些只在服务器站点中进行更改的代码......所以也许我可以减少跨度和计数器?

说真的,不要这样做。

您有一个非常具体的用例,其中限制是有用的:防止暴力破解密码(通常以登录形式)。你不是通过IP地址这样做(因为我们看到,它几乎没用),而是用户帐户。在一个帐户上尝试失败太多了?此帐户已锁定几分钟。

现在,如果你有一个特定的IP地址,它会给你的网站发送垃圾邮件,那么直接用防火墙或网络服务器禁用它会更加高效。

答案 1 :(得分:0)

不仅你的代码不能像@rlanvin所说的那样工作,你的脚本最终会导致网站崩溃甚至没有攻击者攻击你的网站。

您的代码会搜索整个表格两次,在某个百分比内您需要第三次搜索以更新记录。这很糟糕,非常糟糕。

由于您的表记录了触及服务器的每个唯一IP,因此您的表格将以非常快的速度增长。通常搜索超过100,000条记录的表可能会对性能造成严重损害(响应时间超过10秒),具体取决于服务器的计算能力。但是,无论你有多少计算能力,因为它是一个不断增长的表,它最终会达到一个严重损害服务器性能的程度。

首先,它可能只是让您的用户等待,但是当它达到某个时间(通常是30秒)时,服务器会将其视为错误并返回超出时间限制的错误。因此,即使根本没有攻击者,您的脚本也会关闭您的网站。

最糟糕的是,改变/伪造IP是攻击者的基础。所以当真的有攻击者的时候,他很可能会使用大量的IP,这会让你的桌子快速增长到那个突破点。因此,即使您的防火墙或其他较低级别的结构(例如路由器)在一段时间后阻止了攻击者,而不是恢复正常,因为您的脚本,该网站仍然处于停机状态。

因此,建议您根本不使用该脚本。