ScanAssassin

I have a server that is directly exposed to the Internet. The only services it exposes are ssh and http, and I monitor my system logs closely in a window in screen running swatch on /var/log/messages.

Recently I got tired of seeing almost daily, someone from Korea, China or anywhere running brute force ssh password scans on my box. They weren't successful but still, it clutters up my monitoring and I'd just rather not allow them to keep trying as long as they wish. So I wrote a Perl script to be run from the command line or be executed by swatch, track authentication failures and after a certain number (default 10) of failed attempts, add an entry to /etc/hosts.deny to put an end to it.

It works as follows:

  1. accept log entries from STDIN (from swatch or command line)
  2. parse for offending host/ip
  3. create file in /tmp named after host/ip with counter in it
  4. once we reach a limit, add to /etc/hosts.deny with comment marking date and count
Run scanassassin --help to see the options. Example of swatch usage:
watchfor = /authentication failure/
        pipe=/usr/local/bin/scanassassin
    
Known to work on Linux and FreeBSD, should also work on other Unices with little effort. If you make it work on another variant of Unix, please let me know so I can update this for others to use too. Or if you need help, probably all I need is a sample of your pam or ssh logs.

Note that, as /tmp gets cleared periodically on most systems, the data files will get deleted. But chances are, this won't matter.

Theoretically this should also work with other authentication attempts than ssh, such as ftp. As long as the log entry has the same syntax.

Here are sample logs that it currently parses:

  • Linux
    Jul 21 20:38:42 nevinyrral sshd(pam_unix)[8948]: authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=61.39.2.15
    Jul 21 20:38:42 nevinyrral sshd(pam_unix)[8948]: authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=61.39.2.15 user=pcap
  • FreeBSD
    Aug 20 13:39:25 filbert sshd[89482]: Failed password for nobody from 167.216.252.49 port 48205 ssh2
  • And here is a sample of the recent results in /etc/hosts.deny:

    # added by scanassassin (10 attempts on sshd(pam_unix)) Tue Aug 16 13:00:21 2005
    ALL: 80.71.245.145
    # added by scanassassin (10 attempts on sshd(pam_unix)) Sat Aug 20 07:03:55 2005
    ALL: 213.203.250.231
    # added by scanassassin (10 attempts on sshd(pam_unix)) Sat Aug 20 20:59:59 2005
    ALL: 216-55-168-86.dedicated.abac.net
    # added by scanassassin (10 attempts on sshd(pam_unix)) Mon Aug 22 07:03:09 2005
    ALL: 212.17.206.194
    # added by scanassassin (10 attempts on sshd(pam_unix)) Wed Aug 24 17:54:51 2005
    ALL: 64.106.226.5
    # added by scanassassin (10 attempts on sshd(pam_unix)) Wed Aug 24 17:54:51 2005
    ALL: 203.66.146.200
    # added by scanassassin (10 attempts on sshd(pam_unix)) Sun Aug 28 11:23:18 2005
    ALL: 59-120-54-72.hinet-ip.hinet.net
    
    Download the Perl script here.

    Written in July, 2005.


    Eric D. Hendrickson
    Last modified: Fri Jul 13 16:41:13 CDT 2007