每3秒执行一次cron作业PHP脚本

时间:2011-02-13 09:03:44

标签: php cron crontab

<?php
$banlog = file("bans.txt");
foreach($banlog as $ip) {
    exec("iptables -I INPUT -s $ip -j DROP");
}
$fp = fopen("bans.txt", "w");
fwrite($fp,"");
fclose($fp);
?>

使用.htaccess我不喜欢当用户“拒绝来自$ ip”时,用户只会获得拒绝访问权限

我喜欢使用iptables,但我不想每次都登录我的服务器来阻止某人连接。所以我上面的php脚本我想每3秒执行一次而不是有限的1分钟cron选项卡。为此,我需要创建一个受控循环,每3秒执行20次。

最好的方法是什么?我的脚本在几毫秒内运行。

3 个答案:

答案 0 :(得分:3)

读取可能有数百或数千行的文件并在每个行上运行iptable命令每三秒 疯狂 - 它必然会给你带来无法忍受的压力您的服务器,如果三秒钟中的两个作业在读取文件时互相干扰,则会导致不可预测的行为。

为什么不在每次向iptables文件添加内容时都调用bans.txt一次?

答案 1 :(得分:3)

使用Apache的mod_rewrite(RewriteModule)中的RewriteMap指令来实现基于动态文件的IP黑名单/白名单。

这里的例子:

https://wiki.koumbit.net/ApacheBlacklisting

http://www.debian-administration.org/articles/283

使用您的cron,只需更新黑名单文本文件即可。无需拨打iptable。 (请注意,您不需要重新启动Apache以使用基于RewriteMap的黑/白名单)

答案 2 :(得分:3)

也许你应该从不同的方向来看待这个问题 - 他们为什么被禁止?你应该使用fail2ban吗?

然而,这也很糟糕 - 从公司防火墙后面访问您网站的所有人都将共享相同的IP,因此您将禁止整个公司而不仅仅是个人。

解决方案1; 您的代码具有竞争条件,其中两个线程可以同时读取和写入同一文件,这可能会很糟糕,因为它可能会破坏您的IPTABLES设置。如果您坚持这样做,请在处理条目之前独占锁定bans.txt文件。

$banlogFp = fopen("bans.txt","a+"); // open for r+w
$tnow = time();
//loop until have lock, or 2 seconds elapsed 
//(since will be invoked again after 3 sec)
while (!flock("bans.txt") && (time() - $tnow < 2) {
   $banlogTxt = fread($handle, filesize($filename));
   $banlogTxt = preg_replace('/\.\\r\\n/m', '@\n', $s); //any CRLF to LF 
   $banlog = explode("\n", $banlogTxt); //Convert to array, splittng on LF
   foreach($banlog as $ip) {
       //validate $ip is numeric - don't want malicious hacker to break IPTABLES
       if (preg_match("/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/",$ip+)) {
           exec("iptables -I INPUT -s $ip -j DROP");
       }
   }
   ftruncate($banlogFp, 0); 
   fclose($banlogFp);
}

解决方案2; 您不需要在.htaccess中使用“拒绝来自aaa.bbb.ccc.ddd”命令,而是可以使用重写规则将它们指向您选择的任何页面。比修改IPTABLES更安全,但仍然存在禁止其他人共享IP地址的大问题。 E.g。

SetEnvIf REMOTE_ADDR 192.12.131.1 REDIR="redir"
SetEnvIf REMOTE_ADDR 192.12.131.2 REDIR="redir"
SetEnvIf REMOTE_ADDR 192.12.131.3 REDIR="redir"
RewriteCond %{REDIR} redir
RewriteRule ^/$ /you_are_banned.html

解决方案3(最好!); 除非他们注册了用户名+密码,否则不允许任何人发布到您的网站,然后只是禁用用户名,而不是IP地址。使用像MySQL这样的数据库来存储用户和密码,并使用一个标志来说明它们是否被禁止。