Introducing Blockhosts

Posted . ~2min read.

Avinash Chopde, back in 2005 (or so), wrote an incredible python script: blockhosts.py. On systems that we deployed that needed public access to SSH, blockhosts was simply a requirement.

Fast, effective, lightweight. Just a phenomenal script.

A lot has changed since 2005, and roughly 20 years later, the default versions of python installed with an OS don’t like the script anymore. Not a problem for most python developers. Problem: I’m not a python developer.

When I started APIBAN, one reason was to learn to build an api in go(lang). In the last 4 years, I would hardly say I’m a Go “programmer” (and I’m sure that people who read my code would agree).

This said, I’m comfortable in Go, and thought that perhaps I could write my own version of blockhosts to help protect some of the servers I work on that still need global access to SSH.

And with that long introduction…

Blockhosts, in Go

Blockhosts is an SSH Log parser / blocker using Golang and IPtables. It’s open source (MIT License) and available on GitHub:

There’s a config file (bhconfig.json) that stores the blocklist, watchlist, and allowed IPs (aka IPs that should not be blocked). For Allowed, you use CIDR format, such as:

"Allowed": [{"cidr":"192.168.0.0/16"},{"cidr":"1.1.1.1/32"},{"cidr":"10.0.10.0/24"}]

Normally, I keep the blockhosts and config file in /usr/local/bin… but this is your choice. I have deploy instructions in the README file.

I recommend you deploy blockhosts just like the blockhosts.py script; using hosts.deny. For example, on Debian based systems, one would update hosts.deny by adding the following to the bottom of the file:

sshd : ALL : spawn (/usr/local/bin/blockhosts) : allow
sshd : ALL : allow

On Redhat/Centos type systems, you would just add the flag to check the “secure” log vs “auth.log”, such as:

sshd : ALL : spawn (/usr/local/bin/blockhosts -ssh=/var/log/secure) : allow
sshd : ALL : allow

Speaking of flags…

You can modify some defaults via optional flags:

  • ssh - log file to parse (default = /var/log/auth.log)
  • target - iptables action (default is DROP – you may like REJECT instead)
  • chain - the iptables chain for adding attackers, default it APIBANLOCAL. If the chain does not exist, it will be created for you.
  • log - log file for output, default is /var/log/blockhosts.log
  • xtra - true/false (default is false). super verbose logging.

Hope you like it… perhaps even throwing a star it’s way. ;)

Happy New Year!

Next...
...and even more...