#!/usr/bin/php -q netstat.out" exec( $netstatCmd." > ".$netstatOutput); // Read the file into an array of lines $lines = file( $netstatOutput ); foreach ( $lines as $line_num => $line ) { // Only parse line if the first 3 chars are TCP (or UDP?) if ( eregi( "(tcp)|(udp)", $line ) ) { // A very important line, DO NOT TOUCH! $regexp = "(tcp|udp|raw)([[:space:]]+)([0-9]+)([[:space:]]+)([0-9]+)([[:space:]]+)([0-9\.:\*]+)([[:space:]]+)([0-9\.:\*]+)([[:space:]]+)([A-Za-z0-9_]+)([[:space:]]+)([0-9]+)([[:space:]]+)([0-9]+)([[:space:]]+)(.+)"; $args = array(); if ( eregi( $regexp, $line, $args ) ) { $connections[$num] = new NetStatInfo(); $localaddr = explode(":", $args[7]); $foreignaddr = explode(":", $args[9]); $connections[$num]->proto = $args[1]; $connections[$num]->recvq = $args[3]; $connections[$num]->sendq = $args[5]; $connections[$num]->localaddr[0] = $localaddr[0]; $connections[$num]->localaddr[1] = $localaddr[1]; $connections[$num]->foreignaddr[0] = $foreignaddr[0]; $connections[$num]->foreignaddr[1] = $foreignaddr[1]; $connections[$num]->state = $args[11]; $connections[$num]->user = $args[13]; $connections[$num]->inode = $args[15]; // TODO: Parse program info, into program name and pid (seperator = /) $connections[$num]->pid = $args[17]; $connections[$num]->program = $args[17]; $num++; } } } // Counter array - for every new ip found - it will be added to the array, and its counter incremented // i.e. $counter[0][0] = 192.168.1.100 // $counter[0][1] = 13 $counter = array(); $num_conns = $num; $num = 0; // Flag to determine if the IP was found in the counter. $found = false; // Check for multiple connections on the following local ports. // *** Now a configuration setting at top // Determine if there are multiple records! for ( $i = 0; $i < $num_conns; $i++ ) { $found = false; for ( $j = 0; $j < count( $counter ); $j++ ) { if ($counter[$j][0] == $connections[$i]->foreignaddr[0] && in_array($connections[$i]->localaddr[1], $ports) && ($connections[$i]->status != "TIME_WAIT")) { // IP already exists in counter array, (incr. count) $counter[$j][1]++; $found = true; } } if ( !$found ) { if ( in_array( $connections[$i]->localaddr[1], $ports ) ) { // IP wasn't found in counter array, so add it. $counter[$num] = array(); $counter[$num][0] = $connections[$i]->foreignaddr[0]; $counter[$num][1] = 1; $num++; } } } // Flag to denote an IP was banned $banned = false; $bancount = 0; // Use the counter array to ban any users over X connections for ( $i = 0; $i < count( $counter ); $i++ ) { if ( $counter[$i][1] > $maxConnsPerIP ) { // BAN IP IN APF exec($apfDeny . $counter[$i][0]); // Add comment to APF deny_hosts.rules $apfComment = "echo \"# {AntiDoS - ".$counter[$i][0]."\t- ".$counter[$i][1]." open connections\t- ".date($dateFormat)."}\""; exec($apfComment . " >> " . $apfDenyHostRules); $banned = true; $logComment = "echo \"** Banned " . $counter[$i][0] . " - " . $counter[$i][1] . " open connections. (" . date($dateFormat) . ")\" >> " . $logRoot . $logNameBan; exec($logComment); $bancount++; } } if ( $banned ) { exec("echo \"\tBanned a total of $bancount IPs.\" >> " . $logRoot . $logNameRun); exec("echo \"\tRestarting APF\" >> " . $logRoot . $logNameRun); exec("service apf restart"); } exec( "echo -e \"Test complete: ".date($dateFormat)."\n----------------\" >> ".$logRoot.$logNameRun );