This site is now 100% read-only, and retired.

Brute Force Protection with BlockHosts

Posted by chr0nik on Mon 30 Jan 2006 at 14:02

Brute force attacks are a weekly issue on my Debian box and until now, I've manually managed my hosts.allow and hosts.deny files. The issue isn't so much the actual security threat as brute force attacks are usually unsuccessful, but seeing log files that are just loaded up with thousands of failed login attempts is unnerving at best.

I've searched for solutions from the black list daemon (bld) that's available as a Debian package to more complicated iptables based protection. I haven't really found whether any other services actually use bld and as far as iptables, I have a great firewall script already that I don't want to tinker with anymore.

The Solution:

Enter BlockHosts; a python script that even a novice can setup, unless the existing log file patterns do not meet your needs... then you'll need a regex guru.

BlockHosts v1.0.3 has built-in support for OpenSSH, ProFTPD and vsftpd. By built-in support, I mean that blockhosts.cfg already contains regular expressions to match failed login attempts for those services. Because of the fact that the installation is so trivial and well documented in the text files included in the BlockHosts distribution, I will only cover the steps at a high-level.

Installation:

BlockHosts needs Python 2.3. It will also need the development package as it will look for the Python Makefile when you run BlockHosts' setup script. These packages are installed easily with apt-get:

apt-get install python2.3 python2.3-dev

Additionally, you'll need to ensure that the services you wish to protect are being invoked by inetd and not running in standalone mode. You will also need to ensure you're using tcp_wrappers. My /etc/inetd.conf looks like this:

ftp             stream  tcp     nowait  root    /usr/sbin/tcpd  /usr/sbin/vsftpd
ssh             stream  tcp     nowait  root    /usr/sbin/tcpd  /usr/sbin/sshd -i

Once you've downloaded and unpacked the GZIPped tarball from the download page, the installation is fired off by executing this command:

python setup.py install --force

This copies the main script, blockhosts.py, to /usr/bin and places the configuration file, blockhosts.cfg in /etc. There is really only one thing you have to be concerned with in /etc/blockhosts.cfg and that's the line that specifies where your system log files are. Again, there are examples and abundant comments in the config file so you shouldn't have any difficulty maintaining it. Mine looks like this:

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

Finally, modifications are required to your /etc/hosts.allow file. The overall format of hosts.allow is defined as:

  • Manually maintained whitelist
  • BlockHosts marker lines
  • The command to fire off BlockHosts on inbound connection attempts

My /etc/hosts.allow file now looks like this:

# permanent whitelist addresses - these should always be allowed access

ALL: 127.0.0.1  : allow
ALL: 192.168.1. : allow

# permanent blacklist addresses - these should always be denied access

ALL: 10.  : deny
ALL: 192. : deny
ALL: 172. : deny

# ----------------------------------------
# next section is the blockhosts section - it will add/delete entries in
# between the two marker lines (#---- BlockHosts Additions)

#---- BlockHosts Additions
#---- BlockHosts Additions

# ----------------------------------------
# finally, the command to execute the blockhosts script, based on
# connection to particular service or services, for example, here's what
# I use:
sshd, vsftpd, in.vsftpd: ALL: spawn (/usr/bin/blockhosts.py --verbose --echo "%c-%s" >> /var/log/blockhosts.log 2>&1 )& : allow
Conclusion:

BlockHosts will now evaluate my log files on each connection attempt, maintain a "watched" host list between the markers in /etc/hosts.allow, and maintain the current blocked hosts in /etc/hosts.deny. The default configuration is to block a host after 7 failed login attempts and to reset the block list after 12 hours (+/- some tolerance based on the timing of log file writes, etc.)

BlockHosts is easy to install and quite effective. If nothing else, I know I'll sleep better knowing that now after 7 failed logins instead of thousands of failed logins, the attacker will be dissuaded.

 

 


Re: Brute Force Protection with BlockHosts
Posted by Anonymous (65.78.xx.xx) on Mon 30 Jan 2006 at 14:21
apt-cache show fail2ban

Simple, effective, no configuration needed.

See also:
Keeping SSH access secure http://www.debian-administration.org/articles/87

[ Parent ]

Re: Brute Force Protection with BlockHosts
Posted by Anonymous (212.20.xx.xx) on Mon 30 Jan 2006 at 14:26

Seconded, if only because I don't want to start SSH via inetd.

[ Parent ]

Re: Brute Force Protection with BlockHosts
Posted by Anonymous (194.109.xx.xx) on Mon 30 Jan 2006 at 19:51
fail2ban is not in Sarge (stable), only in unstable.
http://packages.debian.org/unstable/net/fail2ban

[ Parent ]

Re: Brute Force Protection with BlockHosts
Posted by Anonymous (213.216.xx.xx) on Tue 31 Jan 2006 at 11:56
Sadly true. OTOH it's perl (bleargh, but it's an interpreted language) and the package just drops in if you download it and dpkg -i or drop it into any of your own repositories.

[ Parent ]

Re: Brute Force Protection with BlockHosts
Posted by trew (129.242.xx.xx) on Tue 31 Jan 2006 at 12:54
Not perl. fail2ban is written in python as well. The only dependencies fail2ban has is for the packages 'python' and 'iptables', so it will fit a woody installation as well as sarge/etch. I wonder if potato has the package 'iptables' :-)

[ Parent ]

Re: Brute Force Protection with BlockHosts
Posted by Anonymous (65.78.xx.xx) on Tue 31 Jan 2006 at 14:50
Wait a minute! :)

fail2ban installs and runs perfectly in sarge. Install with dpkg -i, or if you have other packages from sid or from backports.org as I do, just use /etc/apt/preferences to automatically manage package selections.

$ man apt_preferences

[ Parent ]

Re: Brute Force Protection with BlockHosts
Posted by Anonymous (193.238.xx.xx) on Tue 31 Jan 2006 at 09:29
Fail2ban require iptables and packet filtering support in kernel configuration. All my server run with a custom kernel without packet filtering support. Fail2ban can work with hosts.deny file, but this is an undocumented hack

[ Parent ]

Re: Brute Force Protection with BlockHosts
Posted by Anonymous (83.219.xx.xx) on Mon 30 Jan 2006 at 15:30
To those who suggested using fail2ban: it uses iptables, so it doesn't work on a virtual server where access to the network interfaces is blocked.

I'm using denyhosts, which is also a python script very similar to blockhosts. I don't know about blockhosts, but denyhosts can be configured to write the blocked hosts in a separate file, e.g. /etc/hosts.blocked, which you can then include from /etc/hosts.deny. This has the advantage of keeping hosts.deny free from hundreds of IP addresses.

http://denyhosts.sourceforge.net/

[ Parent ]

Correction re: hosts.allow / hosts.deny
Posted by chr0nik (68.60.xx.xx) on Mon 30 Jan 2006 at 16:41
[ View Weblogs ]
There should be no activity on /etc/hosts.deny - only one file is touched, hosts.allow, that contains all the denied addresses also.

Thanks to the author of BlockHosts, Avinash Chopde, for the correction.

[ Parent ]

Be careful with this whole approach!
Posted by k8to (64.142.xx.xx) on Mon 30 Jan 2006 at 21:48
Be careful with this whole approach to IP blocking. There are some common flaws that crop up.

The simplest is that depending upon your network config, an attacker can spoof the failed connections to cause you to block access to arbitrary hosts, controlling your network connection as a denial of service or as a prelude to other mischief. Ensuring that these failures represent unspoofed connections is a matter of configuring your services and network stack. Keep on top of these issues.

A more worrying problem is that the regexes as shipped in these packages are often very poorly analyzed (as regexes typically are!) enabling people to login with names like 192.168.0.4, causing that IP address to be blocked. Some of these methods are service specific, but the regexes are often loose enough to be fooled. This definitely affected fail2ban, and I expect it to recur with sufficient creativity and/or laziness over time.

There is also the general problem, which does not affect most stock-configured debian services, of DNS problems. That is, if a service logs reversed hostnames, rather than IP addresses, can be manipulated by causing forward resolution of the name to map to an arbitrary IP address, again allowing the attacker to cause your system to block access to an arbitrary IP address. To safely employ this type of system, your services must log IP addresses, not hostnames.

[ Parent ]

Re: Brute Force Protection with BlockHosts
Posted by Anonymous (193.238.xx.xx) on Tue 31 Jan 2006 at 09:27
For the same target exist also DenyHosts:

http://denyhosts.sourceforge.net/

And I've made a debian package:

http://denyhosts.sourceforge.net/faq.html#1_12

available by adding this repository:

deb http://bertorello.ns0.it/debian binary/

P.S.

This packages will be available in official SID repository as soon as possible

[ Parent ]

Re: Brute Force Protection with BlockHosts
Posted by Anonymous (192.48.xx.xx) on Tue 31 Jan 2006 at 10:39
iptables with:

-A CHAINNAME -i <interface> -p tcp -m tcp --dport 22 -m state --state NEW -m recent \
--set --name DEFAULT --rsource
-A CHAINNAME -i <interface> -p tcp -m tcp --dport 22 -m state --state NEW -m recent \
--update --seconds 60 --hitcount 4 --name DEFAULT --rsource -j DROP

Rate limits connections to 4 per minute per IP. Anything more is dropped. You can choose to tarpit/log/redirect hostile hosts but leave your service open. Needs no intervention or maintenance. Works for me...

[ Parent ]

Re: Brute Force Protection with BlockHosts
Posted by Anonymous (84.133.xx.xx) on Wed 1 Feb 2006 at 07:09
How long will they be blocked? I need to look for newer manpages on my system, I didn't find the answer in there...

[ Parent ]

Re: Brute Force Protection with BlockHosts
Posted by Anonymous (192.48.xx.xx) on Wed 1 Feb 2006 at 15:51
It's a rate limit, not a time limit. i.e. limited to 4 connections in (any) 60 seconds. Any more thatn that from an IP are blocked.

[ Parent ]

Re: Brute Force Protection with BlockHosts
Posted by stevenothing (212.36.xx.xx) on Mon 20 Feb 2006 at 14:03
Last time I tried this there was a bug with the recent module which, after a few days, caused new ssh connections to be blocked instantly; Has this been fixed?

[ Parent ]

Re: Brute Force Protection with BlockHosts
Posted by mnaumann (213.39.xx.xx) on Fri 16 Mar 2007 at 11:21
[ View Weblogs ]

[ Parent ]

Re: Brute Force Protection with BlockHosts
Posted by Anonymous (198.54.xx.xx) on Tue 31 Jan 2006 at 11:16

[ Parent ]

Re: Brute Force Protection with BlockHosts
Posted by hypatia (65.205.xx.xx) on Wed 1 Feb 2006 at 17:22
I've been looking for something like this. I've used portsentry which can change the routing table to block portscans. When it detects a port scan, portsentry issues the command:

/sbin/route add -host $TARGET_IP$ gw 333.444.555.666

This will block all traffic going to TARGET_IP. It's nice to find a tool to block brute force SSH attacks. I don't really like the idea of perminantly banning the IPs though, since they are usually dynamic addresses. I go in once a week or so and clean up my routing table.

[ Parent ]

Re: Brute Force Protection with BlockHosts
Posted by Anonymous (221.31.xx.xx) on Thu 2 Feb 2006 at 14:27
I like fail2ban. It's been packaged for sid. The package can be installed to Sarge without disturbing the environment. You only need Sarge's iptables and python. For ssh, you don't need any configuration.

http://packages.debian.org/unstable/net/fail2ban

[ Parent ]

Re: Brute Force Protection with BlockHosts
Posted by GoodTimes (146.180.xx.xx) on Thu 2 Feb 2006 at 14:46
[ View Weblogs ]
heer's something

you mention how easy the installation is...

after reading this line

python setup.py install --force

I wondered, why --force? what problems are we working around?

aaron


Through correctness comes ease
-Chiun
-The Destroyer series

[ Parent ]

Works without inetd
Posted by Anonymous (84.163.xx.xx) on Fri 3 Feb 2006 at 14:53
The script works without inetd as well. Debian's sshd is compiled with support for tcp wrappers. You can just use sshd as the service name in hosts.deny.

David

[ Parent ]

Re: Brute Force Protection with BlockHosts
Posted by Anonymous (64.186.xx.xx) on Thu 9 Feb 2006 at 02:39
There is also denyhosts already packaged :

apt-get install denyhosts

[ Parent ]

Re: Brute Force Protection with BlockHosts
Posted by Anonymous (70.125.xx.xx) on Fri 3 Mar 2006 at 12:17
There is also denyhosts already packaged :

apt-get install denyhosts
denyhosts is not yet in the sarge repositorys.

[ Parent ]

Re: Brute Force Protection with BlockHosts
Posted by Anonymous (151.38.xx.xx) on Wed 30 May 2007 at 16:55
To use denyhosts on debian with vsftpd logfile I have created these regexp:


SSHD_FORMAT_REGEX = .*? (?P<message>.*)

FAILED_ENTRY_REGEX = .*FAIL LOGIN.*(Client "(?P<host>\d*\.\d*\.\d*\.\d*)*)"

SUCCESSFUL_ENTRY_REGEX = .*OK LOGIN.*(Client "(?P<host>\d*\.\d*\.\d*\.\d*)*)"

:) bort_83

[ Parent ]

Re: Brute Force Protection with BlockHosts
Posted by Anonymous (85.181.xx.xx) on Sat 1 Jul 2006 at 10:48
Most services in Debian are compiled using libwrap, so they can be left running in standalone mode and don't need to be specifically called from inetd using tcp_wrappers.

Other than that, thanks for the nice description.

[ Parent ]

How to do this regex?
Posted by Anonymous (200.150.xx.xx) on Wed 16 Dec 2009 at 15:35
pop3d: LOGIN FAILED, user=user, ip=[::ffff55.55.55.555]

[ Parent ]