Thank you, @Ritov! This didn’t get me all the way there, but it made me look in the right places. I had overlooked /etc/ssh/sshd_config.d/ and hadn’t been aware that I had files in there that were overriding whatever I directly put into my modified /etc/ssh/sshd_config
For the benefit of others who look for a solution and stumble across this topic, here is what I did:
From Epel9 I installed these RPMs:
dnf install google-authenticator qrencode qrencode-libs
Then I fixed up the SSH configuration:
sed -i 's|^ChallengeResponseAuthentication no|#ChallengeResponseAuthentication no|g' /etc/ssh/sshd_config.d/50-redhat.conf
echo "ChallengeResponseAuthentication yes" > /etc/ssh/sshd_config.d/10-gauth.conf
Edited /etc/pam.d/sshd to change it to this:
#%PAM-1.0
auth substack password-auth
auth include postlogin
auth required pam_google_authenticator.so secret=${HOME}/.google_authenticator nullok no_increment_hotp
account required pam_sepermit.so
account required pam_nologin.so
account include password-auth
password include password-auth
# pam_selinux.so close should be the first session rule
session required pam_selinux.so close
session required pam_loginuid.so
# pam_selinux.so open should only be followed by sessions to be executed in the user context
session required pam_selinux.so open env_params
session required pam_namespace.so
session optional pam_keyinit.so force revoke
session optional pam_motd.so
session include password-auth
session include postlogin
Then I made some further changes to /etc/ssh/sshd_config and my combined SSHd config now looks like this:
]# cat /etc/ssh/sshd_config.d/* /etc/ssh/sshd_config|grep -v ^#|awk NF
PermitRootLogin yes
ChallengeResponseAuthentication yes
Include /etc/crypto-policies/back-ends/opensshserver.config
SyslogFacility AUTHPRIV
GSSAPIAuthentication yes
GSSAPICleanupCredentials no
UsePAM yes
X11Forwarding yes
PrintMotd no
Include /etc/ssh/sshd_config.d/*.conf
AuthorizedKeysFile .ssh/authorized_keys
Subsystem sftp /usr/libexec/openssh/sftp-server
PermitRootLogin yes
StrictModes no
AllowTcpForwarding no
X11Forwarding no
X11DisplayOffset 10
PubkeyAuthentication yes
Protocol 2
Port 22
# Want password-auth generally on? Use this:
PasswordAuthentication yes
# Want password only for users of google-authenticator group,
# provided they don't have a pubkey set up? Use this instead:
Match Group google-authenticator
AuthenticationMethods publickey keyboard-interactive
Match all
AuthenticationMethods publickey
Then I added the group ‘google-authenticator’ and added all users with configured Google Authenticator to it:
groupadd google-authenticator
usermod -aG google-authenticator [username of user with GoogleAuth set up]
That way it now works like this:
- User not in group ‘google-authenticator’ and doesn’t have SSH keys exchanged?
They get: Permission denied (publickey).
- User has SSH key exchanged, but isn’t in ‘google-authenticator’ group?
Can login w/o password - just with the SSH key.
- User has SSH key exchanged, is in group ‘google-authenticator’ and has authenticator configured?
They get in just with the key.
- User has NO key exchanged, is in group ‘google-authenticator’ and has authenticator configured?
They get asked for their password and the verification code from the authenticator.
There are probably other/better ways to do it, but the above suits my usage needs best. Playing around with the ‘AuthenticationMethods’ one can pretty much tweak it to other usage cases. Such as to require OTP and/or passwords for key based logins as well.