Attackers change their behavior, so we have to change in response.
Way back in the olden days, someone with evil intent would ping your IP address to make sure it was up, run nmap to figure out which of four or five exploitable services were available, and then pound their fist against the door repeatedly with different usernames and passwords until they got bored or found a way in.
Ah, those were the days.
Now a botnet works in phases: one segment compiles a list of IP addresses that respond on the right ports; another group sends a single attack to each host on the list. They evade rate-limiters by mimicking a distributed denial of service attack, only much slower.
I used to run a response system which would note several failed logins from a particular IP address and add a firewall rule to ban it. After a while it would remove the rule.
Then I changed to a two-part system: a few attempts would incur a temporary ban, but more attempts over a longer period of time would ban the source for a very long time indeed.
I have now instituted a third part: some attempts are going straight from
a single try to the permaban list. Among other things, trying to log in to
my ssh or IMAP services with the username
root will get this response.
There are 4 billion IPv4 addresses out there, and a dismaying fraction of them appear to be owned by botnets.