#! /usr/bin/perl -w use strict; our %ips; # Count up how many failed passwords from each host while(defined($_ = <>)) { # (?:::ffff:) = non-capturing grouping of ::ffff: if(/Failed password for illegal user .* from (?:::ffff:)?([0-9\.]+) port [0-9]+ ssh2/) { $ips{$1}++; } } # Eliminate anything that's already been firewalled out open(FW, "iptables -L INPUT -n|") or die "$0: executing iptables: $!\n"; while(defined($_ = )) { if(/^DROP *all *-- *([0-9\.]+) *0.0.0.0\/0/) { delete $ips{$1} } } if(!close(FW)) { if($!) { die "error closing pipe to iptables: $!\n"; } die sprintf("iptables returned wait status %#x\n", $?); } # Firewall out anything that's had 5 or more failures for my $ip (keys %ips) { if($ips{$ip} >= 5) { print "*** $ips{$ip} failed passwords from $ip\n"; my $cmd = "iptables -I INPUT -s $ip -j DROP"; my $s = system($cmd); if($s == -1) { print STDERR "error executing iptables: $!\n"; } elsif($s != 0) { printf STDERR "iptables returned wstat %#x\n", $s; } } }