I think I already wrote a post about this, but this post is about how to use a proper two factor method, not just a shell script.


While I recommend you check out the full tutorial from the sources link at the bottom of this post, here’s the summary:

sudo apt install libpam-google-authenticator

and answer the questions. Next, edit a file with

sudo nano /etc/ssh/sshd_config

and change/add

ChallengeResponseAuthentication yes
UsePAM yes
AuthenticationMethods publickey,password publickey,keyboard-interactive

edit another file

sudo nano /etc/pam.d/sshd

and comment out

@include common-auth

and at the bottom, add:

auth required pam_google_authenticator.so nullok

and restart SSH with:

sudo service ssh restart

Allowing password authentication

Now, you have two factor with public keys, but what about passwords? Well, you just disabled passwords from disabling the pam module for that, so here’s my workaround:

Add a user called backup:

sudo adduser backup --disabled-password

Now, add the following to the bottom of /etc/ssh/sshd_config:

Match User backup
    AuthenticationMethods publickey keyboard-interactive
    ForceCommand sudo login

Run sudo visudo, and at the bottom, add the line:

backup ALL=(ALL:ALL) NOPASSWD:/bin/login

Now, copy your .google_authenticator file to /home/backup. Now, when you want to log in with a password, simply ssh into the backup user, and you’ll get the system login prompt. Here, enter the username and password of your normal user, and you’re in! This still uses two-factor, and will in fact ask for your TOTP key before allowing you to login with your username and password.

Whitelisting IPs

To the bottom of /etc/pam.d/sshd right before the

auth required pam_google_authenticator.so nullok

line, add

auth [success=done default=ignore] pam_access.so accessfile=/etc/security/access-local.conf

Now, in /etc/security/access-local.conf, add/edit:

#localhost doesn't need two step verification
+ : ALL : IP here
#All other hosts need two step verification
- : ALL : ALL

This part is from the stack exchange link at the bottom of the post

Sources: DigitalOcean Unix Stack Exchange