<?php
//Array of Protocols to search in the log files
$protocolsToWatch = array('sshd');
//Path of config directory for xinetd services
$xinetdServiceConf = '/opt/etc/xinetd.d';
//Array of filenames for xinetd services config files
$xinetdConfFiles = array('ssh');
//Path of log file
$logPath = '/opt/var/log/auth.log';
//Maximum allowed failed logins tries
$maxLogonTries = 2;
//Minimum time between last and second last failed login
$minTimeBetweenLogins = 10;
//Login Failures older than this will be ignored
$maxAgeLastLogin = 600;
/**
* Initialo function to read full content of syslog file
*
* @param string path Path of the log file
* @return array Content of Log File
*/
function getRawLog($path){
return file($path);
}
/**
* Function to filter the raw data from syslog for failed logins with defined protocols
*
* @param array $content Array of syslog lines
* @return array A array of filtered log lines
*/
function filterRecords($content){
$cont = array();
foreach($content as $wert){
if(stripos($wert,'failed') !== false){
preg_match('/.*'.$protocolsToWatch[0].'.*/',$wert,$temp);
}else{
continue;
}
//$content[] = $temp[0];
if(count($temp) > 0) $cont[] = $temp[0];
}
return $cont;
}
/**
* Function to get IP adresses and access times from filtered log lines
*
* @param array $content Array of filtered log lines
* @return array Array of IPs and Access Times => array[IP_ADDR] = array(TIME_OF_TRY,TIME_OF_TRY...)
*/
function processRecords($content){
$cont = array();
//var_dump($content);
foreach($content as $wert){
preg_match('/^([a-zA-z]*)\s(\d{1,2})\s(\d{1,2}:\d{1,2}:\d{1,2}).*?(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/',$wert,$temp);
$cont[$temp[4]][] = strtotime($temp[1].' '.$temp[2].' '.$temp[3]);
}
return $cont;
}
/**
* Function for check the log records (return of proccessRecords()) for violations of Login Rules
*
* This functions checks the log records and adds ip-addresss to be blocked if:
* * more than $maxLogonTries failed attempts to login are detected AND
* * the time difference between the last failed login and the second last is less than $minTimeBetweenLogins seconds
*
* @param array $content Array of ips and access times from syslog array[IP_ADDR] = array(TIME_OF_TRY,TIME_OF_TRY...)
* @return array Array of ips to be blocked
*/
function determineViolations($content){
$cont = array();
//var_dump($content);
//exit;
foreach($content as $key=>$wert){
if(count($wert) >= $GLOBALS['maxLogonTries']){
sort($wert);
//var_dump($wert);
//exit;
if(($wert[count($wert)-1]-$wert[count($wert)-2] < $GLOBALS['minTimeBetweenLogins']) && (time() - $wert[count($wert)-1] <= $GLOBALS['maxAgeLastLogin'])){
$cont[] = $key;
}else{
continue;
}
}
}
//var_dump($cont);
//exit;
return $cont;
}
/**
* Function to block a certain IP Adress in xinet Service Conf
*
* This function expects a array with IP addresses to block
* @param array $ip
* @return boolean true for block action and false for no block action
*/
function blockIP($ip){
//var_dump($ip);
//exit;
$block = false;
$str = '';
$content = file($GLOBALS['xinetdServiceConf'].'/'.$GLOBALS['xinetdConfFiles'][0]);
$t = array();
$schl = null;
foreach($content as $key=>$wert){
if(strpos($wert,'no_access') !== false){
preg_match_all('/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/',$wert,$t);
//var_dump($t);
//exit;
break;
}
}
//var_dump($t);
//exit;
foreach($ip as $ipp){
if(in_array($ipp,$t[0]) === false){
$block = true;
$str .= $ipp.' ';
}
}
$content[$key] = 'no_access = '.implode(' ',$t[0]).' '.$str."\n";
if($block === true){
$t = implode('',$content);
/*echo '<pre>';
echo $t;
echo '</pre>';
exit;*/
$fp = fopen($GLOBALS['xinetdServiceConf'].'/'.$GLOBALS['xinetdConfFiles'][0],'w');
fwrite($fp,$t);
fclose($fp);
exec('kill -HUP `pidof xinetd`');
return true;
}else{
return false;
}
}
var_dump(blockIP((determineViolations((processRecords(filterRecords(getRawLog($logPath))))))));
?>