HOWTO Secure SSHd with BlockHosts

(Updated version: http://gentoo-wiki.com/HOWTO_BlockHosts)

Protecting SSHd (and others) with BlockHosts

What is BlockHosts?

Blockhosts is a python script which records how many times a system service has been probed, using configurable pattern matching to recognize failed accesses (such as for "sshd" or "proftpd" or any service), and when a particular IP address exceeds a certain number of failed attempts that IP address is blocked by using one of the following techniques, e.g.:

  • using TCP_WRAPPERS (writes to /etc/hosts.allow)
  • using "ip route" commands to setup null-routing for attackers
  • using IPtables to setup packet filtering for attackers

Advantages

I decided to install BlockHosts rather than its aquivalents, e.g. denyhosts or fail2ban, because it provided more features:

  • BlockHosts can prevent attacks from SSHd and many other services (such as proftpd, vsftpd) innately, rather than its equivalents
  • It provides multiple ways to block the attacker
  • It's very easy to set up

Installation

Ebuild

Currently there's no BlockHosts package in the Portage tree. I've written an ebuild (thanks again to #gentoo-sunrise for reviewing it) which should work (for all archs?). If you do not know how to cope with 3rd party ebuilds, refer to the handbook.

Download: blockhosts ebuild

Emerge

WARNING: I assume that you've set your PORTDIR_OVERLAY to /usr/local/portage. First, copy the ebuild to /usr/local/portage/app-admin/blockhosts/. Then do this:

# Create blockhosts digest
ebuild /usr/local/portage/app-admin/blockhosts/blockhosts-2.0.2.ebuild digest
# Unmask blockhosts
echo "app-admin/blockhosts ~x86" >> /etc/portage/package.keywords
# I'm not sure if this is needed, but it won't hurt anyone
emerge --metadata
# Emerge it
emerge -va app-admin/blockhosts

That's everything.

Configuration

First, you need to create and edit some files

# Create /etc/hosts.allow if it does not exists (required by BlockHosts)
touch /etc/hosts.allow
# Append the following lines to /etc/hosts.allow
# (BlockHosts will write its own stuff between them)
echo "#---- BlockHosts Additions" >> /etc/hosts.allow
echo "#---- BlockHosts Additions" >> /etc/hosts.allow

Setting up BlockHosts protecting SSHd

Setting up openssh:
Check if openssh was merged with the tcpd useflag enabled:
equery uses openssh
If not, add this useflag (it's necessary to work with TCP_WRAPPERS) to the openssh package
echo "net-misc/openssh tcpd" >> /etc/portage/package.use

Re-emerge to apply use flags

emerge -va net-misc/openssh
Check if your SSHd logs to /var/log/sshd (Gentoo default, afaik)
cat /var/log/sshd
If there's some recent output, everything's ok. Proceed.

Setting up BlockHosts:
Edit /etc/blockhosts.cfg nano /etc/blockhosts.cfg

All occurences of LOGFILES are commented, uncomment the first occurence, and change "secure" to "sshd".
/etc/blockhosts.cfg

...
LOGFILES = [ "/var/log/sshd", ]
#LOGFILES = [ "/var/log/auth.log", ]
#LOGFILES = [ "/var/log/secure", "/var/log/vsftpd.log", ]
...

Save, close nano again, this should be enough.

Post-Configuration

You can tune some settings in the config file if you like to (THRESHOLD and stuff), but the defaults are ok.

Testing

Run blockhosts.py in --dry-run mode (simulation):
# This will check your logs for potential attacks
/usr/bin/blockhosts.py --dry-run --verbose
The blockhosts.py script should output something like this (assumed there were some failed login attempts already):

...
#---- BlockHosts Additions
ALL: 89.13.50.6 : deny 
#bh: ip:      89.13.50.6 :   8 : 2007-04-10 00:52:23 CEST

#bh: logfile: /var/log/sshd
#bh: offset: 13083
#bh: first line:Apr  9 23:49:37 hostname sshd(pam_unix)[29697]: authentication$
#---- BlockHosts Additions
...
  • The lines starting with "#bh: ip:" count how many times a host has failed to login to any of your services.
  • The lines starting with "ALL:" are the blocked hosts.

Now, if everything seems to be ok, drop the --dry-run parameter.
BlockHosts will now write to the /etc/hosts.allow file and every service that uses TCPWRAPPERS (modwrap for proftpd) refuses connections from this ip.
/usr/bin/blockhosts.py --verbose

Completion

Now we want to have a cronjob or something which will run blockhosts.py again and again, to check the logs frequently.

Cronjob

Add a cronjob which runs every five minutes
nano /etc/crontab
Add blockhosts.py cron

*/5 * * * * /usr/bin/blockhosts.py --verbose >> /var/log/blockhosts.log 2>&1

Save, close. BlockHosts should now update hosts.allow every five minutes.

TODO

  • BlockHosts and iptables
  • BlockHosts + spawn utility

See also

http://www.aczoom.com/tools/blockhosts/ - BlockHosts Homepage