If you are a system administrator of a linux system, you may find the following log entries familiar:
Sep 15 02:00:30 sol sshd[16364]: Failed password for invalid user test from ::ffff: 61.167.x.x port 53382 ssh2
Sep 15 02:00:30 sol sshd[16365]: Failed password for invalid user test from ::ffff: 61.167.x.x port 53394 ssh2
Sep 15 02:00:30 sol sshd[16366]: Failed password for invalid user test from ::ffff:61.167.x.x port 53396 ssh2
Sep 15 02:00:28 sol sshd[16366]: Invalid user test from ::ffff: 61.167.x.x
Sep 15 02:00:28 sol sshd[16370]: Invalid user test from ::ffff:61.167.x.x

Many, many times over. These are caused by an brute force attack from the remote host. Most likely this is another compromised machine, checking your machine for easy to guess username and password combinations. It could be someone manually trying to run a password cracking program on your ssh server too. In either case, the remote system really has no business touching your machine. This situation needs an automated solution to block this IP from even getting to your machine. Doing this real-time is essential as well.

Enter the Free APF + BFD scripts from R-fx Networks. These programs work in conjunction with one another to monitor for brute password attempts on your system, then ban the attacking host.

First install the APF (Advanced Policy Firewall) script [Download]

Then install the BFD (Brude Force Detection) script [Download]

When it finds a host that has tried and failed to log in too many times, or has tried too many users who don’t exist on your system, it blocks them in your firewall and e-mails you a message:

The remote system 61.167.x.x was found to have exceeded acceptable login
failures on somehost.com; there was 63 events to the service sshd. As such the
attacking host has been banned from further accessing this system. For the integrity
of your host you should investigate this event as soon as possible.

Executed ban command:
/etc/apf/apf -d 61.167.x.x {bfd.sshd}

The following are event logs from 61.167.x.x on service sshd (all time stamps are GMT -0400):

Sep 15 02:00:27 sol sshd[16364]: Invalid user test from ::ffff:61.167.x.x
Sep 15 02:00:27 sol sshd[16365]: Invalid user test from ::ffff: 61.167.x.x
Sep 15 02:00:28 sol sshd[16366]: Invalid user test from ::ffff: 61.167.x.x
Sep 15 02:00:28 sol sshd[16370]: Invalid user test from ::ffff:61.167.x.x
Sep 15 02:00:30 sol sshd[16364]: Failed password for invalid user test from ::ffff: 61.167.x.x port 53382 ssh2
Sep 15 02:00:30 sol sshd[16365]: Failed password for invalid user test from ::ffff: 61.167.x.x port 53394 ssh2
Sep 15 02:00:30 sol sshd[16366]: Failed password for invalid user test from ::ffff:61.167.x.x port 53396 ssh2
Sep 15 02:00:31 sol sshd[16370]: Failed password for invalid user test from ::ffff:61.167.x.x port 53412 ssh2
Sep 15 02:00:31 sol sshd[16372]: Invalid user test from ::ffff:61.167.x.x
Sep 15 02:00:32 sol sshd[16373]: Invalid user test from ::ffff: 61.167.x.x

In my experience it works great and is a very easy to install!

12 comments
  1. DenyHosts works to block services using TCP Wrappers, such as SSH and FTP however services like Apache which do not use TCPWrappers would still allow that host to connect. Assuming that any IP performing brute force attacks on your system is malicious (I think that is safe to assume) – I would much rather block them from using all services rather than just services using TCP Wrappers. A Brute force attack may be an indication that someone is trying to find a way into your system, so in my opinion it is better to block them via Firewall (iptables) rather than TCP Wrappers.

  2. DenyHosts works to block services using TCP Wrappers, such as SSH and FTP however services like Apache which do not use TCPWrappers would still allow that host to connect. Assuming that any IP performing brute force attacks on your system is malicious (I think that is safe to assume) – I would much rather block them from using all services rather than just services using TCP Wrappers. A Brute force attack may be an indication that someone is trying to find a way into your system, so in my opinion it is better to block them via Firewall (iptables) rather than TCP Wrappers.

  3. OK. How about the following as another viable alternative:
    +—————————+
    /usr/bin/swatch –config-file=/etc/swatchrc –tail-file=/var/log/messages
    –awk-field-syntax –tail-args “-F” &
    +—————————+
    watchfor /Authentication failed for user/
    exec “/usr/local/sbin/lockout $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15″
    +—————————+
    #! /bin/bash
    #
    IP=`echo $* | awk ‘/Authentication failed/{sub(/(?@/,””);print $6}’ | sed ‘s/)//g’`
    ATTEMPTS=`grep $IP /var/log/messages | grep “Authentication failed for user” | wc -l`

    if [ $ATTEMPTS -gt 2 ]
    then
    route add $IP lo
    MINUTES=`expr $ATTEMPTS – 2`
    echo “route del $IP lo 2> /dev/null” | at now +$MINUTES minutes 2>&1 > /tmp/.pure-lockout.$$
    (hostname ; echo $* ; echo “IP=$IP” ; echo “ATTEMPTS=$ATTEMPTS” ;
    echo “Blocking for $MINUTES minutes” ;
    cat /tmp/.pure-lockout.$$ ) | Mail -s “Lockout”
    admin@example.com
    fi

    rm -f /tmp/.lockout.$$

  4. OK. How about the following as another viable alternative:
    +—————————+
    /usr/bin/swatch –config-file=/etc/swatchrc –tail-file=/var/log/messages \
    –awk-field-syntax –tail-args “-F” &
    +—————————+
    watchfor /Authentication failed for user/
    exec “/usr/local/sbin/lockout $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15″
    +—————————+
    #! /bin/bash
    #
    IP=`echo $* | awk ‘/Authentication failed/{sub(/\(\?@/,””);print $6}’ | sed ‘s/)//g’`
    ATTEMPTS=`grep $IP /var/log/messages | grep “Authentication failed for user” | wc -l`

    if [ $ATTEMPTS -gt 2 ]
    then
    route add $IP lo
    MINUTES=`expr $ATTEMPTS – 2`
    echo “route del $IP lo 2> /dev/null” | at now +$MINUTES minutes 2>&1 > /tmp/.pure-lockout.$$
    (hostname ; echo $* ; echo “IP=$IP” ; echo “ATTEMPTS=$ATTEMPTS” ; \
    echo “Blocking for $MINUTES minutes” ; \
    cat /tmp/.pure-lockout.$$ ) | Mail -s “Lockout”
    admin@example.com
    fi

    rm -f /tmp/.lockout.$$

  5. sudo iptables -A INPUT -i eth0 -p tcp –dport 22 -m state –state NEW -m recent –set –name SSH
    sudo iptables -A INPUT -i eth0 -p tcp –dport 22 -m state –state NEW -m recent –update –seconds 60 –hitcount 8 –rttl –name SSH -j DROP

    and off he goes :)

  6. sudo iptables -A INPUT -i eth0 -p tcp –dport 22 -m state –state NEW -m recent –set –name SSH
    sudo iptables -A INPUT -i eth0 -p tcp –dport 22 -m state –state NEW -m recent –update –seconds 60 –hitcount 8 –rttl –name SSH -j DROP

    and off he goes :)

Comments are closed.

You May Also Like

Using nice to control CPU usage and process priority

If you wish to run a command which typically uses a lot…

Install CAB files directly to a Windows Mobile Device from your Desktop via ActiveSync

Downloading a CAB file to install onto your Windows Mobile device can…

What a Resilver Looks Like in ZFS (and a Bug and/or Feature)

At home I have an (admittedly small) ZFS array set up to experiment with this neat newish raid technology. I think it has been around long enough that it can be used in production, but I’m still getting used to the little bugs/features, and here is one that I just found. After figuring out that I had 2 out of 3 of my 1TB Seagate Barracuda hard drives fail, I had to give the array up for a loss and test out my backup strategy. Fortunately it worked and there was no data loss. After receiving the replacement drives in from RMA, I rebuilt the ZFS array (using raidz again) and went along my merry way. After 6 months or so, I started getting some funky results from my other drive. Thinking it might have some issue as with the others, I removed the drive and ran Seatools on it (by the way, Seatools doesn’t offer a 64-bit Windows version – what year is this?). The drive didn’t show any signs of failure, so I decided to wipe it and add it back into the array to see what happens. That, of course, is easier said than done.