Security audits normally require 2 factor authentication for all users that access sensitive services on public facing servers. So although once upon a time it was cool to use single factor authentication such as the ‘publickey’ method for services like SSH, more recently it has become essential to use 2FA for accessing SSH on web servers.
There are 2 common options for implementing 2FA on Linux SSH systems. Time-based One-Time Password (TOTP) is an obvious choice and works very well provided you don’t use scripts or other software to automatically login to your servers. We’ll look into configuring TOTP authentication in a future article.
Publickey and password
The simplest option for protecting SSH using 2FA is to configure SSH to require a public key – “something the user has” – with a server side password – “something the user knows”. Once this is setup correctly your SSH setup should pass all but the strictest of security audits.
How to set up SSH with keys and passwords
Modern versions of SSH – I think 6.2 and later – support a new authentication directive called AuthenticationMethods
This can be enabled on a per-user basis, so to start with, add this to the bottom of the SSH file on your server called /etc/ssh/sshd_config
Match User testuser AuthenticationMethods publickey,keyboard-interactive
Clearly you should change testuser to a valid username that you can use for testing. Its vital that AuthenticationMethods is started on a new line, if you put all the text on one line you might find it impossible to login to SSH with any user. As always, its best to make a full system backup of your server before making changes to important files such as your SSH config.
You’ll also need to check that the two authentication methods are enabled in the SSH config file:
Once you have made the above changes, you can restart SSH using the correct command for your system. I use Ubuntu, so the command for my server is systemctl restart ssh
Once this is done, when my testuser tried to login the server SSH software will first check for the correct public/private key on testuser’s local system, and if it’s present, the SSH server will prompt testuser for their server password. Boom!