How to setup two factor authentication via SSH

In this tutorial I will describe how the security of an SSH access can be upgraded using two factor authentication. When finished, a user that wants to login via SSH to a server needs to provide an access code generated by an app on one of his personal devices additionally to entering the password. This way the SSH login is still safe if someone manages to get to know the password.

This tutorial is related to Debian 11 (Bullseye). In later versions some details could have been changed.

Ensure that the system clock is synchronized

For the time based codes to work, you need to be sure that the clock of your Debian system is synchronized to a time server. To check, run following command on the server:

timedatectl

The output should contain following line:

System clock synchronized: yes
If the stated line indicates „no“, you need to setup the NTP daemon to synchronize the system clock.

Setup Google Authenticator on the server

First install the Google Authenticator PAM module:

apt install libpam-google-authenticator
If your ~/.ssh directory does not yet exist, create it by executing the command „ssh-keygen“. You can leave all prompts empty.

Now create the secret key on the server:

google-authenticator -s ~/.ssh/google_authenticator

The command will ask if it should generate time-based tokens. Press „y“ to accknowled it. After that it will print a QR code and the generated secret key. Import it into your authenticator app on your personal device by either scanning the QR code or by entering the displayed secret key into the app.

You can use any authenticator app. I suggest using Google Authenticator as it allows to easy copying the stored secret keys onto other devices if you want to have a backup device in case that your main device is lost or broken.

After importing the QR code or entering the displayed secret key, your app will now show the generated token. Enter that token into the prompt on your server to verify the connection. The authenticator on the server side should now display „code confirmed“ and ask you some final questions:

  1. It asks if it should update your ~/.ssh/google_authenticator file. Press „y“ to acknowledge.
  2. It asks if it should disallow multiple uses of the same token. Press „y“ to acknowledge.
  3. It asks if it should recognize more tokens as valid. Press „n“ to reject, except you want to allow for up to 4 minutes of time difference between the servers clock and the clock of your personal device
  4. It asks if you want to enable rate limit. Press „y“ to acknowledge.

Now add following line at the end of the file /etc/pam.d/sshd:

auth required pam_google_authenticator.so secret=/home/${USER}/.ssh/google_authenticator

Open /etc/ssh/sshd_config. Locate following key

ChallengeResponseAuthentication yes

and set it to „yes“.

In Debian versions above Bullseye, the key might have a different name: „KbdInteractiveAuthentication“

Restart the SSH daemon:

systemctl restart sshd

Now open a second SSH session and login. You should now be requested for a password and the verification code which is generated by the authenticator app on your personal device. Check that you can login to the server using the new SSH session, your password and the verification code.

You now have setup the two factor authentication successfully