Securing SSH with DenyHosts

The frequency of brute force attacks on SSH is increasing but can be stoped with DenyHosts for example. A simple hack starts the program only to check during a login.


Some month ago, I noticed in the log files of a server an increasing frequency of SSH attacks. The attackers obviously used scripts to try long lists of logins such as common names and standard accounts. Fortunately, I had already changed /etc/ssh/sshd_config to deny access as “root”, and to permit access only for a selected group of users:

PermitRootLogin no
AllowUsers Dave Jack Scott

This was an initial step to minimize the risk of brute force attacks. To slow down the speed of an attack I also limited the number SSH daemons:

MaxStartups 1

Unfortunately, OpenSSH does not have any mechanism build-in to stop unsuccessful login attempts that come from the same IP address. So, I started looking for other tools and found DenyHosts and SSHDFILTER interesting. I preferred DenyHosts because it uses /etc/hosts.deny to block the access from attacking IP address and did not require IPTABLES.

DenyHosts can be automatically started as cron job or can run in daemon mode. Both methods can be used to check in defined time intervals the log file for failed logins and deny access from an IP address with more failed logins than the defined threshold. The configuration file for DenyHost offers very fine-grained settings. For example, the threshold for known users can be higher than for unknown users so that the tolerance for password typos can be higher than the maximum number of unknown login attempts. Another very interesting feature is the purge option that can be used to reset the number of failed logins after a defined time interval.

Running DenyHosts in daemon mode or as cron job leaves the time interval between two scans of the log files as time window for an attacker. The log files showed that the frequency of SSH connections during an attack was about one per second. To keep the time window short it would be necessary to run DenyHosts very frequently just to secure the SSH port while SSH access is not in permanent use. I thought running DenyHost once per login to check the log file would minimize the effort and the time window for attacks.

Eventually, I found a hack to realize it. It is quit simple. I configured DenyHosts to write all blocked IP addresses in /etc/host.blocked and use it in the first line of /etc/hosts.deny. This avoids that IP addresses would be added to the end and gives /etc/hosts.blocked a high priority because TCPWRAPPER stops scanning /etc/host.allow and /etc/hosts.deny when it finds a matching IP address. All logins from not blocked IP addresses get eventually to the last line where the SPAWN option is used to start the Python script DenyHosts:

ALL:/etc/hosts.blocked
sshd:ALL:spawn python2.4 /usr/bin/denyhosts.py –purge -c /etc/denyhosts.cfg: allow

Since then the log files have shown that the access from attacking computers was denied after the defined maximum number of failed logins was reached. DenyHosts is an excellent program that even allows running an external program or script as a plug-in. This could be the next hack to keep a record of denied IP addresses for statistics because it would be interesting to know if the attackers return after their IP address is removed from /etc/host.blocked. But using DenyHosts with a threshold of five failed logins for unknown users does not allow them to run a brute force attack anymore.

Related bookmarks — absolutely del.icio.us

The OpenSSH project recently asked for donation so that the development can continue. PLEASE CONSIDER TO DONATE!

About these ads

Tags: , ,

One Response to “Securing SSH with DenyHosts”

  1. eric Says:

    Hi,
    that’s a nice trick, but it doesn’t seem to work on Mac OS X 10.4.10 :
    /etc/hosts.deny:
    _________________________
    ALL:/etc/hosts.blocked
    sshd:ALL:spawn /usr/local/denyhosts/bin/denyhosts.py -c /usr/local/denyhosts/etc/denyhosts.cfg –purge >& /tmp/coucou:allow
    _________________________

    sshd chokes on the /include/ line :
    Dec 7 11:00:42 ****** sshd[11474]: warning: /etc/hosts.deny, line 1: bad net/mask expression: /etc/hosts.blocked

    but the script gets executed and populates /etc/hosts.blocked !
    unfortunately, the ban isn’t effective.

    I can find no mention of the syntax :
    ALL:/include/file
    in
    man -S 5 hosts_access
    or
    man hosts_options

    which system are you using ?

    Cheers,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


Follow

Get every new post delivered to your Inbox.

%d bloggers like this: