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.
On ubuntu, you'll need to install the
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 https://github.com/google/google-authenticator/git google-authenticator cd google-authenticator/libpam make && sudo make install
Add the following at the top of your
auth required pam_google_authenticator.so
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 pam_google_authenticator.so # Two-Factor Auth auth required pam_env.so #  # In Debian 4.0 (etch), locale-related environment variables were moved to # /etc/default/locale, so read that as well. auth required pam_env.so envfile=/etc/default/locale # Standard Un*x authentication. @include common-auth # Disallow non-root logins when /etc/nologin exists. account required pam_nologin.so # 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 pam_access.so # 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 pam_motd.so #  # Print the status of the user's mailbox upon successful login. session optional pam_mail.so standard noenv #  # Set up user limits from /etc/security/limits.conf. session required pam_limits.so # Set up SELinux capabilities (need modified pam) # session required pam_selinux.so multiple # Standard Un*x password updating. @include common-password
Make sure you have
ChallengeReponseAuthentication set to
yes in your
# /etc/ssh/sshd_config ChallengeResponseAuthentication yes
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 https://www.google.com/chart?chs=200x200&chld=M|0&cht=qr&chl=otpauth://email@example.com%3Fsecret%3DAAAA Your new secret key is: AAAAAAAAAAAAAAAA Your verification code is 123123 Your emergency scratch codes are: XXXXXX XXXXXX XXXXXX XXXXXX Do you want me to update your "~/.google_authenticator" file (y/n) # ...
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.
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 firstname.lastname@example.org PAM Verification Code: |
Enter the code shown on your phone's screen. Note that codes are only good for a short period of time.
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.