Wiki source for AutoBlockPHP
%%(php)
#!/usr/bin/php
<?
// Autoblock v20060511
// /etc/autoblock/autoblock.php
// Copyright 2006 by Jeff Taylor
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
require('./autoblock.conf');
openlog("autoblock", LOG_PID, LOG_SYSLOG);
if ($Debug & 1) logger("Autoblock started...");
$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
socket_set_option($socket, 1, 6, TRUE);
socket_bind($socket, '255.255.255.255', $Port);
$sockRef[] =& $socket;
socket_select($sockRef, $write=NULL, $except=NULL, 0);
socket_set_nonblock($socket);
$Blocked[] = "";
$LongestHitTime = 10; // Minimum seconds to retain IP info
// declare(ticks = 1);
// pcntl_signal(SIGTERM, "sig_handler");
// pcntl_signal(SIGKILL, "sig_handler");
// pcntl_signal(SIGINT, "sig_handler");
//----------------------------------------//
// Functions //
//----------------------------------------//
function sig_handler($sig) {
// If SIGKILL is detected, shut down gracefully
fclose($fp);
closelog();
echo "Exiting autoblock\n";
exit;
}
function my_ip($dest='10.0.0.0', $port=80) {
$sckt = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
socket_connect($sckt, $dest, $port);
socket_getsockname($sckt, $addr, $port);
socket_close($sckt);
return $addr;
}
function adjTime($stamp) {
$x = 0;
while (is_numeric(substr($stamp,$x,1))) { $x++; }
$num = trim(substr($stamp, 0,$x));
$type = trim(strtoupper(substr($stamp, $x)));
switch (substr($type, 0, 2)) {
case "SE":
$newstamp = $num;
break;
case "MI":
$newstamp = $num * 60;
break;
case "HO":
case "HR":
$newstamp = $num * 3600;
break;
case "DA":
case "DY":
$newstamp = $num * 86400;
break;
case "WE":
case "WK":
$newstamp = $num * 604800;
break;
}
return $newstamp;
}
function Broadcast($data) {
global $EnableBroadcasting;
global $Port, $socket;
if ($EnableBroadcasting) {
// logger("Broadcasting: $data");
$send_ret = socket_sendto($socket, $data, strlen($data), 0, '255.255.255.255', $Port);
if($send_ret < 0) echo "sendto() failed, error: " . strerror($send_ret) . "<BR>\n";
}
}
function GetRules($filename) {
global $Debug, $Events, $LongestHitTime;
$blocks=0;
$lines = file($filename);
foreach ($lines as $num => $line) {
$line=CleanLine($line);
$x=strpos($line, "=") - 1;
$cmd=trim(substr($line, 0, $x));
$val=trim(substr($line, $x));
switch ($val) {
case "{":
$blocks++;
$Events['Name'][$blocks] = $cmd;
break;
case "}":
// End of block
break;
default:
$val=strtolower(trim(substr($val, strpos($val, "=") + 1)));
switch ($cmd) {
case "domain":
$q = 0;
while (strpos($val, "|")) {
$x=strpos($val, "|");
$Events['Domain'][$blocks][$q] = substr($val, 0, $x);
$val=substr($val, $x+1);
$q++;
}
$Events['Domain'][$blocks][$q] = $val;
break;
case "hits":
if (! is_numeric($val)) $val = 0;
$Events['Hits'][$blocks] = $val;
break;
case "hittime":
$Events['HitTime'][$blocks] = $val;
$chkTime = adjTime($val);
if ($LongestHitTime < $chkTime) { $LongestHitTime = $chkTime; }
break;
case "info":
$Events['Info'][$blocks] = $val;
break;
case "time":
$Events['Time'][$blocks] = $val;
break;
case "match":
$q = 0;
while (strpos($val, "|")) {
$x=strpos($val, "|");
$Events['Match'][$blocks][$q] = substr($val, 0, $x);
$val=substr($val, $x+1);
$q++;
}
$Events['Match'][$blocks][$q] = $val;
break;
case "source":
$Events['Source'][$blocks] = $val;
break;
}
break;
}
}
}
function CleanLine($line) {
// Clean up input and remove comments
$line=trim($line);
$x=strpos($line, "#"); if (! is_numeric($x)) $x=strlen($line);
$line=substr($line, 0, $x);
$x=strpos($line, "//"); if (! is_numeric($x)) $x=strlen($line);
$line=substr($line, 0, $x);
return $line;
}
function UpdateIP($eIP, $eHits, $eTime, $eHitTime, $eName) {
global $Blocked, $Debug, $DIR;
global $IPTABLES, $Interface;
$fwTest = exec("$IPTABLES -nL autoblock | grep \" $eIP \"");
$whitelist = exec("grep ^$eIP $DIR/whitelist");
$NewDate = date("YmdHis", strtotime("+$eTime"));
if ($eHitTime < 0) $eHitTime = 0;
$HitDate = date("YmdHis", strtotime("+$eHitTime"));
if ($whitelist) {
logger("$eIP is whitelisted");
} elseif ($eHits < 1) {
// These are immediate blocks
$Blocked[$eIP]['Time'][$Blocked[$eIP]['Time'].count] = time();
if ($fwTest == "") {
// Adding new entry to iptables
// exec("$IPTABLES -A autoblock -i $Interface -s $eIP -j autoblock_drop > /dev/null 2>&1");
addIP($eIP);
Broadcast("+$eIP:$NewDate");
if ($Debug & 2) {
if ($eHits == -1) logger("Quick-block $eIP until $NewDate");
elseif ($eHits == -2) logger("Broadcast-block $eIP until $eTime");
else logger("Blocking $eIP until $NewDate (Rule=$eName)");
}
}
if ($eHits == -2) {
$Blocked[$eIP]['Expire'] = $eTime;
$Blocked[$eIP]['Count'] = -2;
} else {
$Blocked[$eIP]['Expire'] = $NewDate;
$Blocked[$eIP]['Count'] = -1;
}
} else {
// These events require multiple hits before blocking the IP address
$Blocked[$eIP]['Count']++;
$Blocked[$eIP][$Blocked[$eIP]['Time'].count] = time();
//echo " $eIP (x".$Blocked[$eIP]['Count'].")\n";
if ($Blocked[$eIP]['Count'] >= $eHits) {
if ($fwTest == "") {
// Adding new entry to iptables
// exec("$IPTABLES -A autoblock -i $Interface -s $eIP -j autoblock_drop > /dev/null 2>&1");
addIP($eIP);
Broadcast("+$eIP:$NewDate");
if ($Debug & 2) logger("Blocking $eIP (" . $Blocked[$eIP]['Count'] . "/$eHits) until $NewDate (Rule=$eName)");
}
$Blocked[$eIP]['Expire'] = $NewDate;
$Blocked[$eIP]['Count'] = -1;
} else {
$Blocked[$eIP]['Expire'] = $HitDate;
if ($Debug & 8) logger("Updating $eIP (" . $Blocked[$eIP]['Count'] . "/$eHits) ($HitDate)");
}
}
}
function addIP($IP) {
global $IPTABLES, $Interface;
exec("$IPTABLES -A autoblock -i $Interface -s $IP -j autoblock_drop > /dev/null 2>&1");
}
function logger($info) {
syslog(LOG_NOTICE, $info);
}
//----------------------------------------//
//Read config files and existing blocklist//
//----------------------------------------//
$RulesDate = filemtime($RULES);
GetRules("$RULES");
exec("touch $Blocklist");
// Set up IPTABLES
//if (exec("$IPTABLES -N autoblock 2> /dev/null; echo $?") == "0") {
exec("$IPTABLES -F autoblock 2> /dev/null");
exec("$IPTABLES -X autoblock 2> /dev/null");
exec("$IPTABLES -N autoblock 2> /dev/null");
exec("$IPTABLES -F autoblock_drop 2> /dev/null");
exec("$IPTABLES -X autoblock_drop 2> /dev/null");
exec("$IPTABLES -N autoblock_drop 2> /dev/null");
exec("$IPTABLES -A autoblock_drop -j DROP");
if (! exec("$IPTABLES -nL INPUT | grep autoblock")) exec("$IPTABLES -I INPUT -j autoblock");
$lines = file($Blocklist);
foreach ($lines as $num => $line) {
$line=CleanLine($line);
$x=strpos($line, " ");
if (! is_numeric($x)) $x=strpos($line, " ");
if (is_numeric($x)) {
$IP = trim(substr($line, 0, $x));
$Blocked[$IP]['Expire'] = trim(substr($line, $x));
$Blocked[$IP]['Count'] = -1;
exec("$IPTABLES -A autoblock -i $Interface -s $IP -j autoblock_drop > /dev/null 2>&1");
if ($Debug & 32) logger("Blocklist: $IP (" . $Blocked[$IP]['Expire'] . ")");
}
}
//----------------------------------------//
// Begin monitoring log files for events //
//----------------------------------------//
if ($Debug & 1) logger("Autoblock initialized...");
// Open filter log and jump backwards $linecount lines
$fp = fopen($Filter, "r");
$fpRef=array($fp);
fseek ($fp, 0, SEEK_END);
$pos = -2; $lc = 1; $t=" ";
$linecount = 2;
while ($t != "\n" and $lc <= $linecount) {
fseek ($fp, $pos, SEEK_END);
$t = fgetc($fp);
$pos = $pos - 1;
if ($t == "\n" and $lc < $linecount) {
fseek ($fp, $pos, SEEK_END);
$t = fgetc($fp);
$pos = $pos - 1;
$lc++;
}
}
$NextUpdate = date("YmdHis", strtotime("+$BlockUpdates seconds"));
while ( True ) {
fseek ($fp, ftell($fp), 0);
if (stream_select($fpRef, $w=null, $e=null, 0)) $line = fgets($fp, 1024);
else $line="";
if ($line == "") {
//
// pause for a moment then reset the connection and try again
//
$Now = date("YmdHis");
foreach ($Blocked as $IP => $test) {
if ($Blocked[$IP]['Expire'] < $Now) {
$log = False;
if (($Debug & 4) && ($Blocked[$IP]['Count'] < 0)) $log=True;
if (($Debug & 16) && ($Blocked[$IP]['Count'] >= 0)) $log=True;
if ($log == True) logger("$IP expired at " . $Blocked[$IP]['Expire']);
exec("$IPTABLES -D autoblock -i $Interface -s $IP -j autoblock_drop > /dev/null 2>&1");
if ($Blocked[$IP]['Count'] == -1) Broadcast("-$IP");
unset($Blocked[$IP]['Count']);
unset($Blocked[$IP]['Expire']);
unset($Blocked[$IP]['Time']);
unset($Blocked[$IP]);
}
if (is_array($Blocked[$IP]['Time'])) {
foreach ($Blocked[$IP]['Time'] as $HT => $test) {
// if time of this hit is longer than $LongestHitTime,
// remove it from the array
echo "\$Blocked[$IP]['Time'][$test] = $HT\n";
//if (time()-$HT > $LongestHitTime) { unset $Blocked[$IP]['Time'][$HT]; }
}
}
}
if (date("YmdHis") > $NextUpdate) {
if ($Debug & 128) logger("--- Updating Blocklist ---");
$wr = fopen($Blocklist, "w");
foreach ($Blocked as $IP => $test) {
if ($Blocked[$IP]['Count'] < 0) {
// Write update to file
$padIP = substr("$IP ", 0, 15);
fputs($wr, $padIP . " " . $Blocked[$IP]['Expire'] . "\n");
}
}
fclose($wr);
$NextUpdate = date("YmdHis", strtotime("+$BlockUpdates seconds"));
} else {
// Nothing else to do
clearstatcache();
$ChkDate = filemtime($RULES);
if ($ChkDate != $RulesDate) {
GetRules("$RULES");
$RulesDate = filemtime($RULES);
if ($Debug & 1) logger("$RULES has been updated.");
}
// Check for broadcast messages
if (@socket_recvfrom($socket, $msg, 256, 0, $sndIP, $sndPort)) {
if ($localIP != $sndIP) {
// logger("Broadcast Msg: $msg");
$cmd = substr($msg,0,1);
$x = strpos($msg, ":");
$mIP = substr($msg, 1, $x-1);
$mDate = substr($msg, $x+1);
switch($cmd) {
case "+":
logger("+($sndIP) $mIP until $mDate");
exec("$IPTABLES -A autoblock -i $Interface -s $mIP -j autoblock_drop > /dev/null 2>&1");
break;
case "-":
logger("-($sndIP) $mIP");
exec("$IPTABLES -D autoblock -i $Interface -s $mIP -j autoblock_drop > /dev/null 2>&1");
break;
}
}
}
usleep(200000);
}
} else {
//
// got a new line of data to process
//
$lline=strtolower($line);
//echo $line;
for($x=1; $Events['Name'][$x]!=""; $x++) {
// Test Match
$test=0; $q=0;
while ($test == 0) {
//echo $Events['Match'][$x][$q];
if (! isset($Events['Match'][$x][$q])) $test = 1;
elseif (! is_numeric(strpos($lline, $Events['Match'][$x][$q]))) $test = -1;
$q++;
}
// End Match
if ($test == 1) {
//echo "::" . $Events['Name'][$x] . "\n";
$IP = substr($line, strpos($lline, $Events['Source'][$x]) + strlen($Events['Source'][$x]));
$q = strpos($IP, "#"); if (is_numeric($q)) { $IP = substr($IP, 0, $q); }
$IP = trim($IP);
$q = strpos($IP, " "); if (is_numeric($q)) { $IP = substr($IP, 0, $q); }
//echo " $IP\n";
if (strlen($IP) < 7) $IP="";
if ($IP != "") {
UpdateIP($IP, $Events['Hits'][$x], $Events['Time'][$x], $Events['HitTime'][$x], $Events['Name'][$x]);
if (isset($Events['Domain'][$x][0])) {
$beg = strpos($lline, $Events['Domain'][$x][0]) + strlen($Events['Domain'][$x][0]);
$end = strpos($lline, $Events['Domain'][$x][1], $beg);
$Domain = substr($line, $beg, $end-$beg);
$HitIP = "|$IP|";
$HitNum = 1;
for($i=$qbLines; $i>0; $i=$i-1) {
$j = $i - 1;
$Tail['IP'][$i] = $Tail['IP'][$j];
$Tail['Domain'][$i] = $Tail['Domain'][$j];
if (($Domain == $Tail['Domain'][$i]) && ($Tail['IP'][$i] != "")) {
$test = strpos($HitIP, $Tail['IP'][$i]);
if ($test == "") {
$HitIP = $HitIP . $Tail['IP'][$i] . "|";
$HitNum++;
}
}
}
$Tail['IP'][1] = $IP;
$Tail['Domain'][1] = $Domain;
if ($HitNum >= $qbUniq) {
$HitIP = substr($HitIP, 1);
$xIP="";
while (strlen($HitIP) > 1) {
$end = strpos($HitIP, "|");
$xIP = substr($HitIP, 0, $end);
$HitIP = substr($HitIP, $end + 1);
UpdateIP($xIP, -1, $Events['Time'][$x], $Events['HitTime'][$x], $Events['Name'][$x]);
}
}
}
}
break;
}
}
}
}
?>
%%
----
CategoryDNSBlockList
#!/usr/bin/php
<?
// Autoblock v20060511
// /etc/autoblock/autoblock.php
// Copyright 2006 by Jeff Taylor
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
require('./autoblock.conf');
openlog("autoblock", LOG_PID, LOG_SYSLOG);
if ($Debug & 1) logger("Autoblock started...");
$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
socket_set_option($socket, 1, 6, TRUE);
socket_bind($socket, '255.255.255.255', $Port);
$sockRef[] =& $socket;
socket_select($sockRef, $write=NULL, $except=NULL, 0);
socket_set_nonblock($socket);
$Blocked[] = "";
$LongestHitTime = 10; // Minimum seconds to retain IP info
// declare(ticks = 1);
// pcntl_signal(SIGTERM, "sig_handler");
// pcntl_signal(SIGKILL, "sig_handler");
// pcntl_signal(SIGINT, "sig_handler");
//----------------------------------------//
// Functions //
//----------------------------------------//
function sig_handler($sig) {
// If SIGKILL is detected, shut down gracefully
fclose($fp);
closelog();
echo "Exiting autoblock\n";
exit;
}
function my_ip($dest='10.0.0.0', $port=80) {
$sckt = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
socket_connect($sckt, $dest, $port);
socket_getsockname($sckt, $addr, $port);
socket_close($sckt);
return $addr;
}
function adjTime($stamp) {
$x = 0;
while (is_numeric(substr($stamp,$x,1))) { $x++; }
$num = trim(substr($stamp, 0,$x));
$type = trim(strtoupper(substr($stamp, $x)));
switch (substr($type, 0, 2)) {
case "SE":
$newstamp = $num;
break;
case "MI":
$newstamp = $num * 60;
break;
case "HO":
case "HR":
$newstamp = $num * 3600;
break;
case "DA":
case "DY":
$newstamp = $num * 86400;
break;
case "WE":
case "WK":
$newstamp = $num * 604800;
break;
}
return $newstamp;
}
function Broadcast($data) {
global $EnableBroadcasting;
global $Port, $socket;
if ($EnableBroadcasting) {
// logger("Broadcasting: $data");
$send_ret = socket_sendto($socket, $data, strlen($data), 0, '255.255.255.255', $Port);
if($send_ret < 0) echo "sendto() failed, error: " . strerror($send_ret) . "<BR>\n";
}
}
function GetRules($filename) {
global $Debug, $Events, $LongestHitTime;
$blocks=0;
$lines = file($filename);
foreach ($lines as $num => $line) {
$line=CleanLine($line);
$x=strpos($line, "=") - 1;
$cmd=trim(substr($line, 0, $x));
$val=trim(substr($line, $x));
switch ($val) {
case "{":
$blocks++;
$Events['Name'][$blocks] = $cmd;
break;
case "}":
// End of block
break;
default:
$val=strtolower(trim(substr($val, strpos($val, "=") + 1)));
switch ($cmd) {
case "domain":
$q = 0;
while (strpos($val, "|")) {
$x=strpos($val, "|");
$Events['Domain'][$blocks][$q] = substr($val, 0, $x);
$val=substr($val, $x+1);
$q++;
}
$Events['Domain'][$blocks][$q] = $val;
break;
case "hits":
if (! is_numeric($val)) $val = 0;
$Events['Hits'][$blocks] = $val;
break;
case "hittime":
$Events['HitTime'][$blocks] = $val;
$chkTime = adjTime($val);
if ($LongestHitTime < $chkTime) { $LongestHitTime = $chkTime; }
break;
case "info":
$Events['Info'][$blocks] = $val;
break;
case "time":
$Events['Time'][$blocks] = $val;
break;
case "match":
$q = 0;
while (strpos($val, "|")) {
$x=strpos($val, "|");
$Events['Match'][$blocks][$q] = substr($val, 0, $x);
$val=substr($val, $x+1);
$q++;
}
$Events['Match'][$blocks][$q] = $val;
break;
case "source":
$Events['Source'][$blocks] = $val;
break;
}
break;
}
}
}
function CleanLine($line) {
// Clean up input and remove comments
$line=trim($line);
$x=strpos($line, "#"); if (! is_numeric($x)) $x=strlen($line);
$line=substr($line, 0, $x);
$x=strpos($line, "//"); if (! is_numeric($x)) $x=strlen($line);
$line=substr($line, 0, $x);
return $line;
}
function UpdateIP($eIP, $eHits, $eTime, $eHitTime, $eName) {
global $Blocked, $Debug, $DIR;
global $IPTABLES, $Interface;
$fwTest = exec("$IPTABLES -nL autoblock | grep \" $eIP \"");
$whitelist = exec("grep ^$eIP $DIR/whitelist");
$NewDate = date("YmdHis", strtotime("+$eTime"));
if ($eHitTime < 0) $eHitTime = 0;
$HitDate = date("YmdHis", strtotime("+$eHitTime"));
if ($whitelist) {
logger("$eIP is whitelisted");
} elseif ($eHits < 1) {
// These are immediate blocks
$Blocked[$eIP]['Time'][$Blocked[$eIP]['Time'].count] = time();
if ($fwTest == "") {
// Adding new entry to iptables
// exec("$IPTABLES -A autoblock -i $Interface -s $eIP -j autoblock_drop > /dev/null 2>&1");
addIP($eIP);
Broadcast("+$eIP:$NewDate");
if ($Debug & 2) {
if ($eHits == -1) logger("Quick-block $eIP until $NewDate");
elseif ($eHits == -2) logger("Broadcast-block $eIP until $eTime");
else logger("Blocking $eIP until $NewDate (Rule=$eName)");
}
}
if ($eHits == -2) {
$Blocked[$eIP]['Expire'] = $eTime;
$Blocked[$eIP]['Count'] = -2;
} else {
$Blocked[$eIP]['Expire'] = $NewDate;
$Blocked[$eIP]['Count'] = -1;
}
} else {
// These events require multiple hits before blocking the IP address
$Blocked[$eIP]['Count']++;
$Blocked[$eIP][$Blocked[$eIP]['Time'].count] = time();
//echo " $eIP (x".$Blocked[$eIP]['Count'].")\n";
if ($Blocked[$eIP]['Count'] >= $eHits) {
if ($fwTest == "") {
// Adding new entry to iptables
// exec("$IPTABLES -A autoblock -i $Interface -s $eIP -j autoblock_drop > /dev/null 2>&1");
addIP($eIP);
Broadcast("+$eIP:$NewDate");
if ($Debug & 2) logger("Blocking $eIP (" . $Blocked[$eIP]['Count'] . "/$eHits) until $NewDate (Rule=$eName)");
}
$Blocked[$eIP]['Expire'] = $NewDate;
$Blocked[$eIP]['Count'] = -1;
} else {
$Blocked[$eIP]['Expire'] = $HitDate;
if ($Debug & 8) logger("Updating $eIP (" . $Blocked[$eIP]['Count'] . "/$eHits) ($HitDate)");
}
}
}
function addIP($IP) {
global $IPTABLES, $Interface;
exec("$IPTABLES -A autoblock -i $Interface -s $IP -j autoblock_drop > /dev/null 2>&1");
}
function logger($info) {
syslog(LOG_NOTICE, $info);
}
//----------------------------------------//
//Read config files and existing blocklist//
//----------------------------------------//
$RulesDate = filemtime($RULES);
GetRules("$RULES");
exec("touch $Blocklist");
// Set up IPTABLES
//if (exec("$IPTABLES -N autoblock 2> /dev/null; echo $?") == "0") {
exec("$IPTABLES -F autoblock 2> /dev/null");
exec("$IPTABLES -X autoblock 2> /dev/null");
exec("$IPTABLES -N autoblock 2> /dev/null");
exec("$IPTABLES -F autoblock_drop 2> /dev/null");
exec("$IPTABLES -X autoblock_drop 2> /dev/null");
exec("$IPTABLES -N autoblock_drop 2> /dev/null");
exec("$IPTABLES -A autoblock_drop -j DROP");
if (! exec("$IPTABLES -nL INPUT | grep autoblock")) exec("$IPTABLES -I INPUT -j autoblock");
$lines = file($Blocklist);
foreach ($lines as $num => $line) {
$line=CleanLine($line);
$x=strpos($line, " ");
if (! is_numeric($x)) $x=strpos($line, " ");
if (is_numeric($x)) {
$IP = trim(substr($line, 0, $x));
$Blocked[$IP]['Expire'] = trim(substr($line, $x));
$Blocked[$IP]['Count'] = -1;
exec("$IPTABLES -A autoblock -i $Interface -s $IP -j autoblock_drop > /dev/null 2>&1");
if ($Debug & 32) logger("Blocklist: $IP (" . $Blocked[$IP]['Expire'] . ")");
}
}
//----------------------------------------//
// Begin monitoring log files for events //
//----------------------------------------//
if ($Debug & 1) logger("Autoblock initialized...");
// Open filter log and jump backwards $linecount lines
$fp = fopen($Filter, "r");
$fpRef=array($fp);
fseek ($fp, 0, SEEK_END);
$pos = -2; $lc = 1; $t=" ";
$linecount = 2;
while ($t != "\n" and $lc <= $linecount) {
fseek ($fp, $pos, SEEK_END);
$t = fgetc($fp);
$pos = $pos - 1;
if ($t == "\n" and $lc < $linecount) {
fseek ($fp, $pos, SEEK_END);
$t = fgetc($fp);
$pos = $pos - 1;
$lc++;
}
}
$NextUpdate = date("YmdHis", strtotime("+$BlockUpdates seconds"));
while ( True ) {
fseek ($fp, ftell($fp), 0);
if (stream_select($fpRef, $w=null, $e=null, 0)) $line = fgets($fp, 1024);
else $line="";
if ($line == "") {
//
// pause for a moment then reset the connection and try again
//
$Now = date("YmdHis");
foreach ($Blocked as $IP => $test) {
if ($Blocked[$IP]['Expire'] < $Now) {
$log = False;
if (($Debug & 4) && ($Blocked[$IP]['Count'] < 0)) $log=True;
if (($Debug & 16) && ($Blocked[$IP]['Count'] >= 0)) $log=True;
if ($log == True) logger("$IP expired at " . $Blocked[$IP]['Expire']);
exec("$IPTABLES -D autoblock -i $Interface -s $IP -j autoblock_drop > /dev/null 2>&1");
if ($Blocked[$IP]['Count'] == -1) Broadcast("-$IP");
unset($Blocked[$IP]['Count']);
unset($Blocked[$IP]['Expire']);
unset($Blocked[$IP]['Time']);
unset($Blocked[$IP]);
}
if (is_array($Blocked[$IP]['Time'])) {
foreach ($Blocked[$IP]['Time'] as $HT => $test) {
// if time of this hit is longer than $LongestHitTime,
// remove it from the array
echo "\$Blocked[$IP]['Time'][$test] = $HT\n";
//if (time()-$HT > $LongestHitTime) { unset $Blocked[$IP]['Time'][$HT]; }
}
}
}
if (date("YmdHis") > $NextUpdate) {
if ($Debug & 128) logger("--- Updating Blocklist ---");
$wr = fopen($Blocklist, "w");
foreach ($Blocked as $IP => $test) {
if ($Blocked[$IP]['Count'] < 0) {
// Write update to file
$padIP = substr("$IP ", 0, 15);
fputs($wr, $padIP . " " . $Blocked[$IP]['Expire'] . "\n");
}
}
fclose($wr);
$NextUpdate = date("YmdHis", strtotime("+$BlockUpdates seconds"));
} else {
// Nothing else to do
clearstatcache();
$ChkDate = filemtime($RULES);
if ($ChkDate != $RulesDate) {
GetRules("$RULES");
$RulesDate = filemtime($RULES);
if ($Debug & 1) logger("$RULES has been updated.");
}
// Check for broadcast messages
if (@socket_recvfrom($socket, $msg, 256, 0, $sndIP, $sndPort)) {
if ($localIP != $sndIP) {
// logger("Broadcast Msg: $msg");
$cmd = substr($msg,0,1);
$x = strpos($msg, ":");
$mIP = substr($msg, 1, $x-1);
$mDate = substr($msg, $x+1);
switch($cmd) {
case "+":
logger("+($sndIP) $mIP until $mDate");
exec("$IPTABLES -A autoblock -i $Interface -s $mIP -j autoblock_drop > /dev/null 2>&1");
break;
case "-":
logger("-($sndIP) $mIP");
exec("$IPTABLES -D autoblock -i $Interface -s $mIP -j autoblock_drop > /dev/null 2>&1");
break;
}
}
}
usleep(200000);
}
} else {
//
// got a new line of data to process
//
$lline=strtolower($line);
//echo $line;
for($x=1; $Events['Name'][$x]!=""; $x++) {
// Test Match
$test=0; $q=0;
while ($test == 0) {
//echo $Events['Match'][$x][$q];
if (! isset($Events['Match'][$x][$q])) $test = 1;
elseif (! is_numeric(strpos($lline, $Events['Match'][$x][$q]))) $test = -1;
$q++;
}
// End Match
if ($test == 1) {
//echo "::" . $Events['Name'][$x] . "\n";
$IP = substr($line, strpos($lline, $Events['Source'][$x]) + strlen($Events['Source'][$x]));
$q = strpos($IP, "#"); if (is_numeric($q)) { $IP = substr($IP, 0, $q); }
$IP = trim($IP);
$q = strpos($IP, " "); if (is_numeric($q)) { $IP = substr($IP, 0, $q); }
//echo " $IP\n";
if (strlen($IP) < 7) $IP="";
if ($IP != "") {
UpdateIP($IP, $Events['Hits'][$x], $Events['Time'][$x], $Events['HitTime'][$x], $Events['Name'][$x]);
if (isset($Events['Domain'][$x][0])) {
$beg = strpos($lline, $Events['Domain'][$x][0]) + strlen($Events['Domain'][$x][0]);
$end = strpos($lline, $Events['Domain'][$x][1], $beg);
$Domain = substr($line, $beg, $end-$beg);
$HitIP = "|$IP|";
$HitNum = 1;
for($i=$qbLines; $i>0; $i=$i-1) {
$j = $i - 1;
$Tail['IP'][$i] = $Tail['IP'][$j];
$Tail['Domain'][$i] = $Tail['Domain'][$j];
if (($Domain == $Tail['Domain'][$i]) && ($Tail['IP'][$i] != "")) {
$test = strpos($HitIP, $Tail['IP'][$i]);
if ($test == "") {
$HitIP = $HitIP . $Tail['IP'][$i] . "|";
$HitNum++;
}
}
}
$Tail['IP'][1] = $IP;
$Tail['Domain'][1] = $Domain;
if ($HitNum >= $qbUniq) {
$HitIP = substr($HitIP, 1);
$xIP="";
while (strlen($HitIP) > 1) {
$end = strpos($HitIP, "|");
$xIP = substr($HitIP, 0, $end);
$HitIP = substr($HitIP, $end + 1);
UpdateIP($xIP, -1, $Events['Time'][$x], $Events['HitTime'][$x], $Events['Name'][$x]);
}
}
}
}
break;
}
}
}
}
?>
%%
----
CategoryDNSBlockList