The OpenSSH server has limits on what user authentication you can use

October 6, 2021

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 /etc/pam.d/mfa PAM 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).

Written on 06 October 2021.
« Some early notes on using pipx for managing third-party Python programs
What Linux kernel "unknown reason" NMI messages mean »

Page tools: View Source, Add Comment.
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Wed Oct 6 22:39:09 2021
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.