Linux – how to require publickey and otp, or password and otp when logging in with ssh

googlelinuxpamssh

I'm trying to get ssh to work in a way where password auth can be skipped with a key, and in addition every login would be followed up with totp using google's libpam on my new debian 9 installation.

So far i've been able to get the first part working, where if i provide a key, the server asks me for the otp, but the way it is, i've had to comment out both @include common-auth and @include common-password to suppress the password prompt in /etc/pam.d/sshd.

Seems obvious then that if i do
AuthenticationMethods publickey,keyboard-interactive:pam password,keyboard-interactive:pam in my sshd_config and i try logging in without a key it does not matter what password i provide since the password checking parts are commented out.

The logical way to solve this as it would seem to a novice like me, would be that i could define different pam methods or classes, and then somehow reference those in my sshd_config, but i cant seem to find any information regarding such an operation.

Is it even possible to accomplish this particular combo?

edit 1:

Tinkering further with this, it really does not make as much sense as i initially thought.
If i comment out both @include common-auth and @include common-password, i can get publickey,keyboard-interactive:pam to not ask for password. If i now set AuthenticationMethods password for a specific user, that user is not able to log in at all due to every password being rejected, even if it really is the valid one. So logically then it seems sshd password auth method also uses the /etc/pam.d/sshd configs.
if i dont comment those includes, keyboard-interactive:pam asks for password and verification code, but password auth method still fails for any user that has otp initialized (and would fail for all except i give google libpam the nullok option). Seems like password is just a crappy version of keyboard-interactive:pam that can only prompt for one input and thus always fails if there are more then one required inputs.

If i write my own pam.d module, is there any way to make ssh use it instead of /etc/pam.d/sshd?

edit 2:

Im starting to think that i cant do (password && otp) || (publickey && otp), because the public key is checked in a different place from the rest, and so unless i can define which pam config to use with AuthenticationMethods, or i can somehow send parameters/arguments to the pam module, knowing when to check both and when to only check otp seems impossible

Best Answer

The parameter you are looking for in the sshd_config is AuthenticationMethods. I wrote a blog post about combinting SSH key authentication with OTP a while ago.

However, this blog post uses the OTP with a pam module against the privacyIDEA authentication system. But you should be able to easily exchange this with the google pam.