BlockHosts is a python script that protects against brute force dictionary attacks of ssh and ftp servers. For example, when sshd is scanned by a spammer looking for new email addresses or a script kiddie looking for accounts with weak passwords, your system logs will be flooded with warning messages indicating unsuccessful logins. Your logs become clogged with thousands of messages like this:
sshd: Invalid user sales from 184.108.40.206 sshd: error: Could not get shadow information for NOUSER sshd: Failed password for invalid user sales from 220.127.116.11 port 51565 ssh2
Blockhosts uses the "spawn" feature of TCP wrappers to run automatically from /etc/hosts.allow when an ssh connection is made. It then reads the portion of a specified log file that has changed since the last connection. If certain conditions are met, it adds the attacker's IP number to hosts.allow, preventing them from connecting again. After a fixed period of time, the attacker's IP is automatically removed. You can then decide whether to add their IP address to your firewall, permanently "blackholing" the attacker. (The guy at 18.104.22.168 made the cut). The program works well and uses no CPU time unless a specified connection is occurring.
Some people argue that this type of automatic IP blocking will encourage attackers to spoof their return IP address, turning the scan into a denial of service attack against an innocent third party by tricking you into blocking their access to your site. However, this scenario is extremely improbable. If the attacker forges the return IP address, the packets do not return to the attacker and he or she has no way of knowing whether the attack was successful. The attacker gains no information, and meanwhile, they may have blocked one or two individuals from logging into your server for a day or so. It would be a very feeble DOS indeed, and one that does not match the interests of most attackers.
- Make sure your sshd is compiled with tcpwrappers support.
- Install python 2.3, 2.4 or higher. By default python installs in
/usr/local, which means you must remove
the old versions manually. The easiest way is to remove the links.
rm /usr/bin/python rm /usr/lib/python
- Edit blockhosts.cfg to specify which log file to watch and how many attempts to allow, and add any special conditions to check for.
- Add the following 3 lines to /etc/hosts.allow:
The "BlockHosts Additions" line must be in front of the line where blockhosts.py is called, otherwise blockhosts will be called, but an "allow" is granted before the forbidden hosts can be read (Thanks to Martin Dittmar for pointing this out).
#---- BlockHosts Additions sshd, proftpd, in.proftpd: ALL: spawn (/usr/bin/blockhosts.py \ --verbose --echo "%c-%s" >> /var/log/blockhosts.log 2>&1 )& : allow
- Add /usr/local/bin to root's path if
necessary and install blockhosts:
python setup.py install --force
- Get blockhosts up-to-date in the log file.
- Before logging out, check to make sure it doesn't add your own IP by mistake. And don't forget to turn it off if you run nessus.
Update: We have recently switched to Denyhosts instead of Blockhosts. Denyhosts works the same way as Blockhosts, but is a daemon and doesn't store its state in your hosts.allow file.