fail2ban would surely be the best bet here. It's based on Python but does
exactly what you're describing and does it well...as long as your web app
logs requests in a file somewhere.

On Jan 23, 2018 17:39, "SurfShop" <contactat...@surfshopcart.com> wrote:

>         I'm working on adding anti-hammering code to SurfShop to be able
> to temporarily ban visitors if they enter certain "keywords" into the query
> string, or if they repeatedly hammer the cart.  I've also set it up to be
> able to permanently block foreign IP's of the store owner's choosing.  Each
> country's IPs are in separate text files and the temp IPs are in another,
> so there could be quite a few files.  The temporary IPs also have a date
> associated with them, so they can be deleted later on.
>
>         I decided to go with Net::Netmask for CIDR blocks but it's
> excruciatingly slow - it adds 2+ seconds to each page load in the cart.
> That's a deal breaker.  If I remove the Net::Netmask section, the delay
> drops to about 1 second per page, but that's still visibly slower than
> without this sub.
>
>         So I got the idea to keep track of the last 10?, 30?, 50? good IP
> addresses and not process those again after the first visit.  The first
> page view gets the delay, but subsequent page speeds are normal.  I've
> included my code below and I'm wondering what the problem is.  Did I code
> something wrong?  Did I choose the wrong module?  Perhaps I'm looking at
> this incorrectly.  Is there a better way to do what I'm after?
>
>         The lines in the IP text files can be in any of these formats:
>
> 23.254.251.87
> 60.1.33.
> 41.96.0.0/12
> 11.22.33.44  2018-01-23
>
> Thanks,
> Frank
>
>
>
> sub banned_ip_check($current_ip) {
>   return unless $current_ip;
>   my @ips = read_last_visitor_ips();  ## Last X visitors.
>   foreach my $ip (@ips) {
>      chomp $ip;
>      return if $ip eq $current_ip;    ## Only check the IP on first visit.
>   }
>   my $t2 = Time::Piece->new();  ## Today's date to compare with saved date.
>   my @files = File::Find::Rule->file()
>                        ->name('*.txt')
>                        ->in("${data_dir}/banned_ips");
>   foreach my $ip_file (@files) {
>      open (my $ip_fh, '<', $ip_file) || SSLib::error("Xtras::banned_ip_check:
> Can't open $ip_file");
>      while (my $line = <$ip_fh>) {
>         chomp $line;
>         my ($ip, $date) = split (/\s/, $line);
>         my $process = 'yes';
>         if ($date =~ m/\d+/) {
>            $t1 = Time::Piece->strptime($date, "%Y-%m-%d");
>            if (($t2 - $t1) > 2_600_000) { $process = 'no' }
>         }
>         my $long = length($ip);
>         my $found;
>         if ($ip =~ m|/\d{2}$|) {
>            ## CIDR IP Addresses
>            my $block = Net::Netmask->new($ip);
>            $found = 'yes' if $block->match($current_ip);
>         }
>         if ($found || $process eq 'yes' && substr($current_ip, 0, $long)
> eq $ip) {  ## Match partial IP's, too.
>            deny_entry($current_ip, 'IP address', $ip_file);
>         }
>      }
>      close ($ip_fh);
>   }
> }
>
> --
> To unsubscribe, e-mail: beginners-unsubscr...@perl.org
> For additional commands, e-mail: beginners-h...@perl.org
> http://learn.perl.org/
>
>
>

Reply via email to