Use 2FA (Two-Factor Authentication) with SSH

Traducciones al Español
Estamos traduciendo nuestros guías y tutoriales al Español. Es posible que usted esté viendo una traducción generada automáticamente. Estamos trabajando con traductores profesionales para verificar las traducciones de nuestro sitio web. Este proyecto es un trabajo en curso.
Create a Linode account to try this guide with a $ credit.
This credit will be applied to any valid services used during your first  days.

In this guide, you’ll learn how to use one-time passwords for two-factor authentication with SSH. No matter what kind of data you’re hosting, securing access to your Linode is a critical step in preventing your information from being compromised. By default, you will need a password to log in, and you may also configure an authentication key-pair for even greater security. However, another option exists to complement these methods: time-based one-time passwords (TOTPs).

TOTPs allow you to enable two-factor authentication for SSH with single-use passwords that change every 30 seconds. By combining this method with a regular password or publickey (or both), you can add an extra layer of security, further ensuring your server is sufficiently protected.

This guide explains how to install the necessary software, configure your system to use two-factor authentication (2FA), and use your new time-based one-time password (TOTP) in combination with existing security features.

Before You Begin

  1. Familiarize yourself with our Getting Started guide and complete the steps for setting your Linode’s hostname, updating your system’s hosts file, and setting the timezone.

  2. Review the Securing Your Server guide to update your system and create a limited user. This guide will explain a different way to harden SSH access, but you can also use public key authentication in addition for even greater protection. That method will be covered in the optional section Combine Two-Factor and Public Key Authentication.

    If you plan on combining two-factor and public key authentication, ensure you upload your computer’s public key to your Linode’s standard user account before beginning the steps in this guide.
  3. You will need a smartphone or another client device with an authenticator application such as Google Authenticator or Authy. Many other options exist, and this guide should be compatible with nearly all of them.

This guide is written for a non-root user. Commands that require elevated privileges are prefixed with sudo. If you’re not familiar with the sudo command, you can check our Users and Groups guide.

Install Google Authenticator

In this section, you will install the Google Authenticator package to set up two-factor authentication. This software will generate keys on your Linode, which will then be paired with an app on a client device (often a smartphone) to generate single-use passwords that expire after a set period of time.

  • CentOS 7:

    yum install epel-release
    yum install google-authenticator qrencode
  • Debian and Ubuntu:

    sudo apt install libpam-google-authenticator

Although this guide uses the Google Authenticator package, the keys it generates are compatible with any authentication app (including Google Authenticator, Microsoft Authenticator, Authy, and more).

Generate a Key

Now that the packages have been installed, you’ll use them to generate keys. Software on client devices use these keys to generate TOTPs. To understand the difference between these passwords and the ones you already use, let’s break down the TOTP concept:

  • Time-based - The generated password will change every 30-60 seconds. This means that if an attacker tries to use brute force, they’ll almost certainly run out of time before new credentials are needed to gain access.
  • One-time - The password will be valid for a single authentication only, thus minimizing the risk of a replay attack. Even if your TOTP is intercepted upon sending it to the server, it will no longer be valid after you’ve logged in.

The following instructions will allow you to specify a user for whom you’d like to generate a password. If you are configuring two-factor authentication for multiple users, follow these steps for each user.

Be sure to have your phone or mobile device ready, since this is where you’ll add the password to your authenticator app. If you haven’t downloaded an authenticator app, do so before proceeding.
  1. Run the google-authenticator program. A prompt will appear asking you to specify whether you’d like to use time-based authentication (as opposed to one-time or counter-based). Choose “yes” by entering y at the prompt.

  2. You should see a QR code in your terminal:

    Using the authenticator app on your phone or mobile device, scan the code. A new entry should be added to your authenticator app in the format username@hostname.

    You’ll also see a “secret key” below the QR code. You can also enter this secret key into the app manually, instead of scanning the QR code, to add your account.

  3. Record your emergency scratch codes in a secure location. These codes can be used for authentication if you lose your device, but be aware that each code is only valid once.

  4. You’ll be prompted to answer the following questions:

    Do you want me to update your "/home/exampleuser/.google_authenticator" file (y/n)

    This specifies whether the authentication settings will be set for this user. Answer y to create the file that stores these settings.

    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)

    This makes your token a true one-time password, preventing the same password from being used twice. For example, if you set this to “no,” and your password was intercepted while you logged in, someone may be able to gain entry to your server by entering it before the time expires. We strongly recommend answering 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)

    This setting accounts for time syncing issues across devices. Unless you have reason to believe that your phone or device may not sync properly, answer n.

    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)

    This setting prevents attackers from using brute force to guess your token. Although the time limit should be enough to prevent most attacks, this will ensure that an attacker only has three chances per 30 seconds to guess your password. We recommend answering y.

  5. Before you log out, review the next section carefully to avoid getting locked out of your Linode.

You have finished generating your key and adding it to your client, but some additional configuration is needed before these settings will go into effect. Carefully read the following section in this guide for instructions on how to require two-factor authentication for all SSH login attempts.

Configure Authentication Settings

The TOTP authentication methods in this guide use PAM, or Pluggable Authentication Modules. PAM integrates low-level authentication mechanisms into modules that can be configured for different applications and services. Because you’re using additional software (i.e., programs that aren’t built into the Linux distro), you’ll need to configure PAM to properly authenticate users.

  • It is strongly recommended that you have another terminal session open while configuring your authentication settings. This way, if you disconnect to test authentication and something is not properly configured, you won’t be locked out of your Linode. You can also use Lish to regain access.

  • If you or a user on your system use this method, be sure that the SSH key and authenticator app are on different devices. This way, if one device is lost or compromised, your credentials will still be separate and the security of two-factor authentication will remain intact.

  1. Edit the system’s PAM configuration file for SSH.

    sudoedit /etc/pam.d/sshd
  2. Add the following lines to the end of the file:

    File: /etc/pam.d/sshd
    auth    required     no_warn try_first_pass
    auth    required

    The first line tells PAM to authenticate with a normal Unix user password before other methods. The second line specifies an additional method of authentication, which in this case is the TOTP software we installed earlier.

  3. Edit the system’s SSH configuration file.

    sudoedit /etc/ssh/sshd_config
  4. The parameter KbdInteractiveAuthentication should be set to yes (which is the default). The deprecated alias of this parameter is ChallengeResponseAuthentication, so edit that line instead if it is present in your file.

    At the end of the file, add lines to enable the keyboard-interactive method with your user. Replace example-user in the example configuration below with any system user for which you’d like to enable two-factor authentication.

    File: /etc/ssh/sshd_config
    KbdInteractiveAuthentication yes
    Match User example-user
        AuthenticationMethods keyboard-interactive

    If you created TOTPs for multiple users, and you’d like to have them all use two-factor authentication, create additional Match User blocks for each user, duplicating the command format shown above.

    If you want to enforce two-factor authentication globally, you can use the AuthenticationMethods directive by itself, outside of a Match User block. However, this should not be done until two-factor credentials have been provided to all users.
  5. Restart the SSH daemon to apply these changes:

    sudo systemctl restart sshd

    Two-factor authentication is now enabled. When you connect to your Linode via SSH, the authentication process will proceed as shown in the diagram.

  6. Open a new terminal session and test your configuration by connecting to your Linode via SSH. You will be prompted to enter in your standard user account’s password and then, you will be prompted to enter in a Verification Code. Open your authorization app, select the account you created in the Generate a Key section and enter in the password that is displayed. You should authenticate successfully and gain access to your Linode.

If your SSH client disconnects before you can enter your two-factor token, check if PAM is enabled for SSH. You can do this by editing /etc/ssh/sshd_config: look for UsePAM and set it to yes. Don’t forget to restart the SSH daemon.

Combine Two-Factor and Public Key Authentication (Optional)

This section is optional. If you’d like to use public key authentication instead of a password authentication with TOTP, follow the steps in this section.


Before completing this section, ensure that your computer’s public key has been uploaded to your Linode. Public keys are normally stored in your home directory’s authorized_keys file.

cat ~/.ssh/authorized_keys
  1. Set PasswordAuthentication to no and modify the AuthenticationMethods line in /etc/ssh/sshd_config to include publickey:

    File: /etc/ssh/sshd_config
    PasswordAuthentication no
    Match User example-user
        AuthenticationMethods publickey,keyboard-interactive

    Configure this setting in the AuthenticationMethods directive for each user as appropriate. When any of these users log in, they will need to provide their SSH key and they will be authenticated via TOTP, as well.

  2. Restart your SSH daemon to apply these changes.

    sudo systemctl restart sshd
  3. Next, you’ll need to make changes to your PAM configuration. Comment out or omit the following lines in your /etc/pam.d/sshd file:

    File: /etc/pam.d/sshd
    # auth       substack     password-auth
    # auth    required     no_warn try_first_pass

    You should now be able to log in using your SSH key as the first method of authentication and your verification code as the second. To test your configuration, log out and try to log in again via SSH. You should be asked for your 6-digit verification code only, since the key authentication will not produce a prompt.

Next Steps

First, be sure you have followed our guide to Securing Your Server. Although there is no single, foolproof method to protect your data, firewalls and services like Fail2Ban are a great means to minimize risk.

When you use two-factor authentication with TOTPs, an important point to consider is the physical security of the device on which you’ve configured your authenticator app. Be sure your phone or device is secured with a passphrase, so that even if it falls into the wrong hands, it can’t easily be used to compromise your server. If you lose the phone or device that stores your credentials, you can use Lish to access your Linode and disable two-factor authentication. If this happens, you should switch to a different, hardened method of SSH access, such as public key authentication, in the interim.

While two-factor authentication may be a valuable security feature, total security is an ongoing process not an end goal that can be achieved by adding extra layers of authentication. To provide the best protection for your data, take care to follow security best practices at all times.

More Information

You may wish to consult the following resources for additional information on this topic. While these are provided in the hope that they will be useful, please note that we cannot vouch for the accuracy or timeliness of externally hosted materials.

This page was originally published on

Your Feedback Is Important

Let us know if this guide was helpful to you.

Join the conversation.
Read other comments or post your own below. Comments must be respectful, constructive, and relevant to the topic of the guide. Do not post external links or advertisements. Before posting, consider if your comment would be better addressed by contacting our Support team or asking on our Community Site.
The Disqus commenting system for Linode Docs requires the acceptance of Functional Cookies, which allow us to analyze site usage so we can measure and improve performance. To view and create comments for this article, please update your Cookie Preferences on this website and refresh this web page. Please note: You must have JavaScript enabled in your browser.