Hier hab ich noch ein beispiel und ein teilcode von einem cgi das dies bestätigen könnte:
Children Process Handling
$SIG{CHLD} = sub { wait };
%hits = (); %bytes = (); %blocked = (); %second_attempts = (); ($last_minute, $last_second) = &GetTime(); while ($line = <STDIN>) { chop ($line); if ($line =~ /^.+|.+|\d+|.+$/) { ($ip, $username, $status, $site, $bytes) = split (/|/, $line); if (($username ne "-") && (($status eq "200") || ($status eq "401")) && ($ip =~ /^\d+.\d+.\d+.\d+$/)) { # Form the subnet only @ipz = split (/./, $ip); $subnet = "$ipz[0].$ipz[1].$ipz[2]";
# Regular hit if ($status eq "401") { $username = "$-PPP-$"; $subnet = $ip; $status = "200"; }
# Get the time ($this_minute, $this_second) = &GetTime();
if ($status eq "200") { # Add the hit if (defined($hits{"$site|$username|$subnet"})) { $hits{"$site|$username|$subnet"}++; $bytes{"$site|$username|$subnet"} += $bytes; $second_attempts{"$site|$username|$subnet|$this_second"}++; } else { $hits{"$site|$username|$subnet"} = 1; $bytes{"$site|$username|$subnet"} = $bytes; $second_attempts{"$site|$username|$subnet|$this_second"} = 1; }
# Check to see if this 401 exceeds the limit per second if ($username eq "$-PPP-$") { if ($second_attempts{"$site|$username|$subnet|$this_second"} >= $BAPS) { if ($blocked{"$site|$subnet"} ne "1") { &AddRule ($subnet, $site, $BAPS_TIME); $blocked{"$site|$subnet"} = "1"; } } } }
# Check the current minute if ($this_minute != $last_minute) { if (fork() == 0) { # Flush all the hits &ProcessHits (%hits, %bytes);
# Expire IP address bans &ExpireFiles();
# Exit child process exit; }
%hits = (); %bytes = (); %blocked = (); %second_attempts = (); $last_minute = $this_minute; } } } } exit;
sub ProcessHits { local ($hits, $bytes) = @_; local ($combo, $numhits); local ($query, $rin, $win, $ein, $timeout, $nfound, $timeleft) = "";
if (&EstablishConnection) { print PPP "POST /cgi-bin/ppp_server_isp.pl HTTP/1.0\n"; print PPP "Connection: Keep-Alive\n"; print PPP "User-Agent: Pennywize Password Protection/2.0\n"; print PPP "Host: online.pennywize.com\n"; print PPP "Content-type: application/x-www-form-urlencoded\n";
# Construct the content string $query = "DATA="; while (($combo, $numhits) = each (%$hits)) { ($site, $username, $ip) = split (/|/, $combo); $bytez = $$bytes{$combo} || 0; $query .= &Escape("$PENNYWIZE_USERNAME|$PENNYWIZE_PASSWORD|$site|$username|$ip|$numhits|$bytez|$PENNYWIZE_VERSION\n"); }
# Calculate the length of the content print PPP "Content-length: ".length($query)."\n";
# Print the content print PPP "\n$query\n";
# Wait for any response or max 30 seconds $rin = $win = $ein = ''; vec($rin,fileno(PPP),1) = 1; $ein = $rin | $win; $timeout = 30; ($nfound,$timeleft) = select($rout=$rin, $wout=$win, $eout=$ein, $timeout);
# Close the connection &CloseConnection; }
}
sub EstablishConnection { local ($pppaddr, $oldfh);
# Get the server address $pppaddr = ($PENNYWIZE_SERVER =~ /^(\d{1,3}).(\d{1,3}).(\d{1,3}).(\d{1,3})$/) ? pack('C4',$1,$2,$3,$4) : (gethostbyname($PENNYWIZE_SERVER))[4];
# Get the socket $proto = (getprotobyname('tcp'))[2]; if (!socket(PPP, AF_INET, SOCK_STREAM, $proto)) { return (0); }
if (!(connect(PPP, sockaddr_in($PENNYWIZE_PORT, $pppaddr)))) { return (0); }
# Unbuffer the output $oldfh = select(PPP); $| = 1; select($oldfh);
# Return Success return (1); }
sub CloseConnection { shutdown (PPP, 2); }
sub GetTime { local ($sec, $min, $ignore, $ignore, $ignore, $ignore) = localtime(time); return ($min, $sec); }
sub Escape { local ($text) = @_; local ($escapes);
return undef unless defined $text;
# Build the escape hash for (0..255) { $escapes{chr($)} = sprintf("%%%02X", $); }
# Default unsafe characters. (RFC 2396 ^uric) $text =~ s/([^;/?:@&=+$,A-Za-z0-9-_.!~*'()])/$escapes{$1}/g;
return ($text); }
sub AddRule { local ($data, $site, $time) = @_; my ($now); my ($directory) = "$CGIBIN_PATH/pennywize/$site"; my ($filename) = "$directory/$data";
# Create the sub-directory if it doesnt exist mkdir ($directory, 0777) or return ("Unable to create directory $directory") if (!(-d $directory)); chmod 0777, $directory;
# Write out the data if (!(-e $filename)) { open (OUTPUT, "> $filename") or return ("Unable to open file $filename"); close (OUTPUT); chmod 0777, $filename;
# Change the file modification time $now = time() + $time; utime $now, $now, $filename; }
# Return return ("Disable rule successfully written:\n$CGIBIN_PATH/pennywize/$site/$data\n"); }
sub ExpireFiles { local ($dir, $file, $age); local (@files) = ();
# Get all the files opendir (DIR, "$CGIBIN_PATH/pennywize"); while ($dir = readdir(DIR)) { # Test to see if it's a directory if ((-d ("$CGIBIN_PATH/pennywize/$dir")) && ($dir !~ /^./)) { # Get all files within the directory opendir (FILES, "$CGIBIN_PATH/pennywize/$dir"); while ($file = readdir(FILES)) { if (-f "$CGIBIN_PATH/pennywize/$dir/$file") { push (@files, "$CGIBIN_PATH/pennywize/$dir/$file"); } } closedir (FILES); } } closedir (DIR);
for (@files) { local ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size, $atime,$mtime,$ctime,$blksize,$blocks) = stat($_);
# Remove the block if the file has 'expired' if ((time() > $mtime) && ($size == 0)) { unlink ($_); } } }
sub WelcomeScreen { print << "EOF"; <html> <head> <title>Pennywize Online V2.0</title> </head> <body bgcolor=black> <center> <img src="http://www.pennywize.com/images/logo.gif" width=329 height=74 border=0> <p> <hr><p> <font face="arial,courier" color=white size=2> EOF }
sub TestSetup { local ($site) = @_; local ($pppaddr);
print "</center>\n"; print "<B>Perl Version:</b> $]<br>\n"; print "<B>Perl Location:</b> $^X<br><br>\n"; print "<B>Server Software:</b> $ENV{'SERVER_SOFTWARE'}<br>\n"; print "<B>Server VirtualHost:</b> $ENV{'SERVER_NAME'}<br>\n"; print "<B>Server Address:</b> $ENV{'SERVER_ADDR'}<br>\n"; print "<B>Pennywize Server:</b> $PENNYWIZE_SERVER (Resolves to ";
# Resolve the address if ($PENNYWIZE_SERVER =~ /^(\d{1,3}).(\d{1,3}).(\d{1,3}).(\d{1,3})$/) { $pppaddr = $PENNYWIZE_SERVER; } else { local ( $name, $aliases, $addrtype, $length, @address ) = gethostbyname ($PENNYWIZE_SERVER); local ( $a, $b, $c, $d ) = unpack( 'C4', $address[0] ); $pppaddr = "$a.$b.$c.$d"; }
if ($pppaddr =~ /^(\d{1,3}).(\d{1,3}).(\d{1,3}).(\d{1,3})$/) { print "$pppaddr)<br>\n"; } else { print "<font color=red>Can't Resolve - Check DNS Settings</font>)<br>\n"; exit; } print "<B>Pennywize Version:</b> $PENNYWIZE_VERSION<br>\n"; print "<B>Document Root:</b> $ENV{'DOCUMENT_ROOT'}<br><br>\n"; print "<B>Script Location:</B> $ENV{'SCRIPT_FILENAME'}<br>\n"; print "<B>CGI-BIN Path:</B> $CGIBIN_PATH<br><br>\n";
exit if (length($CGIBIN_PATH) == 0);
# Check to see if the 'pennywize' directory exists print "<B>Checking for pennywize sub directory:</b> "; if (!(-d "$CGIBIN_PATH/pennywize")) { print "<font color=red>Failed!</font><br>\n"; exit; } else { print "<font color=green>Success!</font><br>\n"; }
# Make sure the pennywize directory is writeable print "<B>Making sure pennywize directory is writeable:</b> "; if (!(-w "$CGIBIN_PATH/pennywize")) { print "<font color=red>Failed!</font><br>\n"; exit; } else { print "<font color=green>Success!</font><br>\n"; }
# CustomLog line print "<p><P>\n"; print "<B>Add these lines to your httpd.conf file</B><br>(Inside the corresponding VirtualHost for your site or members section><br><hr>\n"; print "<font face="arial,courier" size=1>\n"; print << "EOF";
# Pennywize Online (http://www.pennywize.com)<br> RewriteEngine on<br> CustomLog "| $CGIBIN_PATH/pennywize.cgi" "%a|%u|%s|$site|%b"<br> RewriteCond $CGIBIN_PATH/pennywize/$site/%{LA-U:REMOTE_USER} -f [OR]<br> RewriteCond $CGIBIN_PATH/pennywize/$site/%{REMOTE_ADDR} -f<br> RewriteRule ^/.$ http://www.pennywize.com/blocked.html [L,R]<br> <hr> EOF
}
sub SplitPath { my ($path) = @_; my ($directory,$file) = ('','','');
$path =~ m|^ ( (?: .* / (?: ..?\z )? )? ) ([^/]*) |xs; return ($1, $2); }