#!/usr/local/bin/php -q
<?php
class Sentinel{
var $loadlimit = 15; // server's load limit before Sentinel assumes a DoS attack & kicks in
var $conlimit = 80; // number of connections an IP can have during a DoS attack before Sentinel gets suspicious...
var $ignore = "127.0.0.1, xx.xx.xx.xx"; // ignore these IP's - add your own! - Also, if your using a remote SQL server, add it.
var $path = '/etc/apf/'; // Full path to APF Firewall directory, with trailing slashes
var $rate = 60; // in seconds, how frequently should sentinel check your server load
var $email = 'your@email.tld'; // your email - where logs are sent
function goodload(){
$shell=shell_exec('uptime');
if(eregi('averages',$shell)){
$shell=explode("load averages:",$shell);
} else{
$shell=explode("load average:",$shell);
}
$loads=trim($shell[1]);
$loads=explode(" ",$loads);
$myload=$loads[0];
if($myload>$this->loadlimit){
return 0;
} else{
return 1;
}
}
function ignore($ip){
$ips=explode(",",$this->ignore);
for($i=0;$i<=count($ips)-1;$i++){
$ignore[]=trim($ips[$i]);
}
$rules=file_get_contents($this->path.'deny_hosts.rules');
$rules=explode("\n",$rules);
foreach($rules as $rule){
if(!eregi('#', $rule)){
$ignore[]=$rule;
}
}
foreach($ip as $i){
if(!in_array($i,$ignore)){
$good[]=$i;
}
}
return $good;
}
function restartapf(){
ob_start();
$sh=shell_exec("{$this->path}apf -r");
if($sh){return 1;} else{
return 0; }
ob_end_clean();
}
function banip($ip){
$handle=fopen($this->path.'deny_hosts.rules', "a");
fwrite($handle,"\n".$ip);
fclose($handle);
return 1;
}
function getattackers(){
$shell=shell_exec('netstat -ntu | awk \'{print $5}\' | cut -d: -f1 | sort | uniq -c | sort -nr | more');
//$pattern="/.{1,} [1-9]{1,3}\.[1-9]{1,3}\.[1-9]{1,3}\.[1-9]{1,3}/";
//preg_match_all($pattern, $shell,$out);
//$ips=$out[0];
$gips=explode("\n",$shell);
foreach($gips as $wip){
if(eregi('.',$wip)){
$ips[]=trim($wip);
}
}
foreach($ips as $ip){
$ip=explode(" ",$ip);
if( ($ip[0]>=$this->conlimit) ){
$killthem[]=$ip[1];
}
}
if( eregi('warning, got duplicate',$killthem) ){
return 0;
}
$killthem=@$this->ignore($killthem);
return $killthem;
}
function report($ips){
foreach($ips as $ip){
$rip .= "$ip\n";
}
$subject = "YOUR SERVER WAS ATTACKED!";
$headers= "From: SENTINEL <SENTINEL@Protection.omg";
$body= "Omega Sentinel V2 has detected a (D)Dos attack against your server. The following IP's have been blocked:\n:\n-------------\n$rip\n------------";
mail($this->email,$subject,$body,$headers);
}
function guard(){
do{
sleep($this->rate);
$load=$this->goodload();
if(!$load){
echo '.';
$ips=$this->getattackers();
if($ips){
foreach($ips as $ip){
$this->banip($ip);
}
$this->restartapf();
$this->report($ips);
}
}
} while(1>0);
}
}
$Sentinel=new Sentinel;
$Sentinel->guard();
?>