PHP 中的防洪 DDoS
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12553606/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Anti-flood DDoS in PHP
提问by Unknown3r
<?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();
?>
I've already tested this script as you higher the second It Will keep redirecting to http://www.example.com/403.htmlwithout any reason.
我已经测试了这个脚本,当你第二个更高时它会http://www.example.com/403.html毫无理由地继续重定向。
Can anyone tell me why?
谁能告诉我为什么?
回答by nand
Let's think about this logically for a second...
让我们从逻辑上思考一下这个问题......
The attacker's request is already being sent to the web-server and through to the PHP script. The bottle-neck which causes failure in DDoS attacks is the web-server.
攻击者的请求已经被发送到网络服务器并通过 PHP 脚本。导致 DDoS 攻击失败的瓶颈是网络服务器。
The idea behind a DDoS attack is just that - to cause a denial of service, in which the website/server is unable to process any new requests. So in escense, this approach is irrational. You need to go up the ladder of request handling.
DDoS 攻击背后的想法就是 - 导致拒绝服务,其中网站/服务器无法处理任何新请求。所以从本质上讲,这种做法是不合理的。您需要爬上请求处理的阶梯。
If you have a server to your disposal, it's easier. You could simply implement a rate limiting rule on the kernel firewall/iptables. But assuming you do not have access to that, Apache is still at your disposal - although not as efficient.
如果您有一台可供您使用的服务器,那就更容易了。您可以简单地在内核防火墙/iptables 上实施速率限制规则。但假设您无权访问它,Apache 仍可供您使用 - 尽管效率不高。
Implementing a rule within .htaccess is a bettersolution, but still not perfect. But depending on the DDoS attack, there's no real solution at the developer's disposal to block it.
在 .htaccess 中实现规则是一个更好的解决方案,但仍然不完美。但是根据 DDoS 攻击,开发人员没有真正的解决方案来阻止它。
回答by manuelbcd
I'm using a good anti-flood script that des not need cookies (perfect for webservices). It's not perfect against advanced DDOS attacks but it's enough for preventing beginners attacks and automatic multiple requests.
我正在使用一个很好的防洪脚本,它不需要 cookie(非常适合网络服务)。它对于高级 DDOS 攻击并不完美,但足以防止初学者攻击和自动多个请求。
For using it, before it's needed to create "flood" folder with a "ctrl" file inside and a "lock" subfolder. Also needed to be setted with correct permissions.
为了使用它,在需要创建带有“ctrl”文件和“lock”子文件夹的“flood”文件夹之前。还需要设置正确的权限。
Already tested by me.
已经被我测试过了。
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);
}
Taken from here: https://github.com/damog/planetalinux/blob/master/www/principal/suscripcion/lib/antiflood.hack.php
取自这里:https: //github.com/damog/planetalinux/blob/master/www/principal/suscripcion/lib/antiflood.hack.php
回答by Dave Holitish
What spudinksi said still holds true, however here is what your looking for:
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();
?>
回答by Rhythm Shahriar
回答by Narvulkan_MVCore
This will count page reloads & also save time after 3 seconds .... if it gives problems or to easy for newbies to bypass then leave comment..
这将计算页面重新加载并在 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;
}
回答by Sr. Presidente
For stop DDos add a null route for that ip, like this:
对于停止 DDos,为该 ip 添加一个空路由,如下所示:
route add -host ???.???.???.??? reject
回答by Dan Barzilay
just change >to <:
只需更改>为<:
<?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();
?>
回答by M-A-X
Session may be not work, because we haven't session coockie.
会话可能不起作用,因为我们还没有会话 coockie。
I recommend such
我推荐这样的
$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.');
}
Or you can
或者你可以
shell_exec('/sbin/iptables -I INPUT -j DROP -s ' . $ip);
for ddosing $ip
为 ddosing $ip
回答by mohammad inanloo
this code not work for curl looping like this. session will create again on every curl exec;
此代码不适用于像这样的 curl 循环。session 将在每个 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";
}

