Two Factor SSH Authentication

Security, SSH Posted on

With many popular websites providing two factor authentication, why shouldn't you add two-factor authentication to SSH? Public-key, Private-key encryption is generally considered to be very secure, but why not take an extra step?

This tutorial will use the open source Google Authenticator project and PAM for setting up two-factor authentication.

Install Google Authentication on your Machine

On ubuntu, you'll need to install the libpam0g-dev dependency:

sudo apt-get install libpam0g-dev

The package is pam-devel on REHL, and may vary from platform-to-platform.

Clone the project into a temporary location and your server and install:

cd tmp
git clone google-authenticator
cd google-authenticator/libpam
make && sudo make install

Configure SSHD

Add the following at the top of your /etc/pam.d/sshd file:

auth       required

The whole file should look something like this:

# PAM configuration for the Secure Shell service

# Read environment variables from /etc/environment and
# /etc/security/pam_env.conf.
auth       required # Two-Factor Auth
auth       required # [1]
# In Debian 4.0 (etch), locale-related environment variables were moved to
# /etc/default/locale, so read that as well.
auth       required envfile=/etc/default/locale

# Standard Un*x authentication.
@include common-auth

# Disallow non-root logins when /etc/nologin exists.
account    required

# Uncomment and edit /etc/security/access.conf if you need to set complex
# access limits that are hard to express in sshd_config.
# account  required

# Standard Un*x authorization.
@include common-account

# Standard Un*x session setup and teardown.
@include common-session

# Print the message of the day upon successful login.
session    optional # [1]

# Print the status of the user's mailbox upon successful login.
session    optional standard noenv # [1]

# Set up user limits from /etc/security/limits.conf.
session    required

# Set up SELinux capabilities (need modified pam)
# session  required multiple

# Standard Un*x password updating.
@include common-password

Make sure you have ChallengeReponseAuthentication set to yes in your /etc/ssh/sshd_config file:

# /etc/ssh/sshd_config
ChallengeResponseAuthentication yes

Install Google Authenticator for you smartphone

Download Google Authenticator on your iPhone/Android/Blackberry device.

Setup your Account with 2-Factor Authentication

The command we ran earlier added the google-authenticator executable to our $PATH. As the user desiring two factor authentication, run:


This will generate a secret key, add a file to your home directory in ~/.google_authenticator, ask you some preference questions, and output a bunch of stuff. They are very self explanatory, so we won't cover them here.

$ google-authenticator|0&cht=qr&chl=otpauth://totp/

Your new secret key is: AAAAAAAAAAAAAAAA
Your verification code is 123123
Your emergency scratch codes are:

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

# ...

Configure Google Authenticator

Visit the URL to printed out in the above command in your browser. It will be a barcode that you can scan with Google Authenticator. It will prompt your for your secret key.

Test it Out

Restart SSH

sudo service sshd restart

And try logging in from another terminal session. Leave this session open in case things are broken.

You should see something like this:

$ ssh
PAM Verification Code: |

Enter the code shown on your phone's screen. Note that codes are only good for a short period of time.

About Seth

Seth Vargo is an engineer at Google. Previously he worked at HashiCorp, Chef Software, CustomInk, and some Pittsburgh-based startups. He is the author of Learning Chef and is passionate about reducing inequality in technology. When he is not writing, working on open source, teaching, or speaking at conferences, Seth advises non-profits.