HOME > MISC > LINUX > PROTECT SSH
Quick Search:

Return to Quick Linux Tips

Protect SSH From Hackers (v0.2)
Last modified: Friday November 9, 2012


Set Up Swatch To Monitor Security Logs

Linux is very secure but it still doesn't prevent hackers from scouring the Internet looking for systems with easily guessed passwords. Check your daily LogWatch for your Linux systems and if you see something like this you probably should do something to prevent a potential successful attempt.
sshd:
   Authentication Failures:
      unknown (64.161.121.11): 699 Time(s)
      root (211.136.107.81): 31 Time(s)
	.
	.
One way to solve this problem is to use iptables (see below) to filter these attempts but I chose to go a slightly simpler route. First of all make sure you have swatch installed to easily monitor logfiles.
# yum install swatch
Then create a swatch configuration file called /etc/swatchrc  containing the following:
# Bad login attempts
watchfor   /Failed password for/
        exec "/usr/local/admin/bin/bad_user $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15"
Then you will want the /usr/local/admin/bin/bad_user script to do the work. Below is my script:
#! /bin/bash
#
IP=`echo $* | sed 's/^.* from //' | awk '{print $1}' | sed 's/::ffff://'`
ATTEMPTS=`grep $IP /var/log/secure | grep "Failed password for"  | 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/.bad_user.$$
	(hostname ; echo $* ; echo "IP=$IP" ; echo "ATTEMPTS=$ATTEMPTS" ; \
		echo "Blocking for $MINUTES minutes" ; \
		cat /tmp/.bad_user.$$ ) | Mail -s "bad user" root
fi

rm -f /tmp/.bad_user.$$
Briefly, what this does is allow two invalid logins before blocking any further access from the offending IP address by routing return traffic to that IP to the loopback interface for 1 minute. After that expires each further attempt will cause access to be blocked for longer and longer periods of time.

Finally you need to start swatch to get it to watch your logfile and protect your system:

# /usr/bin/swatch --config-file=/etc/swatchrc --tail-file=/var/log/secure \
	--awk-field-syntax --tail-args "-F" &

Other Useful Resources

I've tried to not just copy other people's tips so I've included a list of other people's tips and tricks I've found to be useful. There should be little or no overlap.
firewall ip adress if it tries to login as a specified user - The place I found one solution to this problem. I solved it in a slightly different way and adapted it for RedHat/Fedora systems.


Comments From People Like You!
Protect SSH From Hackers
Add a Comment add a comment
Steve
09-Mar-2008 10:44
Your best bet if you're serious about protecting your SSH terminal from hackers is to set up SSH keys and then remove the ability to log in with a password.  It also saves you from needing to type in your password every time you connect, since you type it in once to unlock your private key, and then you're all set for the rest of your session.
Claude Le Berre
10-Jan-2008 04:36
Also, a simple application that do the same thing : fail2ban
fw guy
03-Aug-2007 13:33
I picked this up from someone else.  It's really slick.  It includes rate limiting and banning for people that connect too frequently.

/sbin/iptables -N SSH
/sbin/iptables -N SSH_ABL
/sbin/iptables -A SSH -m recent --name SSH_ABL --update --seconds 3600 -j REJECT
/sbin/iptables -A SSH -m recent --name SSH --rcheck --seconds 60 --hitcount 5 -j SSH_ABL
/sbin/iptables -A SSH_ABL -m recent --name SSH_ABL --set -j LOG --log-level warn --log-prefix "ABL: +SSH: "
/sbin/iptables -A SSH_ABL -j REJECT
/sbin/iptables -A SSH -m recent --name SSH --rcheck --seconds 2 -j LOG --log-level warn --log-prefix "RATE: "
/sbin/iptables -A SSH -m recent --name SSH --update --seconds 2 -j REJECT
/sbin/iptables -A SSH -m recent --name SSH_ABL --remove -j LOG --log-level warn --log-prefix "ABL: -SSH: "
/sbin/iptables -A SSH -m recent --name SSH --set -j ACCEPT
/sbin/iptables -A INPUT -m state --state NEW -p tcp -m tcp --dport 22 -j SSH
Kevin
28-Jul-2007 13:36
WHere or what files does this iptables command go into?
Kevin
Msquared
02-Jul-2006 10:48
Here's a simple iptables method to achieve roughly the same result:

iptables -A INPUT -m recent --update --seconds 40 --hitcount 5 --name SSH --rsource -j DROP
iptables -A INPUT -m recent --set --name SSH --rsource -j ACCEPT

If the rules detect 5 attempts to connect to SSH from any given IP address within 40 seconds, it will prevent further connections to SSH from that IP address.  If attempts are continued, the counter is reset, thus prolonging the black hole for that IP address.

I've set this up on my server, and it performs really well.  Feel free to check your system logs and tweak the timing and the count...
Pedro Bezunartea Lopez
16-Nov-2005 16:52
Another very good tool to deal with this problem is: http://www.pettingers.org/code/sshblack.html

Nice site!
Sam Moore
15-Nov-2005 13:10
Slight typo in this starter script - swatchrc should read swatch.rc
Otherwise works great - thanks guys!
Jay Farschman
14-Sep-2005 20:53
Thanks for a great system.  I used to rely on obscure passwords.  Now I've added this as an additional layer.  Also.... I wrote up a swatch start file for fedora/redhat/centos and thought I should share it.  This system stripped out the tabs and extra spaces... so the formatting is shot, but it should still run.

# !/bin/sh
#
# swatch        This shell script takes care of starting and stopping
#               swatch.
#
# chkconfig: 2345 81 31
# description: Swatch is a System WATCHdog program that we are
#              using here to block repeated failed ssh logins.
# processname: swatch


 RETVAL=0
 test -x /usr/bin/swatch || exit 0
 start(){
   echo "Starting swatch"
     # Spawn a new swatch program
       /usr/bin/swatch --config-file=/etc/swatchrc --tail-file=/var/log/secure --awk-field-syntax --tail-args "-F" &
       echo $PID
 return $RETVAL
}
stop () {
     # stop daemon
   echo "Stopping swatch:" $PROG
   killall swatch
   return $RETVAL
}
restart () {
   stop
   start
   RETVAL=$?
   return $RETVAL
}

case "$1" in
   start)
       start
       ;;
   stop)
       stop
       ;;
   restart)
       restart
       ;;
   *)
       echo "Usage: $0 {start|stop|restart}"
       RETVAL=1
esac
exit $RETVAL

Please E-mail Me with any questions, comments or corrections.

All pictures and text are the property of Gregory Gulik unless otherwise specified. Please contact site owner if you would like permission to use these pictures for your own purposes or to make comments about anything you see here.