#! /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($_ = <FW>)) {
    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;
	}
    }
}
