ssh_login_blocker

Anyone who has a run a GNU/Linux server on the Internet for more than a few weeks has probably noticed that they will occasionally get “hammered” by a robot attempting to make an ssh connection using common usernames and passwords. Usually these are not truly “brute force” attacks—they try 20-30 times, rather than thousands—but either way they are annoying.

These attacks are rarely successful with a properly configured system, but they can use up bandwidth and system resources, and perhaps more troublesome is that they clog your log files so it is more difficult to detect a bona fide system attack. I suspect that at least some of these random ssh login attempts are accompanied by attacks on other known vulnerabilities, with the hope that the sysadmin won’t notice the more devious attack because the stupid attack is going on at the same time.

Strangely, there is no “canonical” solution to guarding against these attacks. A few people have written up their own hack solutions, and here is mine.

It’s called ssh_login_blocker. It’s very simple—just drop it in /etc/init.d and make symlinks to the proper /etc/rc?.d directories (or just start it running from the command line). It must be run as root. You can configure it to allow a certain number of bad passwords or bad usernames before it blocks an IP address. You can also configure it to “reset” the bad username/password count after a certain amount of time has passed. Just look at the first few lines of code and adjust the settings accordingly.

If you are running it on a system to which you don’t have physical access, you should whitelist at least one IP address where you will be able to get in from in case something goes awry.

There are many improvements I’d like to make. For example, it should use libfile-tail-perl rather than running a shell for tail. It should have a “temporary blacklist” feature in addition to the current “permanent blacklist” feature. It should have an auto-whitelist function such that “known good” IP addresses get marked up. It should use something other than /etc/hosts.deny to block ip addresses—for example, iptables. It doesn’t do any of these things, but it works pretty well, and it makes me happy that my log files are not currently clogged with spurious login attempts.

17 comments

  1. erich Jan 28

    Why not use the iptables “recent” features (or rate features) to allow only, lets say 3 ssh connections within five minutes, then block for the next 5 minutes?
    This should stop these scanners and they’ll probably just move on, while it’s not too likely to hit you (and you can always put your frequent hosts onto a whitelist or use a port-knocking to reopen the ports, this can be done using the same iptables rules…)

  2. Ben Finney Jan 28

    Visiting the “Download it here” link leads me to a 302 redirect, to a ‘forbidden.html’ document.

  3. Antoine Jan 28

    This article explain how to implemant erich’s technic :
    http://www.debian-administration.org/articles/187
    I use it and I can say it is very efficient with only two iptables commands.

  4. Adam Rosi-Kessel Jan 28

    Oops–sorry about the 302 redirect. Fixed now.

  5. Steven Jan 28

    Hi. How about denyhosts? I used it for a couple of days and it’ve seemed to work pretty well.

  6. erich Jan 28

    I’ve setup iptables on my firewall, and it also protects accesses to other hosts. A ssh scanner will not even discover all ssh-enabled hosts, he’s blocked before that.
    Amazing stuff you can do with the recent match in iptables. There are also port-knocking solutions available using only iptables…

  7. Anonymous Jan 28

    erich’s solution doesn’t separate sucessfull logins/connections from unsuccessfull ones. This makes *real* difference: with scp/darcs/cvs/svn over ssh, one easily goes over the “3 in a minute” limitations

  8. Ari Pollak Jan 28

    You should probably use tail –follow=name instead of -f, so the script will still work after the logs get rotated.

  9. Adam Rosi-Kessel Jan 28

    Thanks, Ari. I had actually fixed that but had posted an old version. I’ve since updated the entry.

  10. Mick Jan 28

    Why not use Swatch?

    http://gentoo-wiki.com/HOWTO_Protect_SSHD_with_Swatch

  11. Ercin EKER Jan 28

    i get some errors, which perl modules have to be installed?

    error message is:
    polaris:~# /etc/init.d/ssh_login_blocker start
    /etc/init.d/ssh_login_blocker: line 6: use: command not found
    /etc/init.d/ssh_login_blocker: line 7: syntax error near unexpected token `(‘
    /etc/init.d/ssh_login_blocker: line 7: `use Unix::Syslog qw(:subs :macros); # Syslog macros’

  12. Adam Rosi-Kessel Jan 28

    Ercin: Looks like maybe you didn’t download the executable and instead copied the HTML out? You shouldn’t be getting an error on “use.” You do need the perl module Unix::Syslog, but it doesn’t appear to me that that is your problem.

  13. Ercin EKER Jan 28

    hehe, i really feel stupid :)

    when i removed the comments before the “#!/usr/bin/perl -w” line it worked.

  14. Moritz Jan 28

    The Debian package which provides the required Unix::Syslog perl module is called libunix-syslog-perl. You can use sysv-rc-conf to set the rc?.d symlinks. Setting the same as those set for sshd (usually 2,3,4) should work.

  15. William Jan 28

    Note! You shouldn’t use the recent iptable module, because it is broken. For details see:
    http://blog.blackdown.de/2005/05/09/fixing-the-ipt_recent-netfilter-module/

  16. gouki Jan 28

    Pretty cool Adam. I personally use Fail2Ban[0], which can be configured to work with other applications, but I’ll make sure to try this one out.

    [0] – http://fail2ban.sourceforge.net/

  17. zozhit Nov 6

    belle chaude marocaine

Leave a Reply

(Markdown Syntax Permitted)