http://www.petefreitag.com/item/505.cfm http://software.newsforge.com/software/05/07/13/1513211.shtml blockip if the connections to apache is too large #!/usr/bin/perl $| = 1; my $port = 80; my $total = 0; my $IP_LIMIT = 90; # upper limit of httpd connections my $LOGF = "/tmp/ddos.log"; # file used to log ips my $EMAIL = 'shared@logicsupport.com'; my $DELAY = 60; my $TIMEF = '/tmp/time_file'; open FD, "+>>$LOGF" or die "$!"; select FD; open( CMD, "netstat -an|" ); while () { chomp; ($proto, undef, undef, $local_addr, $remote_addr, undef) = split(/ +/, $_, 5); ($local_ip, $local_port) = split( /:/, $local_addr ); ($remote_ip, $remote_port) = split( /:/, $remote_addr ); next if $remote_ip =~ /0.0.0.0/; next if $remote_ip =~ /59.93.43.4/; #our ip next if $remote_ip =~ /203.197.151.138/; # our ip next unless $local_port eq $port; if ($proto =~ /tcp/) { $TCP{$remote_ip}++; } else { $UDP{$remote_ip}++; } } sub check_ip_in_log { # check if the ip is already blocked my $curp = tell FD; my $ip = $_[0]; seek( FD, 0, 0 ); # rewind foreach () { return 1 if ( /$ip/ ); } seek( FD, $curp, 0 ); 0; } foreach $key (sort { $TCP{$a} <=> $TCP{$b}} keys %TCP) { if ( $TCP{$key} > $IP_LIMIT ) { unless (check_ip_in_log $key) { #system "/sbin/iptables -I INPUT -p tcp --dport 80 -s $key -j DROP"; system "/usr/local/sbin/apf -d $key"; print "$key:$TCP{$key}\n"; } else { print STDOUT "Skipping $key\n"; } } } system "/etc/init.d/httpd restart";