Suppose you pause for 10s (after an incorrect password/before checking the password/...). This make it very easy to spawn so many sshd processes that you end up with a DoS (either the system stops spawning sshd processes, locking out everyone, or it is overwhelmed). If you solve this somehow, the bad guys can just open a ton of connections and just wait 10s - they'll need more connections, but they can still saturate the link with login attempts. Blocking IPs after too many connections doesn't help much against botnets; limiting the number of total connections locks out legitimate users; blocking all but specific address blocks locks out legitimate users (at home, or your sysadmin-on-a-holiday trying to fix your system in an internet cafe halfway across the globe.)
In short, anything you do seems to make it easy (easier) to lock out legitimate users. On the other hand, switching to private-key-only or private-key-and-one-time-password-only (or instituting a check on password quality) makes this attack infeasible.
There is, but I've never seen it implemented. Throttle login attempts by requiring a cryptographic proof-of-work to accompany each attempt. Send the credentials and proof-of-work over UDP so that there's no connection state to hold open. Scale the required amount of work up and down based on the total number of incorrect attempts in the past minute. After a successful login, issue systems a long-lived cookie that exempts them from future proof-of-work requirements. That way, during attacks, legitimate users may experience a longer delay when trying to log in, but only if they've never logged in from that system before, and they can never be locked out completely.
Besides, I, too, do not recall any actually working implementations.
IPTABLES=/usr/sbin/iptables
# only allow up to 2 connections in a 15 second period
$IPTABLES -A INPUT -p tcp --dport 22 \
-m state --state NEW \
-m recent --update --seconds 15 --hitcount 2 \
-j DROP
$IPTABLES -A INPUT -p tcp --dport 22 \
-m state --state NEW \
-m recent --set \
-j ACCEPT
That's enough to really slow down brute force attacks without locking out fat-fingered users for too long.Finally, I use fail2ban to block persistent attacks for 6 hours after 8 failures/hr in jail.conf:
# Failed login attempts against SSH (port 22)
[ssh-iptables]
enabled = true
filter = sshd
logpath = /var/log/messages
maxretry = 8
bantime = 21600
findtime = 3600
action = iptables[name=SSH, port=ssh, protocol=tcp]
sendmail-whois-lines[name=SSH, dest=admin, logpath=/var/log/messages]
This allows me to identify attacks and penalize them hard without affecting real users. This basically leaves a DoS as the only threat, and only if you're using the same IP address as the attacker.It may look complicated, but it only takes a few minutes to set up and doesn't require using a nonstandard port (which you can do to further harden the system, along with other things). In my experience, this has been enough to thwart brute force attacks against ssh.
From Wikipedia:
In the case of an offline attack where the attacker has access to the encrypted material, he can try key combinations at his leisure without the risk of discovery or interference. However database and directory administrators can take countermeasures against online attacks, for example by limiting the number of attempts that a password can be tried, by introducing time delays between successive attempts and locking accounts out after unsuccessful logon attempts. Website administrators may prevent a particular IP address from trying more than a predetermined number of password attempts against any account on the site.