Installing Sshblack on Linux

Sshblack is a script for blocking attempts to brute-force crack SSH passwords on a linux system. It monitors the system security log to detect multiple attempts to log in from a given source and, when seen, uses iptables to block subsequent attempts from being presented to sshd. One advantage of this is that the system logs don't get overfilled with failed login attempts.

1. Configuring sshblack for RedHat Enterprise 4 Linux

The following sequence is executed as root user.

  1. Download sshblack from http://www.sshblack.com/

  2. Unpack the tar file into a working directory, and check that an executable file sshblackv28.pl is created. I have used /usr/local/sbin/sshblackv28; the sshblack installation suggests /usr/src/sshblack. E.g.:

    • [root@luggage sshblack]# cd /usr/local/sbin/sshblackv28 
      [root@luggage sshblack]# tar xvzf /file/kit/TUXKIT/SSHBlack/sshblackv28.tar.gz 
      bl
      INSTALL.TXT
      iptables-setup.sh
      README.TXT
      sshblack.pl
      sshblack-start.sh
      unbl
      [root@luggage sshblack]# ls -al
      total 116
      drwx------  2 root root  4096 Dec 11 12:01 .
      drwxr-xr-x  3 root root  4096 Dec 11 11:52 ..
      -rwxrwxr-x  1 root root   263 Aug 10 06:07 bl
      -rw-rw-r--  1 root root 24731 Aug  6 18:23 INSTALL.TXT
      -rwxrwxr-x  1 root root   447 Aug 10 05:18 iptables-setup.sh
      -rw-rw-r--  1 root root 14742 Aug  6 18:01 README.TXT
      -rwxr-xr-x  1 root root 11487 Aug 10 06:46 sshblackv.pl
      -rwxrwxr-x  1 root root   223 Aug 10 05:18 sshblack-start.sh
      -rwxrwxr-x  1 root root   278 Aug 10 06:07 unbl
      
  3. Ensure perl is installed; e.g.
    • [root@luggage sshblack]# perl --version 
      
      This is perl, v5.8.5 built for i386-linux-thread-multi
       :
      (etc.)
      
  4. Ensure iptables is installed and running; e.g.
    • root@luggage sshblack]# iptables --list 
      Chain INPUT (policy ACCEPT)
      target     prot opt source               destination         
      RH-Firewall-1-INPUT  all  --  anywhere             anywhere            
      
      Chain FORWARD (policy ACCEPT)
      target     prot opt source               destination         
      RH-Firewall-1-INPUT  all  --  anywhere             anywhere            
      
      Chain OUTPUT (policy ACCEPT)
      target     prot opt source               destination         
      
      Chain RH-Firewall-1-INPUT (2 references)
      target     prot opt source               destination         
      ACCEPT     all  --  anywhere             anywhere            
      ACCEPT     icmp --  anywhere             anywhere            icmp any 
      ACCEPT     ipv6-crypt--  anywhere             anywhere            
      ACCEPT     ipv6-auth--  anywhere             anywhere            
      ACCEPT     udp  --  anywhere             224.0.0.251         udp dpt:5353 
      ACCEPT     udp  --  anywhere             anywhere            udp dpt:ipp 
      ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED 
      ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:http 
      ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:https 
      ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:ssh 
      ACCEPT     udp  --  anywhere             anywhere            state NEW udp dpt:domain 
      ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:domain 
      ACCEPT     udp  --  anywhere             anywhere            state NEW udp dpt:bootps 
      ACCEPT     udp  --  anywhere             anywhere            state NEW udp dpt:netbios-ns 
      ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:netbios-ns 
      ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:netbios-ssn 
      ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:ipp 
      ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:rsync 
      REJECT     all  --  anywhere             anywhere            reject-with icmp-host-prohibited 
      
  5. This step can be skipped if creating the init.d script described below. Create a new iptables chain called BLACKLIST, add this to the start of the INPUT chain for incoming TCP data on port 22 (SSH), and save the resulting iptables configuration:

    • [root@luggage sshblack]# iptables -N BLACKLIST 
      [root@luggage sshblack]# iptables -I INPUT 1 -p tcp --dport 22 -j BLACKLIST
      [root@luggage sshblack]# /sbin/service iptables save
      Saving firewall rules to /etc/sysconfig/iptables: [  OK  ]
      [root@luggage sshblack]# 
      
  6. Tailor the sshblack script: look in particular for my($LOCALNET), my($ADDRULE), my($DELRULE), my($REASONS). In my case, I changed just the following definition to allow for my local net:

    • # regex for whitelisted IPs - never blacklist these addresses 
      my($LOCALNET) = '^(?:127\.0\.0\.1|192\.168\.0|193\.123\.216)';
      
  7. This step can be skipped if creating the init.d script described below. Start the script:

    • [root@luggage sshblack]# /usr/local/sbin/sshblack/sshblack.pl >>/var/log/sshblacklisting 2>&1 & 
      [1] 8105
      

2. Arrange sshblack to run on system reboot

To arrange for the script to be started automatically on system reboot (on my RedHat-based system), I created a script file that conforms to the chkconfig init file conventions. (Remove the (-) from the first line - I don't know why, but the wiki puts that there.)

#!/bin/bash (-)
#
#       /etc/rc.d/init.d/sshblack
#
# Controls the sshblackv28.pl sshd breakin attempt monitoring script
#
# chkconfig:  345 86 14
# description: SSH Black monitors ssh connections for attacks
# processname: sshblack
# pidfile: /var/run/sshblack.pid
#
#              :   :  :
#              |   |  |
#              |   |  priority for kill scripts
#              |   |
#              |   priority for start scripts
#              |
#              run levels at which to start service
#
# The code in this script adapted from /etc/init.d/atd on my RHEL4-derived system,
# with some additional clues from [http://www.pettingers.org/media/sshblackinit.txt]
#
# See also: http://www.netadmintools.com/art94.html

# Source function library.
. /etc/init.d/functions

progname="sshblackv28.pl"
progpath="/usr/local/sbin/sshblackv28/"
prog="${progpath}${progname}"
logfile="/var/log/sshblacklisting"

test -x ${prog} || exit 0

RETVAL=0

#
#       See how we were called.
#

start() {
        # Create firewall table for blacklist (in case it got lost)
        # (On Redhat Linux, running the system security level script causes additional
        # IPtables entries to be removed, so this code reinstates the sshblack entries
        if iptables -L INPUT | grep BLACKLIST >/dev/null
        then
            # Blacklist already configured
            :
        else
            # Blacklist missing.  
            # Lines 2-4 below may need adjusting to match the local iptables usage:
            # currently they insert the blacklist check at the start of the INPUT chain
            iptables -N BLACKLIST
            iptables -I INPUT 1 -m state --state RELATED,ESTABLISHED -j ACCEPT
            iptables -I INPUT 2 -i lo -j ACCEPT
            iptables -I INPUT 3 -p tcp --dport 22 -j BLACKLIST
            # Remove any old blacklist cache 
            # (if iptables is reset without clearing this, previously started attacks 
            # may be allowed through)
            rm -f /var/tmp/ssh-blacklist-pending
        fi
        # Check if prog is already running
        if [ ! -f /var/lock/subsys/${progname} ]; then
            echo -n $"Starting ${progname}: "
            ${prog} >>${logfile} 2>&1 &
            RETVAL=$?
            if [ $RETVAL -eq 0 ]; then
                touch /var/lock/subsys/${progname}
                success
            else
                failure
            fi
            echo
        fi
        return $RETVAL
}

stop() {
        echo -n $"Stopping $progname: "
        killproc ${prog}
        RETVAL=$?
        [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/${progname}
        echo
        return $RETVAL
}


restart() {
        stop
        start
}

reload() {
        restart
}

status_prog() {
        status ${prog}
}

case "$1" in
start)
        start
        ;;
stop)
        stop
        ;;
reload|restart)
        restart
        ;;
condrestart)
        if [ -f /var/lock/subsys/${progname} ]; then
            restart
        fi
        ;;
status)
        status_prog
        ;;
reset)
        [ -f /var/lock/subsys/${progname} ] && rm -f /var/lock/subsys/${progname}
        ;;
*)
        echo $"Usage: $0 {start|stop|restart|condrestart|status}"
        exit 1
esac

exit $?
exit $RETVAL

Placing this file in directory /etc/init.d, and making it executable, the whole sshblack utility becomes manageable using chkconfig and service commands; e.g.

[root@luggage sshblack]# cp sshblack /etc/init.d 
[root@luggage sshblack]# ls -al /etc/init.d/sshblack 
-rwxr-xr-x  1 root root 1863 Dec 11 15:03 /etc/init.d/sshblack
[root@luggage sshblack]# chkconfig --add sshblack
[root@luggage sshblack]# chkconfig --list sshblack
sshblack        0:off   1:off   2:on    3:on    4:on    5:on    6:off
[root@luggage sshblack]# service sshblack start

I don't know how well this might work for other Linux variants.

I have yet to fully test that this continues to work after a reboot, but it seems to work fine for the command service sshblack restart, which I use to re-establish the iptables entries whenever I tweak the system firewall settings using the system security level script.

3. Notes


-- GrahamKlyne 2005-12-11 15:00:49

InstallingSshblack (last edited 2008-04-16 12:42:55 by GrahamKlyne)

Creative Commons License
The content of this wiki is licensed under the Creative Commons Attribution-ShareAlike 2.0 England & Wales Licence.

OSS Watch is funded by the Joint Information Systems Committee (JISC) and is situated within the Research Technologies Service (RTS) of the University of Oxford.