Tuesday, June 1, 2010

Blocking hostile ssh login attempts

We want to block users who attempt to login to our box via ssh with bad intentions, you can see these in the logs coming all day long they look like the following (/var/log/authlog):

May 31 03:17:31 cm47 sshd[3517]: Failed password for root from 218.25.68.9 port 54014 ssh2
May 31 03:17:31 cm47 sshd[20855]: Received disconnect from 218.25.68.9: 11: Bye Bye
May 31 03:17:33 cm47 sshd[20600]: Failed password for root from 218.25.68.9 port 54112 ssh2
May 31 03:17:34 cm47 sshd[8641]: Received disconnect from 218.25.68.9: 11: Bye Bye
May 31 03:17:36 cm47 sshd[19515]: Failed password for root from 218.25.68.9 port 42841 ssh2
May 31 03:17:36 cm47 sshd[25534]: Received disconnect from 218.25.68.9: 11: Bye Bye


Jun 1 11:21:23 cm47 sshd[16250]: Failed password for invalid user webmaster from 88.191.80.193 port 51163 ssh2
Jun 1 11:21:23 cm47 sshd[13312]: Received disconnect from 88.191.80.193: 11: Bye Bye


Jun 1 03:39:01 cm47 sshd[26899]: reverse mapping checking getaddrinfo for 173.1.44.30.reverse.gogrid.com [173.1.44.30] failed - POSSIBLE BREAK-IN ATTEMPT!
Jun 1 03:39:02 cm47 sshd[16507]: reverse mapping checking getaddrinfo for 173.1.44.30.reverse.gogrid.com [173.1.44.30] failed - POSSIBLE BREAK-IN ATTEMPT!
Jun 1 03:39:03 cm47 sshd[10347]: reverse mapping checking getaddrinfo for 173.1.44.30.reverse.gogrid.com [173.1.44.30] failed - POSSIBLE BREAK-IN ATTEMPT!
Jun 1 03:39:04 cm47 sshd[17923]: reverse mapping checking getaddrinfo for 173.1.44.30.reverse.gogrid.com [173.1.44.30] failed - POSSIBLE BREAK-IN ATTEMPT!
Jun 1 03:39:04 cm47 sshd[29303]: reverse mapping checking getaddrinfo for 173.1.44.30.reverse.gogrid.com [173.1.44.30] failed - POSSIBLE BREAK-IN ATTEMPT!
Jun 1 03:39:05 cm47 sshd[12674]: reverse mapping checking getaddrinfo for 173.1.44.30.reverse.gogrid.com [173.1.44.30] failed - POSSIBLE BREAK-IN ATTEMPT!

So here's how we do this:
sshd will deny these logins, but after we already know someone has attempted something we don't like its usually a good idea block these script kiddies from everything that we can, so to do that, we'll use swatch to read our authlog file and add these IP's to the ssh-badguys table so that they are blocked by pf.

Add the following to your pf.conf file:


#rules for "hostile ssh login attempts"
table <sshd-badguys> persist
anchor "sshd_hostiles" {
block in log quick from <sshd-badguys> to any
}


You'll need to install the swatch (syslog-watcher) package
#pkg_add -i swatch

Copy the following into your /etc/swatch.conf file



watchfor /\[(\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3})\] failed - POSSIBLE BREAK-IN ATTEMPT!/
exec /sbin/pfctl -T add -t sshd-badguys $1
exec /sbin/pfctl -k $1

watchfor /Failed password for root from (\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3})/
exec /sbin/pfctl -T add -t sshd-badguys $1
exec /sbin/pfctl -k $1

watchfor /Failed password for invalid user .+ from (\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3})/
exec /sbin/pfctl -T add -t sshd-badguys $1
exec /sbin/pfctl -k $1


Then to run swatch, issue the following command:
/usr/local/bin/swatch --config-file /etc/swatch.conf --daemon --tail-file /var/log/authlogin
to make this happen on boot, stick this line in your /etc/rc.local

This will start working immediatly, you can check the table to see what addresses have been added to it by issuing the following command:

pfctl -T show -t sshd-badguys

If you want these entries to expire after a certain amount of time, you can setup something like the following in your crontab file to run every 30 mins or so (this will expire all entries older than a day, if your really concerned about accuracy, you may want to run this every minute or so:

pfctl -t sshd-badguys -T expire 86400