How can I delay sshd login after bad password

If you block all user even block root you can add this lines to /etc/pam.d/password-auth or /etc/pam.d/sshd, in the auth section add this to block all user for 5 minutes:

auth        required      pam_tally2.so  file=/var/log/tallylog deny=3 even_deny_root unlock_time=300

Now add the following line to the account section:

account     required      pam_tally2.so

Finaly restart your sshd and it should work. After this you can check for fault logins with the command: pam_tally2 You will get this output:

# pam_tally2
Login           Failures Latest failure     From
userxy            4    12/10/13 09:52:31  192.168.100.100

You can try to add

auth       optional   pam_faildelay.so  delay=250000

to the pam config file for sshd (In Debian systems usually in /etc/pam.d/sshd) Delay value of 250000 are 0.25 seconds.


IPtables rules can be tweaked to achieve what you are trying to achieve.

Assumption: Your embedded linux has netfilter module compiled in and provided you know firewall concept and you used iptables before. root access is assumed. If you are sudo capable, append sudo infront of the commands.

iptables -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -m recent --set --name DEFAULT --rsource

The syntax has no vebosity desired but the line instructs firewall police iptables that you want to append a rule onto the existing INPUT chain. The -p tcp argument indicates that this rule will apply only to TCP packets. Most of the rest of the arguments rely on the -m option, which stands for match and tells iptables that the rule applies to packets which match the specific attributes we’re looking for. Here, the rule will be applied to packets that signal the start of new connections headed for TCP port 22. If a packet matches those attributes, iptables will note the remote host’s address in a temporary list.

iptables -N LOG_AND_DROP

Above rule will actually perform an action using a different chain, and in order to append it, we’ll need to first create the chain which we did (e.g LOG_AND_DROP)

iptables -A INPUT  -p tcp -m tcp --dport 22 -m state --state NEW -m recent --update --seconds 20 --hitcount 4 --name DEFAULT --rsource -j LOG_AND_DROP

This rule tells iptables to look for packets that match the previous rule’s parameters, and which also come from hosts already added to the watch list. If iptables sees a packet coming from such a host, it will update the “last seen” timestamp for that host. The --seconds 20 and --hitcount 4 arguments are used to narrow further the hosts we want to block—if a host tries to connect four or more times within sixty seconds, it matches that part of the rule and we jump (-j) to the LOG_AND_DROP chain.

iptables -A INPUT  -p tcp -m tcp --dport 22 -j ACCEPT

Technically speaking, this rule isn’t necessary with the INPUT chain since default is set to policy ACCEPT for all unmatched packets. Fail-safe if you happen to build a restrictive firewall e.g. default reject.


Appending after getting feedback from @singh. I did not realise state has been evicted in favour of more techie conntrack (connectiontracking) module

Instead of e.g.:

-m state --state RELATED

-m conntrack --ctstate RELATED