PHP中的防洪DDoS

时间:2012-09-23 15:30:44

标签: php ddos

<?php
if (!isset($_SESSION)) {
        session_start();
}
// anti flood protection
if($_SESSION['last_session_request'] > time() - 2){
        // users will be redirected to this page if it makes requests faster than 2 seconds
        header("location: http://www.example.com/403.html");
        exit;
}
$_SESSION['last_session_request'] = time();
?>

我已经测试了这个脚本,因为你高出第二个它会毫无理由地重定向到http://www.example.com/403.html

谁能告诉我为什么?

8 个答案:

答案 0 :(得分:8)

让我们在逻辑上考虑一下......

攻击者的请求已经发送到Web服务器并发送到PHP脚本。 导致DDoS攻击失败的瓶颈是网络服务器。

DDoS攻击背后的想法就是 - 导致拒绝服务,其中网站/服务器无法处理任何新请求。所以在这种方法中,这种方法是不合理的。 您需要处理请求处理的阶梯。

如果您有一台服务器,那么<​​em>更容易。您可以在内核防火墙/ iptables上简单地实施速率限制规则。 但是假设您无法访问它,Apache仍然可以随时使用 - 尽管效率不高。

在.htaccess中实施规则是更好的解决方案,但仍然不完美。 但是根据DDoS攻击,开发人员无法阻止它。

答案 1 :(得分:1)

我使用了一个不需要cookie的优秀防洪脚本(非常适合网络服务)。它不能完美抵御高级DDOS攻击,但它足以防止初学者攻击和自动多次请求。

使用它之前,需要创建&#34; flood&#34;带&#34; ctrl&#34;的文件夹文件里面和&#34;锁定&#34;子文件夹。还需要使用正确的权限进行设置。

我已经测试过了。

define("SCRIPT_ROOT", dirname(__FILE__));

// number of allowed page requests for the user
define("CONTROL_MAX_REQUESTS", 3);
// time interval to start counting page requests (seconds)
define("CONTROL_REQ_TIMEOUT", 2);
// seconds to punish the user who has exceeded in doing requests
define("CONTROL_BAN_TIME", 5);
// writable directory to keep script data 
define("SCRIPT_TMP_DIR", SCRIPT_ROOT."/flood");
// you don't need to edit below this line
define("USER_IP", $_SERVER["REMOTE_ADDR"]);
define("CONTROL_DB", SCRIPT_TMP_DIR."/ctrl");
define("CONTROL_LOCK_DIR", SCRIPT_TMP_DIR."/lock");
define("CONTROL_LOCK_FILE", CONTROL_LOCK_DIR."/".md5(USER_IP));
@mkdir(CONTROL_LOCK_DIR);
@mkdir(SCRIPT_TMP_DIR);


if (file_exists(CONTROL_LOCK_FILE)) {
    if (time()-filemtime(CONTROL_LOCK_FILE) > CONTROL_BAN_TIME) {
        // this user has complete his punishment
        unlink(CONTROL_LOCK_FILE);
    } else {
        // too many requests
        echo "<h1>DENIED</h1>";
        echo "Please try later.";
        touch(CONTROL_LOCK_FILE);
        die;
    }
}

function antiflood_countaccess() {
    // counting requests and last access time
    $control = Array();

    if (file_exists(CONTROL_DB)) {
        $fh = fopen(CONTROL_DB, "r");
        $control = array_merge($control, unserialize(fread($fh, filesize(CONTROL_DB))));
        fclose($fh);
    }

    if (isset($control[USER_IP])) {
        if (time()-$control[USER_IP]["t"] < CONTROL_REQ_TIMEOUT) {
            $control[USER_IP]["c"]++;
        } else {
            $control[USER_IP]["c"] = 1;
        }
    } else {
        $control[USER_IP]["c"] = 1;
    }
    $control[USER_IP]["t"] = time();

    if ($control[USER_IP]["c"] >= CONTROL_MAX_REQUESTS) {
        // this user did too many requests within a very short period of time
        $fh = fopen(CONTROL_LOCK_FILE, "w");
        fwrite($fh, USER_IP);
        fclose($fh);
    }
    // writing updated control table
    $fh = fopen(CONTROL_DB, "w");
    fwrite($fh, serialize($control));
    fclose($fh);
}

从这里采取:https://github.com/damog/planetalinux/blob/master/www/principal/suscripcion/lib/antiflood.hack.php

答案 2 :(得分:0)

什么spudinksi说仍然适用,但这是你正在寻找的:

 <?php


 if (!isset($_SESSION)) {
         session_start();
 }

 if($_SESSION['last_session_request'] > (time() - 5)){
    if(empty($_SESSION['last_request_count'])){
        $_SESSION['last_request_count'] = 1;
    }elseif($_SESSION['last_request_count'] < 5){
        $_SESSION['last_request_count'] = $_SESSION['last_request_count'] + 1;
    }elseif($_SESSION['last_request_count'] >= 5){
            header("location: http://www.example.com/403.html");
            exit;
         }
 }else{
    $_SESSION['last_request_count'] = 1;
 }

 $_SESSION['last_session_request'] = time();

 ?>

答案 3 :(得分:0)

有一个名为IOSec的脚本,它很老了,但它可能会有所帮助。

答案 4 :(得分:-1)

只需将>更改为<

<?php        

if (!isset($_SESSION)) {
        session_start();
}
// anti flood protection
if($_SESSION['last_session_request'] < time() - 2){
        // users will be redirected to this page if it makes requests faster than 2 seconds
        header("location: http://www.example.com/403.html");
        exit;
}
$_SESSION['last_session_request'] = time();
?>

答案 5 :(得分:-1)

对于stop DDos,为该ip添加一个空路由,如下所示:

route add -host ???.???.???.??? reject

答案 6 :(得分:-2)

这段代码不能像这样卷曲循环。会话将在每个curl exec上再次创建;

for ($i=0;$i<999999999999999;$i++){

    /**/
    $c=curl_init();
    curl_setopt($c,CURLOPT_URL,"URL YOU WANT ATTACK");
    curl_setopt($c,CURLOPT_DNS_USE_GLOBAL_CACHE,TRUE);//dns
    curl_setopt($c,CURLOPT_HEADER,0);//get the header
    curl_setopt($c,CURLOPT_CONNECTTIMEOUT ,10);//get the header
    curl_setopt($c,CURLOPT_NOBODY,0);//and *only* get the header
    curl_setopt($c,CURLOPT_RETURNTRANSFER,1);//get the response as a string from curl_exec(), rather than echoing it
    curl_setopt($c,CURLOPT_FRESH_CONNECT,1);//don't use a cached version of the url
    curl_setopt($c, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:11.0) Gecko Firefox/11.0');
    curl_setopt($c, CURLOPT_HTTPHEADER, array('Content-type: application/x-www-form-urlencoded;charset=UTF-8' ));

    echo "\n $i";

}

答案 7 :(得分:-2)

会话可能不起作用,因为我们没有会话coockie。

我推荐这样的

$load = sys_getloadavg();
if ($load[0] > 20) {
    header('HTTP/1.1 503 Too busy, try again later');
    die('Server too busy. Please try again later.');
}

或者你可以

shell_exec('/sbin/iptables -I INPUT -j DROP -s ' . $ip);

用于ddosing $ ip