Inhaltsverzeichnis |
Den Code habe ich mehrfach bei mir zu Hause getestet (DS408). Es wird aber an Systemfiles rumgeschrieben. Schlimmstenfalls startet der xinetd nicht mehr. Ich konnte in allen Test keine Fehler feststellen, trotzdem geht der Einsatz komplett auf die eigene Kappe
<?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); $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)))))))); ?>
Leider lässt sich der PHP Code hier im Wiki nicht als Attachment anfügen. Der Quellcode als Textdatei liegt im Forum