I’m spinning up a new CentOS Stream 9 on a cloud VPS. It will be used host a bunch of stuff (nextcloud, VPN server, etc)
The OS is installed through the VPS provider’s image. CIS Server Level 1 security remediation is applied on first boot.
SELinux is enforcing, firewalld is running. EPEL and EPEL Next Release are installed, system is fully updated. SSH keys are installed and I can log in correctly with no problems.
My next step is to configure SSH to use 2FA (TOTP).
CentOS Stream 9, unlike its previous versions or the Fedora 34 that it’s based on, does NOT include the awesome google-authenticator package. So I’m using the oathtool & pam_oath packages to set up TOTP.
Things that work:
- I can login with my ssh keys if I don’t use the oath PAM.
- The vps and my mobile are producing the correctly synced TOTP codes
- If I define the oath pam in pam.d/sshd, I do get asked the TOTP code
Things that DON’T work:
- The login process ALWAYS asks for a password with the TOTP. Using the -v option on ssh shows that there’s no communication with the server before asking for the password, ie the server expects both the TOTP code AND the password to authenticate
- The server accepts any 6-digit code, even incorrect ones, and will happily authenticate if the password is correct.
- Making pam_oath.so “required” in the /etc/pam.d/sshd makes login impossible.
I have my sshd configs in a seperate config file inside sshd_config.d but running “sshd -T” shows that I have the necessary bits setup correctly as far as sshd_config is concerned:
ChallengeResponseAuthentication yes
PasswordAuthentication no
UsePAM yes
AuthenticationMethods publickey,keyboard-interactive
I’m guessing I’m messing up with my /etc/pam.d/sshd configuration but I can’t figure out what
This is how it looks currently:
# PAM-1.0
auth sufficient pam_oath.so usersfile=/etc/users.oath window=30 digits=6
auth substack password-auth
auth include postlogin
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
# auth sufficient pam_oath.so usersfile=/etc/users.oath window=30 digits=6
As it currently stands, the login process asks for OTP first, password second. If I comment out the first line and remove the comment on the last time, it asks for password first, OTP second.
Furthermore, if I make the line “auth required pam_oath.so…” It keeps asking for OTP + password over and over and fails after 3 tries. According to logs authentication fails with no explanation as to why it failed.
Questions:
- How do I make it so that it only asks for OTP and not the password?
- How do I make it so that it only accepts the correct OTP and not just and 6 digit number
- Optional question: One of the users has an SSH key with yubikey, is there any way to configure it so that it asks for TOTP for users with regular keys and no OTP for the user with yubikey protected SSH key?
Thanks
PS: I’m not well-versed in Linux, I arrived at this skill level by headbutting problems so explanation on how things work would be especially welcome.