Fighting off a DDOS attack on an Apache web server


When it rains it pours! It’s hard enough to keep websites running without hackers trying to break in. An even worse situation is when hackers simply want you off-line. A few days ago I experienced just that… my first DDOS (distributed denial of service) attack against a high-profile website we host.

The attacker original exploited some legacy code to gain access to the web sites administration tool. After thwarting their attack, our web server immediately started to hit “max client connections”. Even after restarting Apache the max client connections were reached within seconds.

We quickly created bad routes for IP addresses associated with the hack attempts; however this did not resolve the problem. Below is the syntax we used to add bad routes.

Route add –host xxx.xxx.xxx.xxx reject

The Apache log files left no clues as to who was connecting so we had to look elsewhere. After some quick searching we found a terrific PHP script which shows which IP’s are connecting to your web server too much. The script was just want we needed. After about a ½ hour of blocking listed IP addresses the problem went away. In all we blocked a little over 100 IP addresses.

If you’re ever in a situation where Apache is clearly being flooded with connections. Run this script! It will save you a ton of time identifying the attacker(s).

– BEGIN SCRIPT –

<?php

## Functions ##

function getIP($line) {
        ereg("[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}",$line,$regMatch);
        $ip = $regMatch[0];
        if($ip) return $ip; else return "false";
}

function processString($string, $size = 18) {
        $string = "[ ".$string;
        $length = strlen($string);
        $toAdd = $size - $length;

        for($x = 0; $x < $toAdd; $x++) {
                $string = $string." ";
        }
        $string = $string."]";
        return $string;
}

## Code ##

while (true) {
        $cmd = "netstat -n | awk '{ print $5 }'";
        exec($cmd, $netstatArray);
        $ipArray = array();

        foreach($netstatArray as $line) {
                $ip = getIP($line);
                if($ip != "false" && ip != "127.0.0.1") {
                        if(array_key_exists($ip, $ipArray))
                                                 {
                                                                        $ipArray[$ip]+=1;
                                                 }
                                                 else // if not, count=1
                                                 {
                                                                        $ipArray[$ip] = 1;
                                                 }
                }
        }

        asort($ipArray);

        system("clear");
        foreach($ipArray as $ip => $count) {
                if ($count < 15)
                        continue;
                echo processString($ip);
                echo "\t" .processString(gethostbyaddr($ip), 55);
                echo "\tTimes Accessed: " .$count ."\n";
        }

        echo str_repeat("-", 50) ."\n";
        exec("top -n 1", $top_str);
        preg_match("#load average:(.+)#i", $top_str[0], $match);
        echo "Load Average: " .$match[1] ."\n";
        echo str_repeat("-", 50) ."\n";
        echo 'Showing $count >= 15: (Escape with ctrl+c)' ."\n";

        sleep(10);
}
?>
Share and Enjoy:
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  1. No comments yet.
(will not be published)
  1. No trackbacks yet.