PHP 中的防洪水 DDoS

问题描述 投票:0回答:10
<?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

谁能告诉我为什么?

php ddos
10个回答
8
投票

让我们从逻辑上思考一下......

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

DDoS 攻击背后的想法就是 - 导致拒绝服务,其中网站/服务器无法处理任何新请求。所以从本质上讲,这种做法是不合理的。 您需要提升请求处理的水平。

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

在 .htaccess 中实现规则是一个更好的解决方案,但仍然不完美。 但根据 DDoS 攻击的情况,开发人员没有真正的解决方案来阻止它。


2
投票

我正在使用一个很好的反洪水脚本,不需要cookie(非常适合网络服务)。它并不完美地抵御高级 DDOS 攻击,但足以防止初学者攻击和自动多重请求。

使用它之前,需要创建“flood”文件夹,其中包含“ctrl”文件和“lock”子文件夹。还需要设置正确的权限。

已经被我测试过。

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


0
投票

只需将

>
更改为
<
:

<?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();
?>

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();

 ?>

0
投票

要停止 DDos,请为该 ip 添加空路由,如下所示:

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

0
投票

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


0
投票

这将计算页面重新加载次数并在 3 秒后节省时间...... 如果它出现问题或容易让新手绕过,请发表评论..

if(empty($_SESSION['AFsys_time']) || $_SESSION['AFsys_time'] == '0') {
    $tGoal = time() + 3; // Pluss Seconds
    $_SESSION['AFsys_time'] = $tGoal;
}

if(empty($_SESSION['AFsys_pReloads']) || $_SESSION['AFsys_pReloads'] == 0 ) { $_SESSION['AFsys_pReloads'] = 1; } else { $_SESSION['AFsys_pReloads']++; };

if($_SESSION['AFsys_time'] < time()){
    $_SESSION['AFsys_time'] = 0; // Session Reset
    $_SESSION['AFsys_pReloads'] = 0; // Session Reset
}

if($_SESSION['AFsys_pReloads'] > '5' && $_SESSION['AFsys_time'] > time()){
    $_SESSION['AFsys_time'] = 0; // Session Reset
    $_SESSION['AFsys_pReloads'] = 0; // Session Reset
    header("location: http://www.example.com/403.html");
    exit; 
}

0
投票

更改为

$_SESSION['last_session_request'] > time() - 2
$_SESSION['last_session_request'] - time() < 2

<?php
if (!isset($_SESSION)) {
  session_start();
}
// anti flood protection
if(time() - $_SESSION['last_session_request'] < 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();
?>

如果 $_SESSION['last_session_request'] = 17626 并减去 time() = 17627 并检查减去的时间的余数是否小于 2,如果小于则移至页面 403.html


-1
投票

此代码不适用于像这样的curl循环。会话将在每次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";

}

-1
投票

Session 可能不起作用,因为我们还没有 session 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

© www.soinside.com 2019 - 2024. All rights reserved.