pam_unix contains a hardcoded max retries value of 3. After 3 failed attempts, it starts to return PAM_MAXRETRIES instead of the normal failure status. According to the pam_authenticate(3) manpage: PAM_MAXTRIES One or more of the authentication modules has reached its limit of tries authenticating the user. Do not try again. However, it seems that sshd ignores this and does try again. Pam keeps a count of failed attempts and on cleanup, when this count is higher than the max retries, it emits a message to syslog: Jun 24 02:23:42 login sshd[4821]: PAM service(sshd) ignoring max retries; 6 > 3 This can be worked around by setting AuthMaxTries to 3 in sshd_config, but it seems that sshd should really listen to pam and handle the PAM_MAXRETRIES result by not allowing further retries. I've observed this behaviour on 6.0p1, but looking at the source for 6.6p1 it looks like PAM_RETRIES isn't handled there either. I couldn't find an easy way to browse the most current VCS version, so I didn't check there. See also: https://git.fedorahosted.org/cgit/linux-pam.git/tree/modules/pam_unix/support.c#n297 https://git.fedorahosted.org/cgit/linux-pam.git/tree/modules/pam_unix/support.c#n803 https://git.fedorahosted.org/cgit/linux-pam.git/tree/modules/pam_unix/support.c#n353
It seems things are a bit less obvious when I thought. When I try to reproduce the log message by trying to log in with dummy passwords, it seems sshd kicks me out after 3 tries: Jun 25 13:26:12 login sshd[6762]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=84-245-29-136.dsl.cambrium.nl user=root Jun 25 13:26:14 login sshd[6762]: Failed password for root from 84.245.29.136 port 44444 ssh2 Jun 25 13:26:16 login sshd[6762]: Failed password for root from 84.245.29.136 port 44444 ssh2 Jun 25 13:26:18 login sshd[6762]: Failed password for root from 84.245.29.136 port 44444 ssh2 Jun 25 13:26:18 login sshd[6762]: Connection closed by 84.245.29.136 [preauth] Jun 25 13:26:18 login sshd[6762]: PAM 2 more authentication failures; logname= uid=0 euid=0 tty=ssh ruser= rhost=84-245-29-136.dsl.cambrium.nl user=root This log suggests that the client actually closed the connection, not the server. Is there perhaps some limit builtin to the ssh client? I also see this in my logs, presumably from a password bruteforcer that might be violating the SSH protocol? Jun 25 11:28:58 login sshd[6419]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=116.10.191.168 user=root Jun 25 11:29:01 login sshd[6419]: Failed password for root from 116.10.191.168 port 37803 ssh2 Jun 25 11:29:03 login sshd[6419]: Failed password for root from 116.10.191.168 port 37803 ssh2 Jun 25 11:29:05 login sshd[6419]: Failed password for root from 116.10.191.168 port 37803 ssh2 Jun 25 11:29:07 login sshd[6419]: Failed password for root from 116.10.191.168 port 37803 ssh2 Jun 25 11:29:09 login sshd[6419]: Failed password for root from 116.10.191.168 port 37803 ssh2 Jun 25 11:29:12 login sshd[6419]: Failed password for root from 116.10.191.168 port 37803 ssh2 Jun 25 11:29:12 login sshd[6419]: Disconnecting: Too many authentication failures for root [preauth] Jun 25 11:29:12 login sshd[6419]: PAM 5 more authentication failures; logname= uid=0 euid=0 tty=ssh ruser= rhost=116.10.191.168 user=root Jun 25 11:29:12 login sshd[6419]: PAM service(sshd) ignoring max retries; 6 > 3
(In reply to Matthijs Kooijman from comment #1) > It seems things are a bit less obvious when I thought. When I try to > reproduce the log message by trying to log in with dummy passwords, > it seems sshd kicks me out after 3 tries: [...] > Jun 25 13:26:18 login sshd[6762]: Connection closed by 84.245.29.136 > [preauth] That's actually the (presumably OpenSSH) client disconnecting after 3 attempts. That's settable via NumberOfPasswordPrompts (see ssh_config). > Jun 25 13:26:18 login sshd[6762]: PAM 2 more authentication > failures; logname= uid=0 euid=0 tty=ssh ruser= > rhost=84-245-29-136.dsl.cambrium.nl user=root > > This log suggests that the client actually closed the connection, > not the server. Is there perhaps some limit builtin to the ssh > client? Yes, see above. > I also see this in my logs, presumably from a password bruteforcer > that might be violating the SSH protocol? No, it just doesn't have a client-side limit (which makes sense given its apparent purpose).
Created attachment 2832 [details] stop offereing password and keyboard-interactive auth when PAM_MAXTRIES reached It took some plumbing but this patch should stop offering "password" and "keyboard-interactive" auth methods as soon as PAM returns PAM_MAXTRIES. To test this, I used the following PAM config: #%PAM-1.0 auth required pam_unix.so try_first_pass nullok auth required pam_deny.so account required pam_unix.so session required pam_unix.so It took me a while to figure out why the default (fedora and ubuntu) configs didn't give me PAM_MAXTRIES. They have configs like: auth sufficient pam_unix.so try_first_pass nullok auth required pam_deny.so but that meant that pam_deny always provided the return code and I never saw PAM_MAXTRIES. The other caveat is that for challange-response authentication, sshd runs the PAM modules in a separate process. pam_unix usually won't be able to keep track of the retries, so it won't return PAM_MAXTRIES.
Here's what it looks like on the client side: $ ssh -o preferredauthentications=password -o numberofpasswordprompts=10 -v -p 2022 localhost [...] debug1: Authentications that can continue: publickey,password,keyboard-interactive debug1: Next authentication method: password dtucker@localhost's password: debug1: Authentications that can continue: publickey,password,keyboard-interactive Permission denied, please try again. dtucker@localhost's password: debug1: Authentications that can continue: publickey,password,keyboard-interactive Permission denied, please try again. dtucker@localhost's password: debug1: Authentications that can continue: publickey debug1: No more authentication methods to try. Permission denied (publickey).
The patch has been committed and will be in the 7.3p1 release. Thanks.
https://anongit.mindrot.org/openssh.git/commit/?id=01558b7b07af43da774d3a11a5c51fa9c310849d
Close all resolved bugs after 7.3p1 release