Check the auth log on any server with port 22 open and it's always the same story: endless login attempts from IPs that have clearly done this before. fail2ban bans them, the bantime runs out, and that's it. Nothing learned, nothing shared.
A while ago I started sending those bans to a shared blacklist instead of letting them disappear. I use the one on bl.ipwhois.net, mostly because it needs no signup and no API key. You get 500 requests a day per source IP, which is plenty for a normal server.
Checking an address looks like this:
curl "https://bl.ipwhois.net/api/check?ip=203.0.113.5"
{"ip":"203.0.113.5","listed":false,"message":"Not found in IPWhois Blacklist","rate_limit":{"limit":500,"remaining":499}}
Reporting is a POST to the same API. To make fail2ban do it on every ban, drop this into /etc/fail2ban/action.d/ipwhois-report.conf:
[Definition]
actionstart =
actionstop =
actioncheck =
actionban = curl -s -X POST "https://bl.ipwhois.net/api/report" -d "ip=<ip>" -d "type=<name>" -d "comment=fail2ban <name> ban"
actionunban =
and add the action to whatever jails you want in jail.local:
[sshd]
enabled = true
action = iptables-multiport[name=sshd, port="22"]
ipwhois-report[name=sshd]
Reload fail2ban and that's it. The <ip> and <name> tags get filled in by fail2ban itself, so the jail name ends up as the threat type.
The other direction is more useful. There's a plain text feed of everything the community reported (only direct reports, fail2ban setups like this one, and honeypots, they don't mix in other people's feeds). One IPv4 per line, refreshed every 30 minutes. I load it into an ipset once an hour:
curl -s https://bl.ipwhois.net/feed.txt | grep -v '^#' > /tmp/ipwhois_bl.txt
ipset create ipwhois_bl hash:ip -exist
ipset flush ipwhois_bl
while read -r ip; do ipset add ipwhois_bl "$ip" -exist; done < /tmp/ipwhois_bl.txt
iptables -I INPUT -m set --match-set ipwhois_bl src -j DROP
It's around a thousand entries, the whole refresh takes under a second.
Two warnings from experience. Whitelist your own IPs above the DROP rule, because sooner or later you'll be connecting from a network somebody reported. And run the rule with -j LOG instead of DROP for a day first, just to see what it would have caught.
One more habit that stuck: when a banned IP keeps coming back, I run it through an IP lookup to see who actually owns it. Half the time it's some cheap VPS provider, and a quick IP whois check turns up the abuse contact. Forwarding a chunk of auth.log to that address works more often than you'd think, especially with smaller hosters.
Top comments (0)