Posts Enable 2FA on SSH Login with TOTP verification using Google Authenticator
Post
Cancel

Enable 2FA on SSH Login with TOTP verification using Google Authenticator

Purpose of this document is to enable two-factor authentication (2FA) on SSH login using Time-based One-Time Password (TOTP) verification with Google Authenticator.

Why do we need 2FA?

To enhance security by requiring an additional layer of authentication beyond just a password. This helps prevent unauthorized access even if a password is compromised.

Note: Here we will use ssh key based authentication with TOTP verification.

How to enable 2FA?

1. Install PAM Google Authenticator.

1
2
sudo apt update
sudo apt-get install libpam-google-authenticator

2. Generate a secret key using Google Authenticator.

  • Make sure you have any TOTP authenticator app installed on your mobile device.
  • Generate TOTP secret key
1
google-authenticator
  • For your reference I am giving this steps-
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Do you want authentication tokens to be time-based (y/n) y

<IT WILL SHOW QR CODE>
<SCAN TO AUTHENTICATOR APP>
<TYPE VERIFICATION CODE>

Do you want me to update your "/home/<USER_NAME>/.google_authenticator" file? (y/n) y

Do you want to disallow multiple uses of the same authentication
token? This restricts you to one login about every 30s, but it increases
your chances to notice or even prevent man-in-the-middle attacks (y/n) y

By default, a new token is generated every 30 seconds by the mobile app.
In order to compensate for possible time-skew between the client and the server,
we allow an extra token before and after the current time. This allows for a
time skew of up to 30 seconds between authentication server and client. If you
experience problems with poor time synchronization, you can increase the window
from its default size of 3 permitted codes (one previous code, the current
code, the next code) to 17 permitted codes (the 8 previous codes, the current
code, and the 8 next codes). This will permit for a time skew of up to 4 minutes
between client and server.
Do you want to do so? (y/n) y

If the computer that you are logging into isn't hardened against brute-force
login attempts, you can enable rate-limiting for the authentication module.
By default, this limits attackers to no more than 3 login attempts every 30s.
Do you want to enable rate-limiting? (y/n) n

3. Configure SSH to use TOTP verification.

  • Edit /etc/pam.d/sshd and add the following line before @include common-auth:
1
2
3
auth required pam_google_authenticator.so
# If you don't want to use password authentication then
# add comment before: @include common-auth
  • Edit /etc/ssh/sshd_config and add the following line at the end:
1
2
3
4
5
6
7
# If these already exist, then modify them accordingly
KbdInteractiveAuthentication yes
PasswordAuthentication no

UsePAM yes
ChallengeResponseAuthentication yes
AuthenticationMethods publickey,keyboard-interactive
  • Restart the SSH service:
1
sudo systemctl restart ssh
  • Don’t forget to backup the secret key generated by Google Authenticator.
  • Don’t logout until you have tested the setup.

4. Test the setup by logging in to your SSH server.

  • Open another terminal window and try to login using your SSH key.
  • Enter the TOTP code generated by Google Authenticator.
  • Congrats! You have successfully setup 2FA with SSH.

Bonus Tips

If you only want to use TOTP verification for spacific IP Address (Public IP) and keep the private subnet ip as public key authentication only then you need to do following changes.

  • No changes required for /etc/pam.d/sshd, keep the same as previous we did. Make sure this line is present:
1
auth required pam_google_authenticator.so
  • Edit /etc/ssh/sshd_config and modify these changes:
1
2
3
4
5
6
7
KbdInteractiveAuthentication no
PasswordAuthentication no

UsePAM yes
ChallengeResponseAuthentication no
AuthenticationMethods publickey
PubkeyAuthentication yes
  • Edit /etc/ssh/sshd_config and add the following line at the end:
1
2
3
4
5
# public ip is the server public ip address not the client public ip address
Match LocalAddress <your-public-ip>
    ChallengeResponseAuthentication yes
    AuthenticationMethods publickey,keyboard-interactive
    KbdInteractiveAuthentication yes
  • Restart the SSH service:
1
sudo systemctl restart ssh
  • Don’t logout until you have tested the setup.
  • You can now login to your SSH server using your SSH key and TOTP code.