如何使用php检测和禁止攻击IP
我有一个不允许编辑iptables的web主机。有时我会遇到轻微(约300个请求/秒)的DoS攻击(通常不分布)。我决定写一个PHP脚本来阻止这些IP。首先,我尝试将过去10秒的所有请求存储在数据库中,并查找每个请求的滥用地址。但我很快意识到,用这种方法,我必须为每个DoS请求至少向数据库发出一个请求,这是不好的。然后,我优化了该方法,如下所示:如何使用php检测和禁止攻击IP,php,firewall,Php,Firewall,我有一个不允许编辑iptables的web主机。有时我会遇到轻微(约300个请求/秒)的DoS攻击(通常不分布)。我决定写一个PHP脚本来阻止这些IP。首先,我尝试将过去10秒的所有请求存储在数据库中,并查找每个请求的滥用地址。但我很快意识到,用这种方法,我必须为每个DoS请求至少向数据库发出一个请求,这是不好的。然后,我优化了该方法,如下所示: Read 'deny.txt' with blocked ip's If it contains request ip, then die() ---
Read 'deny.txt' with blocked ip's
If it contains request ip, then die()
--- at this point we have filtered out all known attacking ips ---
store requesting ip in database
clean all requests older than 10 secs
count requests from this ip, if it is greater than threshold, add it to 'deny.txt'
这样,新的攻击ip只会对数据库发出Threshold
请求,然后被阻止
所以,问题是,这种方法是否具有最佳性能?有更好的方法来完成这项任务吗?尝试使用Memcache,它会更快地查找 您可以使用IP地址作为密钥。读取值。如果它不存在,则将其初始化为0,如果它是一个数字,则将其递增。然后用1秒或10秒的TTL或任何你想要的时间段写回来。如果计数高于阈值,则在TTL期间有到多个请求,您可以阻止IP 更新:我只是想,设置更新的值将再次给它一个至少1秒的新TTL,因此,如果IP以不到1秒的连续间隔请求
请求,它可能会被阻止我不认为这会使这个答案完全无用,但如果你想对我描述的内容进行文字化的实现,就要记住这一点 阻塞可以永久地(通过将其记录到数据库中)完成,也可以在更短的时间内完成。您也可以使用MemCache,通过记录一个标记(如“X”)而不是一个计数器,并将TTL设置为更长的周期。计数器脚本必须检查读取值是否不是“X”,否则计数器将覆盖块 我会选择使用Memcache,即使你想让黑名单持久化。查找(您需要为每个请求执行)要快得多。您可以在数据库中保存列入黑名单的IP,并定期或至少在服务器重新启动时恢复该列表。这样,您就得到了一个持久的黑名单,而无需在每次请求时检查数据库。以下是我的代码:
$ip = $_SERVER['REMOTE_ADDR'];
// Log ip
$query = "INSERT INTO Access (ip) VALUES ('$ip')";
mysql_query($query) or HandleException("Error on logging ip access: " . mysql_error() . "; Query: " . $query);
// Here should be database cleanup code
// Count requests
$query = "SELECT COUNT(*) FROM Access WHERE ip='$ip' AND time > SUBTIME(NOW(), '00:01:00')";
$result = mysql_query($query) or HandleException("Error on getting ip access count: " . mysql_error() . "; Query: " . $query);
$num = mysql_fetch_array($result);
$accesses = $num[0];
// Ban ip's that made more than 1000 requests in 1 minute
if($accesses > 1000)
{
file_put_contents('.htaccess', 'deny from ' . $ip . "\r\n", FILE_APPEND | LOCK_EX);
}
和.htaccess存根:
order deny,allow
deny from 111.222.33.44
deny from 55.66.77.88
或者将永久黑名单存储到
.htaccess
文件中。这样PHP就不会再被这些问题困扰了。@GolezTrol非常好的建议,但不幸的是我无法访问memcached