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

每3秒执行一次cron作业PHP脚本,php,cron,crontab,Php,Cron,Crontab,对于.htaccess,我不喜欢用户只有在“拒绝来自$ip”时才被拒绝访问 我喜欢使用iptables,但我不想每次都登录我的服务器来阻止别人连接。因此,我想每3秒执行一次上面的php脚本,而不是使用有限的1分钟cron选项卡。为此,我需要创建一个受控循环,每3秒执行20次 最好的方法是什么?我的脚本以毫秒为单位运行 读取一个可能有数百行或数千行的文件,并且每三秒在其中一行上运行一个iptable命令是疯狂的-这必然会给服务器带来无法承受的压力,如果三秒作业中的两个在读取文件时相互干扰,则会导致

对于.htaccess,我不喜欢用户只有在“拒绝来自$ip”时才被拒绝访问

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


最好的方法是什么?我的脚本以毫秒为单位运行

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

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

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

示例如下:

使用cron,只需更新黑名单文本文件。不需要呼叫iptable。
(请注意,使用基于地图的黑/白列表不需要重新启动Apache)

也许你应该从另一个方向来看待这个问题-为什么它们会被禁止?您是否应该使用fail2ban之类的工具

然而,这也是不好的——任何从公司防火墙后面访问你的网站的人都将共享相同的IP,因此你将禁止整个公司,而不仅仅是个人

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

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

每三秒运行一次
iptables
听起来像是一个可怕的想法,会给服务器带来很大的压力。你为什么需要这个?为什么它需要这种解决方案?当你禁止某人使用IPtables时,它会显示服务器处于脱机状态。完全阻止他们进入。我希望。htaccess做到了,但它没有。你知道还有其他选择吗?你可能会在这里丢失数据。当此进程处于foreach循环中时,另一个进程可能会写入bans.txt,然后新数据将使用您的fwrite立即擦除。为什么需要通过“连接超时”来阻止整个服务器的用户?至少使用
REJECT
而不是
DROP
…我希望在这之前,3秒钟能足够快地完成所有事情^。它只有在我登录到服务器时才起作用。如何从PHP调用Iptables而不必登录?当我尝试时,什么也没有发生。@Kyle你的意思是,你只能在以管理员用户身份登录时从SSH触发它?@Kyle你在指定
iptables
的完整路径吗?是的。当我尝试这样做时,iptables中没有显示ip。我甚至试过了,但还是什么都没有出现。怎么了@米加,我不这么认为。什么是完整路径?@Kyle这是意料之中的,因为用户PHP运行时可能无权更改iptables规则。我同意@Sarwar的建议。这可能是最干净、最理智的方式+1.谢谢。我喜欢保护腐败的羊群。
$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);
}
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