SSH public key authentication with google authenticator still asks for password
I'm trying to enable 2FA with ssh using libpam-google-authenticator. Not all users need authenticator enabled. Everybody uses ssh public keys, and nobody has a password. I'm running Debian buster, and I've also tried libpam-google-authenticator from bullseye.
My problem is that no matter what I put in the PAM config, users without authenticator enabled are never logged straight in, but always asked for a password.
I've install libpam-google-authenticator and configured /etc/ssh/sshd_config with:
PasswordAuthentication no
ChallengeResponseAuthentication yes
AuthenticationMethods publickey,keyboard-interactive
PasswordAuthentication no
PermitEmptyPasswords no
I haven't been able to work out the correct PAM config so that users without a .google_authenticator file are still logged in. Depending on what I use, users are either prompted for a password (they don't have one), or not allowed in at all.
In /etc/pam.d/sshd I've tried (like this Trying to get SSH with public key (no password) + google authenticator working on Ubuntu 14.04.1):
#@include common-auth
auth required pam_google_authenticator.so debug nullok
In this case, users without an authenticator setup get rejected with the following debug;
Aug 05 15:11:18 <host> sshd(pam_google_authenticator)[746624]: debug: start of google_authenticator for "<user>"
Aug 05 15:11:18 <host> sshd(pam_google_authenticator)[746624]: debug: end of google_authenticator for "<user>" Result: The return value should be ignored by PAM dispatch
Aug 05 15:11:18 <host> sshd[746620]: error: PAM: Permission denied for <user> from <IP>
Is pam_permit
is needed to set up the fallback case?
I've also tried various combinations of auth required
and auth sufficient
before and after @include common-auth
but they all result in users without authenticator being asked for a password and sometimes users WITH authenticator also being asked for a password.
Does anyone have a recipe to make this work?
Here is my working configuration. Some users have authenticator enabled and some don't, and only SSH logins with public keys are permitted, never passwords.
In /etc/ssh/sshd_config,
UsePAM yes
PasswordAuthentication no
ChallengeResponseAuthentication yes
AuthenticationMethods publickey,keyboard-interactive
PermitEmptyPasswords no
In /etc/pam.d/sshd,
# Standard Un*x authentication.
#@include common-auth
# Require authenticator, if not configured then allow
auth required pam_google_authenticator.so debug nullok
auth required pam_permit.so
@include comon-auth
must be disabled because it includes pam_unix, which I don't want to use. Then you need pam_permit
to make authentication successful for users without authenticator (for which pam_google_authenticator
returns ignore rather than pass).
This still doesn't let root login with an ssh key; sshd logs
sshd[1244501]: fatal: Internal error: PAM auth succeeded when it should have failed
This is discussed at Google Authenticator PAM on SSH blocks root login without 2FA .
Having gotten this working as above, I think it's actually nicer to enforce 2FA for certain groups using the SSH config as @zoredache suggested. This easily allows you to whitelist certain IPs as not requiring 2FA also. In this case, sshd_config says for example
UsePAM yes
PasswordAuthentication no
ChallengeResponseAuthentication yes
#AuthenticationMethods any # default
PermitEmptyPasswords no
Match Group adm Address *,!172.16.1.0/24
AuthenticationMethods publickey,keyboard-interactive
and /etc/pam.d/ssh says
Standard Un*x authentication.
#@include common-auth
# Require authenticator; SSH should not allow any user in who doesn't have it
auth sufficient pam_google_authenticator.so debug nullok
auth requisite pam_deny.so