Blocking Hackers
How to prevent password guessing attacks against SSH
Remote SSH login access is pretty much a necessity for administering and managing Unix/Linux servers. But how to allow access for the admins without also letting in the hacker hordes? VPNs are one solution, but they can be a pain to use and to setup, especially if you’re working with machines on several different networks.
Servers that allow direct SSH access, are going to attract plenty of remote login attempts. You need to ensure that the hackers can’t just keep beating on your door presenting different passwords until they get lucky. On one fairly typical server I administer there are around 2,800 failed login attempts per day or roughly one attempt a second. Installing a blocker for brute-force password hacking has been on my todo list for a while. This week I finally got a round tuit.
There’s an art to preventing brute-force password guessing attacks. You want to block hackers from having enough tries that they might hit on an actual password, but you don’t want to block so aggressively that you risk locking yourself or your legitimate users out.
I looked at two tools for limiting brute force password guessing hacks: fail2ban and sshguard. Both tools monitor the SSH log files for failed login attempts and insert firewall rules to block the IP addresses of those sources that make repeated failed attempts.
Of the two, fail2ban is the more heavy weight – it’s a python daemon with a flexible monitoring that can watch web, FTP, and email server logs as well as SSH logs. When it blocks an IP address it does so for a configurable but fixed amount of time. When that time has expired, fail2ban automatically removes the block rule. In an upcoming version (v0.11) it will have a facility for a progressively longer block times for sources that continue generating bad login attempts. I took a gander at the codebase to see how soon that release might be forthcoming. What I saw didn’t inspire confidence. Unfortunately, the code isn’t well documented or clearly organized and the manual hasn’t been updated for the upcoming release.
The other tool, sshguard, seemed more promising. It’s a lightweight server written in C. That’s a plus for me, as tools without a lot of dependencies are less likely to cause upgrade headaches later. It only works with SSH, but that’s fine for my purposes. Crucially, it already has an algorithm for progressively increasing the block duration. You configure an initial block period in seconds. The program notices repeat offenders and increases the block period by a factor of 1.5 each time a particular IP is blocked for repeated login failures. This is great. The more aggressively a hacker hits you, the longer they will be blocked for. Why not assert a permanent ban? You can do that, but I’d rather not. IP addresses change use over time (bad IPs can become good) and again, you don’t want to risk locking yourself out of your own server.
Installation
Installation on Ubuntu 18.04 is straightforward (# apt install sshguard
). It comes with a systemd service file (/lib/systemd/system/sshguard.service
) and a configuration file (/etc/default/sshguard
). Modify the configuration file with the value that make sense for you for the block threshold (-a), initial block duration (-p <seconds>), monitoring period timeout (-s <seconds>), and any other parameters from man sshguard
that you care to customize.
Monitoring
You can find out which hosts are currently blocked by looking at the relevant iptables rules. Ubuntu uses ufw for firewall configuration. It is iptables under the hood, so that’s no problem. sshguard also supports ipfw and pf, in case that’s what you’re already using.
$ iptables -n -L sshguard Chain sshguard (1 references) target prot opt source destination DROP all -- 153.36.232.49 0.0.0.0/0 DROP all -- 222.186.15.110 0.0.0.0/0 DROP all -- 211.24.103.163 0.0.0.0/0 DROP all -- 103.249.100.48 0.0.0.0/0 DROP all -- 222.186.52.123 0.0.0.0/0 ...
I checked the addresses at the AbuseIPDB. It will tell you if other people are seeing attacks coming from the same sources. Of course these are mostly not targeted attacks but robots scanning a large number of hosts. It’s likely that any source making login attempts against your server is also trying it against a lot of other people.
One might think of using AbuseIPDB or another similar blacklist as a source for IP addresses to block. I think that’s a little risky though. One could imagine an attack that submitted false hacking reports to the abuse databases as a denial of service attack – an attempt to prevent legitimate users from logging in. Perhaps that’s just my paranoia, but that’s the thing about doing computer security. It necessarily makes you a bit paranoid.
What shows up in the iptables list is just the currently blocked hosts. Hosts will be added and removed from this list automatically over time by sshguard. To see when hosts were added and for how long, take a look at the sshguard entries in auth.log:
$ grep sshguard /var/log/auth.log ... Jul 19 20:06:46 host sshguard[7553]: Blocking 148.70.65.131 for 240 secs (6 attacks in 1738 secs, after 1 abuses over 1738 secs) Jul 19 20:11:46 host sshguard[7553]: Blocking 222.186.15.110 for 3840 secs (6 attacks in 11 secs, after 5 abuses over 112607 secs) Jul 19 20:11:48 host sshguard[7553]: 222.186.15.110 has already been blocked Jul 19 20:24:59 host sshguard[7553]: Blocking 153.36.232.49 for 3840 secs (6 attacks in 12 secs, after 5 abuses over 101629 secs) ...
Wonderful! We can see that sshguard is finding the failed login attempts and blocking access from those IPs with increasingly long block durations for repeat offenders.
P.S. I would be remiss if I didn’t mention that all of this should be done in addition to basic SSH hardening. In particular using public key authentication instead of password authentication much improves the security situation. Once all users are setup with public keys, disabling password logins altogether (with PasswordAuthentication no
in the sshd_config
) is an excellent idea. That greatly reduces the need for tools like sshguard, though it doesn’t eliminate it entirely. While public key authentication login attempts are much less common and more difficult than password logins, sshguard can monitor and block those too.