The OpenSSH server has limits on what user authentication you can use
We've recently deployed multi-factor authentication for SSH access to some especially sensitive machines, which has caused me to become much more familiar with how OpenSSH's sshd and MFA interact with each other and the limits on that. Unfortunately these limits mean that some combinations of authentication methods are not really available (or not available at all). For example, in many situations you can't require people to use their Unix password and then either a public key or MFA authentication.
The simple way to describe the issue is that OpenSSH's public key authentication is done completely separately from PAM (on Linux systems), and OpenSSH has no way to selectively ask PAM to do various things. Roughly speaking, all interaction with PAM is a black box to the OpenSSH server that either passes or fails as the "keyboard-interactive" or "password" authentication method.
There are broadly two ways of doing MFA authentication with OpenSSH; you can do it as people log in to your server (although this gets annoying), or you can do it before hand in some way. The usual approach for the latter is to have an OpenSSH certificate authority that issues short term certificates only if you authenticate to it properly (through, for example, a web front end). Unfortunately the certificate approach is generally much more difficult to deploy, because you need a bunch of moving parts to exist on all of the clients. If you want simple deployment, you need to do all of your MFA at login time. OpenSSH itself has no built in support for MFA, so if you take the 'at login time' path you must put your MFA authentication into your PAM stack.
OpenSSH allows you to require multiple authentication methods but, as mentioned, your entire PAM stack is one authentication method. Since your MFA goes in your PAM stack, it's intrinsically coupled to whatever else the PAM stack does (which almost certainly includes asking for the Unix password). Then since SSH public key authentication isn't exposed through PAM, you can't use PAM's own (rather complicated) conditional features to require public key authentication only in some situations, or to skip only parts of the PAM stack if the user has public key authentication.
Another consequence of your MFA authentication being bolted to the rest
of your PAM authentication is that it's relatively difficult to allow
people using passwords to skip MFA under some circumstances (for example
if they're logging in from your highly secure emergency access server).
If MFA was a separate access method, you could configure this through
Match blocks in your
sshd_config. As it is, perhaps there's some
way to do this reliably through PAM, but it's going to be harder and
less obvious to configure.
In theory all of this could be dealt with if OpenSSH supported an
additional authentication method, or really class of them, that I
will call "
pam:<service>". This would do a keyboard interactive
PAM authentication using the given service name. Then you could put
your MFA PAM configuration into a separate
service and set your SSH server to require, say, 'publickey,password'
or 'password,pam:mfa' (and just 'password' from your emergency
access server, or perhaps 'hostbased,password' for extra security).