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 isDROP
– you may likeREJECT
instead)chain
- the iptables chain for adding attackers, default itAPIBANLOCAL
. 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 isfalse
). super verbose logging.
Hope you like it… perhaps even throwing a star it’s way. ;)
Happy New Year!