20 February 2010

Block brute force SSH attacks & setup statistics reporting to Twitter

Hey there!
Today I found that my home linux PC is under brute force SSH attack. I found next lines in /var/log/messages >>

I did little investigation about how to block similar attacks and wrote small script to analyze logs and report it to twitter.

Note: My machine runs under ASPLinux (kernel Some details of described solution probably need to be modified before applying on machines with different configuration.

Configure sshd

First of all you should disable root logins through ssh (this and next setting could be changes in /etc/ssh/sshd_config):

PermitRootLogin no

Secondary, I decreased timeout for unauthenticated sessions, maximum possible count of them and maximum number of authentication tries per session:

LoginGraceTime 30 # 30 sec
MaxAuthTries 2
MaxStartups 3

You could also disable empty passwords for ssh. I assume your password isn't empty, but anyway:

PermitEmptyPasswords no

And also (most important) you could add banner. Who knows, may be attacker will read it :D

-- Please note: you are now connected to a secure private network..
-- All traffic for this connection will be logged.

Banner /etc/ssh/banner

Note: SSH Banner could cause issues with rsync.

You could read more about sshd configuration options in linux man pages by typing following command:
man 5 sshd_config
or in internet, for instance:

Preventing brute force with iptables

Note: If you don't have firewall configured (iptables) you need to configure and run it first.

Iptables allows you to limit number connections per time period per IP address with using option "-m recent". You could read more about this feature here: http://netfilter.org/documentation/HOWTO/netfilter-extensions-HOWTO-3.html#ss3.16

So, in our case we need to limit number of TCP connections to port 22. Lets limit it for 5 connection per hour (also per IP). You could do it by running following commands:

iptables -A INPUT -p tcp --dport 22 -m recent --name ssh --update --seconds 3600 --hitcount 5 -j REJECT
iptables -A INPUT -p tcp --dport 22 -m recent --name ssh --set -j ACCEPT

You could put these lines to iptables configuration file. For RedHat-like systems it's /etc/sysconfig/iptables. Don't forget to restart iptables service in that case:
# service iptables restart

Reporting script

You can find small bash script to parse /var/log/messages and /var/log/secure below. It reports number of ssh connection failures and successfully opened sessions during yesterday to Twitter. Also it reports IP addresses from which connection was made.

It uses Twitter's REST API to post reports. You could create private account on twitter and receive your server reports via RSS. To send status update to twitter you need to type following command:
curl --fail -u twituser:twitpass --data status=MY_STATUS http://twitter.com/statuses/update.xml

Script source code >>

Strange commands like "sed 's/ /%20/g' | sed 's/=/%3D/g'" needed to encode message in URL format. If somebody knows any linux command to make that job - please write in comments.

It does make sense to put it to the cron and run after midnight. First, you need save that script in file /root/ssh-analyze.sh and give it rights to be executed. Then add next line to cron configuration (/etc/crontab):

5 0 * * * root /root/ssh-analyze.sh >/dev/null

That's it! Don't allow hackers to hack your pc :)


  1. BTW that script gave "Failure count=3277" for today.

  2. As was mentioned in comments on habrahabr.ru the better solution is to use http://www.sshguard.net/ instead of iptables -m recent.

  3. For automatically reporting, you can use my project http://www.blocklist.de/en/ so you can use your own Scripts or use Fail2Ban to generate the Mails and we parse them and give stats and other Stuff over your Account.

  4. Update: Twitter changed API and this script doesn't work anymore.