<?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
。
谁能告诉我为什么?
答案 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