PHP Classes

File: include/Stats.php

Recommend this page to a friend!
  Classes of Rolands Kusins   PHP Block Host   include/Stats.php   Download  
File: include/Stats.php
Role: Class source
Content type: text/plain
Description: Class for statistic calculation
Class: PHP Block Host
Parse logs and block suspicious hosts
Author: By
Last change: Small update to avoid some PHP Notices/Warnings.
Date: 9 years ago
Size: 13,097 bytes
 

Contents

Class file image Download
<?php /** * HostBlock statistics calculation and output class * * @author Rolands Kusiņš * @license GPL * */ class Stats{ // Path to file with IP info public $suspiciousIpsPath = ""; // Object for writing to log files public $log = null; // How many matches must an IP have to be in blacklist public $suspiciousEntryMatchCount = 5; // For how long time to keep IP in blacklist public $blacklistTime = 0; // Array with IP information public $ipInfo = array(); // Array with statistics data private $data = array(); // Permanent blacklist file public $permanentBlacklistFile = ""; // Permanent whitelist file public $permanentWhitelistFile = ""; // IPs from blacklist file private $include = array(); // IPs from whitelist file private $exclude = array(); // Datetime format public $dateTimeFormat = "Y-m-d H:i:s"; /** * Load IP addresses that we need to perminately include or exclude from blacklist */ public function loadBlacklist(){ // Clear blacklist/whitelist arrays $this->include = array(); $this->exclude = array(); // Read blacklist if(!is_null($this->permanentBlacklistFile)){ $f = @fopen($this->permanentBlacklistFile,"r"); if($f){ while(!feof($f)){ $line = trim(fgets($f,4096)); if(ip2long($line) !== false){ if(!in_array($line,$this->include)){ $this->include[] = $line; } else{ $this->log->write("Duplicate IP address ".$line." in permanent blacklist file!"); } } } @fclose($f); } } // Read whitelist if(!is_null($this->permanentWhitelistFile)){ $f = @fopen($this->permanentWhitelistFile,"r"); if($f){ while(!feof($f)){ $line = trim(fgets($f,4096)); if(ip2long($line) !== false){ if(!in_array($line,$this->exclude)){ $this->exclude[] = $line; } else{ $this->log->write("Duplicate IP address ".$line." in permanent whitelist file!"); } } } @fclose($f); } } } /** * Load data about suspicious IP addresses */ public function load(){ // Read IP data $data = @file_get_contents($this->suspiciousIpsPath); if($data != false){ $this->ipInfo = unserialize($data); } else{ $this->log->write("Unable to load IP data!","error"); } } /** * Calculate statistics */ public function calculate(){ $this->data = array(); $currentTime = time(); if(count($this->ipInfo) > 0){ // Init array $this->data['blacklisted_ip_count'] = count($this->include); $this->data['top5'] = array(); $this->data['top5']['ip'] = array(); $this->data['top5']['count'] = array(); $this->data['top5']['refused'] = array(); $this->data['top5']['lastactivity'] = array(); $this->data['last5'] = array(); $this->data['last5']['ip'] = array(); $this->data['last5']['count'] = array(); $this->data['last5']['refused'] = array(); $this->data['last5']['lastactivity'] = array(); // Loop through all IP addresses foreach($this->ipInfo as $k => $v){ if(!isset($v['refused'])) $v['refused'] = 0; // Blacklisted IP address count if($v['count'] >= $this->suspiciousEntryMatchCount && (($currentTime - $v['lastactivity']) <= $this->blacklistTime || $this->blacklistTime == 0) && !in_array($k,$this->exclude)){ $this->data['blacklisted_ip_count']++; } // Last 5 IP addresses if(isset($v['lastactivity'])){ if(count($this->data['last5']['ip']) < 5){ // First we fill up last5 array $this->data['last5']['ip'][] = $k; $this->data['last5']['count'][] = $v['count']; $this->data['last5']['refused'][] = $v['refused']; $this->data['last5']['lastactivity'][] = $v['lastactivity']; } else{ // Then we update with IP addresses that have more recent activity $keys = array_keys($this->data['last5']['lastactivity'],min($this->data['last5']['lastactivity'])); if(count($keys) > 0){ if($this->data['last5']['lastactivity'][$keys[0]] < $v['lastactivity']){ $this->data['last5']['ip'][$keys[0]] = $k; $this->data['last5']['count'][$keys[0]] = $v['count']; $this->data['last5']['refused'][$keys[0]] = $v['refused']; $this->data['last5']['lastactivity'][$keys[0]] = $v['lastactivity']; } } } } // Get top 5 IP addresses by count if(count($this->data['top5']['ip']) < 5){ // First we fill up top5 array $this->data['top5']['ip'][] = $k; $this->data['top5']['count'][] = $v['count']; $this->data['top5']['refused'][] = $v['refused']; $this->data['top5']['lastactivity'][] = $v['lastactivity']; } else{ // Then we update with IP addresses that have more suspicious activity $keys = array_keys($this->data['top5']['count'],min($this->data['top5']['count'])); if(count($keys) > 0){ if($this->data['top5']['count'][$keys[0]] < $v['count']){ $this->data['top5']['ip'][$keys[0]] = $k; $this->data['top5']['count'][$keys[0]] = $v['count']; $this->data['top5']['refused'][$keys[0]] = $v['refused']; $this->data['top5']['lastactivity'][$keys[0]] = $v['lastactivity']; } } } } // Sort top 5 array array_multisort($this->data['top5']['count'], SORT_DESC, $this->data['top5']['ip'], $this->data['top5']['lastactivity'], $this->data['top5']['refused']); // Sort last 5 array array_multisort($this->data['last5']['lastactivity'], SORT_DESC, $this->data['last5']['ip'], $this->data['last5']['count'], $this->data['last5']['refused']); } } /** * Echo statistics */ public function output(){ if(count($this->ipInfo) > 0){ echo "\n"; echo "Total suspicious IP address count: ".count($this->ipInfo)."\n"; echo "Blacklisted IP address count: ".$this->data['blacklisted_ip_count']."\n"; echo "\n"; echo "Top 5 most active IP addresses:\n"; $countPadLength = strlen($this->data['top5']['count'][0]); if($countPadLength < 5) $countPadLength = 5; $refusedPadLength = 7; $dateTimePadLength = 13; foreach($this->data['top5']['refused'] as $k => $v){ if(strlen($v) > $refusedPadLength) $refusedPadLength = strlen($v); if(strlen(date($this->dateTimeFormat, $this->data['top5']['lastactivity'][$k])) > $dateTimePadLength) $dateTimePadLength = strlen(date($this->dateTimeFormat, $this->data['top5']['lastactivity'][$k])); } echo "-------------------".str_repeat("-", $countPadLength).str_repeat("-", $refusedPadLength).str_repeat("-", $dateTimePadLength)."-------\n"; echo " IP | ".str_pad("Count",$countPadLength," ",STR_PAD_BOTH)." | ".str_pad("Refused",$refusedPadLength," ",STR_PAD_BOTH)." | ".str_pad("Last activity",$dateTimePadLength," ",STR_PAD_BOTH)."\n"; echo "-------------------".str_repeat("-", $countPadLength).str_repeat("-", $refusedPadLength).str_repeat("-", $dateTimePadLength)."-------\n"; foreach($this->data['top5']['ip'] as $k => $v){ echo " ".str_pad($v,15," ")." | ".str_pad($this->data['top5']['count'][$k],$countPadLength," ",STR_PAD_BOTH)." | ".str_pad($this->data['top5']['refused'][$k],$refusedPadLength," ",STR_PAD_BOTH)." | ".str_pad(date($this->dateTimeFormat, $this->data['top5']['lastactivity'][$k]),$dateTimePadLength," ")."\n"; } echo "-------------------".str_repeat("-", $countPadLength).str_repeat("-", $refusedPadLength).str_repeat("-", $dateTimePadLength)."-------\n"; echo "\n"; echo "Last activity:\n"; $countPadLength = strlen($this->data['last5']['count'][0]); if($countPadLength < 5) $countPadLength = 5; $refusedPadLength = 7; $dateTimePadLength = 13; foreach($this->data['last5']['refused'] as $k => $v){ if(strlen($v) > $refusedPadLength) $refusedPadLength = strlen($v); if(strlen(date($this->dateTimeFormat, $this->data['last5']['lastactivity'][$k])) > $dateTimePadLength) $dateTimePadLength = strlen(date($this->dateTimeFormat, $this->data['last5']['lastactivity'][$k])); } echo "-------------------".str_repeat("-", $countPadLength).str_repeat("-", $refusedPadLength).str_repeat("-", $dateTimePadLength)."-------\n"; echo " IP | ".str_pad("Count",$countPadLength," ",STR_PAD_BOTH)." | ".str_pad("Refused",$refusedPadLength," ",STR_PAD_BOTH)." | ".str_pad("Last activity",$dateTimePadLength," ",STR_PAD_BOTH)."\n"; echo "-------------------".str_repeat("-", $countPadLength).str_repeat("-", $refusedPadLength).str_repeat("-", $dateTimePadLength)."-------\n"; foreach($this->data['last5']['ip'] as $k => $v){ echo " ".str_pad($v,15," ")." | ".str_pad($this->data['last5']['count'][$k],$countPadLength," ",STR_PAD_BOTH)." | ".str_pad($this->data['last5']['refused'][$k],$refusedPadLength," ",STR_PAD_BOTH)." | ".str_pad(date($this->dateTimeFormat, $this->data['last5']['lastactivity'][$k]),$dateTimePadLength," ")."\n"; } echo "-------------------".str_repeat("-", $countPadLength).str_repeat("-", $refusedPadLength).str_repeat("-", $dateTimePadLength)."-------\n"; echo "\n"; } else{ echo "No data!\n"; } } /** * Echo all blacklisted IP addresses */ public function outputBlacklist($count = false, $time = false){ $currentTime = time(); if(count($this->ipInfo) == 0 && count($this->include) == 0){ echo "No data!\n"; return; } // All automatically blacklisted IP addresses if(count($this->ipInfo) > 0){ // Find max count value $maxCount = 0; $maxRefused = 0; foreach($this->ipInfo as &$ip){ if($ip['count'] > $maxCount) $maxCount = $ip['count']; if(isset($ip['refused']) && $ip['refused'] > $maxRefused) $maxRefused = $ip['refused']; } $countPadLength = strlen($maxCount); $refusedPadLength = strlen($maxRefused); // Loop through all suspicious IP addresses foreach($this->ipInfo as $k => $v){ if($v['count'] >= $this->suspiciousEntryMatchCount && (($currentTime - $v['lastactivity']) <= $this->blacklistTime || $this->blacklistTime == 0) && !in_array($k,$this->exclude)){ if(in_array($k,$this->include)){ $this->log->write("IP address ".$k." is blacklisted by hostblock and is also included in permanent blacklist! Consider removing duplicate from permanent blacklist!"); continue; } echo "a "; echo str_pad($k,15); if($count == true){ echo " ".str_pad($v['count'],$countPadLength," "); if(isset($v['refused'])) echo " ".str_pad($v['refused'],$refusedPadLength," "); else echo " ".str_pad("0",$refusedPadLength," "); } if($time == true){ echo " ".date($this->dateTimeFormat, $v['lastactivity']); } echo "\n"; } } } // All manually blacklisted IP addresses if(count($this->include) > 0){ foreach($this->include as &$ip){ echo "m "; echo str_pad($ip,15); if($count == true){ if(isset($this->ipInfo[$ip])){ echo " ".str_pad($this->ipInfo[$ip]['count'],$countPadLength," "); if(isset($this->ipInfo[$ip]['refused'])) echo " ".str_pad($this->ipInfo[$ip]['refused'],$refusedPadLength," "); else echo " ".str_pad("0",$refusedPadLength," "); } else{ echo " ".str_pad("0",$countPadLength," "); echo " ".str_pad("0",$refusedPadLength," "); } } if($time == true){ if(isset($this->ipInfo[$ip])){ echo " ".date($this->dateTimeFormat, $this->ipInfo[$ip]['lastactivity']); } } echo "\n"; } } } /** * Get blacklisted IP addresses * * @return array */ public function getBlacklistedIps(){ $currentTime = time(); $result = array(); if(count($this->ipInfo) > 0){ foreach($this->ipInfo as $k => $v){ if($v['count'] >= $this->suspiciousEntryMatchCount && (($currentTime - $v['lastactivity']) <= $this->blacklistTime || $this->blacklistTime == 0) && !in_array($k,$this->exclude)){ if(in_array($k,$this->include)){ $this->log->write("IP address ".$k." is blacklisted by hostblock and is also included in permanent blacklist! Consider removing duplicate from permanent blacklist!"); continue; } $result[] = $k; } } } foreach($this->include as $ip){ $result[] = $ip; } return $result; } /** * Get blacklisted IP address count * * @return number */ public function getBlacklistedIpCount(){ $currentTime = time(); $count = count($this->include); if(count($this->ipInfo) > 0){ foreach($this->ipInfo as $k => $v){ if($v['count'] >= $this->suspiciousEntryMatchCount && (($currentTime - $v['lastactivity']) <= $this->blacklistTime || $this->blacklistTime == 0) && !in_array($k,$this->exclude)){ if(in_array($k,$this->include)){ $this->log->write("IP address ".$k." is blacklisted by hostblock and is also included in permanent blacklist! Consider removing duplicate from permanent blacklist!"); continue; } $count++; } } } return $count; } /** * Get total refused connect count * * @return number */ public function getTotalRefusedConnectCount(){ $count = 0; if(count($this->ipInfo) > 0){ foreach($this->ipInfo as $ip){ if(isset($ip['refused'])){ $count += $ip['refused']; } } } return $count; } } ?>