TuX as LLG logo
Software
DMX4Linux
Driver Suite for Linux
csv2iif.pl suite
convert PayPal transactions to IIF, OFX, QIF
Hardware
DMX30 Interface
128Ch SPP
DMX43 Interface
2out 2in EPP
LED Hardware
for Linux and Windows
EPROM Sampler
for 8 bits of sound
Misc
CatWeasel
Linux drivers for MK3/4 PCI
pg_trompe
PostgreSQL replication
trycatch
C exception/signal handling lib
Patches
to various software
Tools
and small scripts
Docs
misc documents
Links
to lighting stuff

sshhackfilter

This is my perl script solution to set Linux iptables rules when remote hosts try to login into SSH accounts on your computer. It reads the syslog.

#!/usr/bin/env perl

use vars qw(%ip %iplast $blocked $interface $prog);

my $logfile="/var/log/messages";
$interface="ppp0";

######################################################################

use strict;

$prog="sshhackfilter["."$$]";
my $run=1;

open(A, "tail -f $logfile|") or die "could not tail $logfile";

END
{
    close(A);
    foreach my $i (keys %ip)
    {
	if($ip{$i}>=10)
	{
	    unblock($i);
	}
    }
    system("logger -t $prog exit. Blocked $blocked IPs");
}

sub sighandler
{
    $run=0;
    system("logger -t $prog caught a signal");
}
$SIG{HUP} = \&sighandler;
$SIG{INT} = \&sighandler;
$SIG{TERM} = \&sighandler;

sub usrhandler
{
  my @k=keys %ip;
  system("logger -t $prog blocking 0 IPs") if $#k==-1;
  foreach my $i (@k)
    {
      if($ip{$i}>=10)
	{
	  system("logger -t $prog blocking $i");
	}
    }
}
$SIG{USR1} = \&usrhandler;

system("logger -t $prog start");
while($run)
{
    while(<A>)
    {
	exit 0 unless $run;

	if(/Failed password for (invalid user)?.+ from (\d+\.\d+\.\d+\.\d+) port \d+ ssh2/)
	{
	    block($2);
	}
	elsif(/ntpd\[\d+\]: sendto\((\d+\.\d+\.\d+\.\d+)\): Invalid argument/)
	{
	    block($1);
	}
    }
}

sub block
{
    my ($i) = @_;
    my $t=time();

    # after 1day we monitor an ip again
    if(exists($iplast{$i}))
    {
	undef $ip{$i} if $t > $iplast{$i}+86400;
    }
    $iplast{$i}=$t;

    # upon the 10th failed login we block this ip
    if(++$ip{$i} == 10)
    {
	system("iptables -A INPUT -j REJECT -i $interface -s $i");
	$blocked++;
	usrhandler();
    }

    # unblock some old IPs
    foreach $i (keys %ip)
    {
	if($ip{$i}>=10 && $t > $iplast{$i}+86400)
	{
	    unblock($i);
	    undef $iplast{$i};
	    undef $ip{$i};
	    usrhandler();
	}
    }
}

sub unblock
{
    my ($i) = @_;
    system("logger -t $prog unblocking IP $i");
    system("iptables -D INPUT -j REJECT -i $interface -s $i");
}

System startup

I use the following startup script to start and stop sshhackfilter as a system service. It utilizes the daemon program for process control.

#!/bin/sh

# chkconfig: 2345 90 10
# description: sshhackfilter

PROG=sshhackfilter

case "$1" in
    start)
	echo "Starting $PROG"
	daemon -n ${PROG} /usr/sbin/$(PROG)
	;;

    stop)
        echo "Stopping $PROG"
	daemon -n $PROG --stop
        ;;

    restart)
	daemon -n $PROG --stop
	sleep 3
	daemon -n $PROG /usr/sbin/$PROG
	;;

    status)
	PID=`ps ax|grep $PROG|grep perl|awk '{print $1}'`
	if [ "$PID" ] ; then
	    kill -s SIGUSR1 $PID
	    logger test
	    sleep 1 ; echo 1
	    tail /var/log/messages | grep $PROG
	else
	    echo $PROG seems not running.
	fi
	;;

    *)
	echo "Usage: $PROG {start|stop|restart|status}"
	exit 1
	;;
esac

Search:
https://llg.cubic.org © 2001-2024 by Dirk Jagdmann