SSH - Multi-Factor Authentication
Intro
Motivation
SSH offers a variety of authentication methods varying from simple password auth to MFA (multi-factor authentication).
Going with SSH-key based authentication (what you have) where the private key is being protected by a passphrase (what you know) in order to store the same encrypted may be reconsidered as much more secure compared to simple password based authentication. But one bigger downside here comes from the fact that there is no passphrase expiration or password policy being forced by the default tooling allowing the user to set a weak passphrase or leave the generated private key unprotected.
In addition to the usage of passphrase protected SSH-keys the device or system where the key is being kept has to be hardened accordingly where MFA may become much more useful if all parts of it can be enforced server side.
Simply put, SSH private keys representing what you have in combination with the protecting passphrase (what you know) should not be considered as MFA mainly because not all parts of it can be enforced server side.
Alternatives
SSH-Key pair with server side password
Combining the SSH-key authentication with a password based authentication allows us to enforce any password policy also including password expiration/renewal server side - This way the what you know part becomes more controllable or physical.
On SSH configuration level this can be achieved by adding the following line to the SSH-Server config (/etc/ssh/sshd_config):
1
2
# Require all users to use public key and local password
AuthenticationMethods publickey,password
Once the change has been applied and the user being allowed to login over SSH has a key accepted by the server the SSH login should look very similar to the following example:
1
2
3
4
➜ ~ ssh localadmin@my-server -i .ssh/id_rsa
Authenticated with partial success.
localadmin@my-server's password:
my-server:~ localadmin$
In some cases it may be required to allow different auth method depending on the user. For instance if we have a technical user being forced by the used milage to login over SSH-key only:
1
2
3
4
5
6
7
# Require all users to use SSH key and SSH user password
AuthenticationMethods publickey,password
# Tech user can only login over public key
Match User inventory
AuthenticationMethods publickey
Match all
Hint: If you are using Ansible and want to automate SSH configuration, then my SSH Hardening Role might be of interest.