Modifying low level authentication is a worrisome thing. If you do it wrong the fear is that you can’t log back in to fix it. So unlike some other guides out there I’ll point out the danger points here and some ideas on how to address them.
This is kind of long so a high level overview is this: install client software, install server software, activate server software, generate key, done! But first, let’s get some background here.
Also note that if you use home directory encryption this guide won’t work for you. Read this.
First let’s explain what this is and why you might want it. The general idea behind “second factor authentication“ (2FA) is that you should need something besides a password to authenticate yourself. The original idea was a hardware token. The token would have a special key that would be used to generate a sequence or time based code that would be matched on the server. This way if your password is compromised (keylogger, someone peeking over your shoulder, phishing), they’re still not going to get in because of that second factor. That second factor is also called a “one time password” (OTP) because it’s a password you can only use once.
Google Authenticator (GA) is actually a number of things that implement all parts of two open standards for a 2FA system. Those two standards are described in RFCs 6238 and 4226 and GA consists of some mobile apps that generate OTPs and a “pluggable authentication module” (PAM) that authenticates those OTPs on the server side.
Install Client Software
Note: Authentication doesn’t change here.
That’s what we’re going to install now. First you need the GA mobile app. You can use the Google Authenticator mobile app, but there are a number of other ones. Last I looked there were ones by Amazon, LastPass and a number of others. The GA app supports reading the key via a barcode which is nice for usability as you’ll see.
In addition to the mobile apps you can also install
a Linux box. Install it with
apt-get install oathtool.
Later on you could run this on your server to generate an OTP:
Install Server Software
Note: Authentication doesn’t change here.
On the Linux server side we’ll install the
package (this will be on an Ubuntu 16.04 system, adjust for yours).
It’s important to note that there are alternatives here too.
On Ubuntu/Debian there’s
libpam-oath. It makes some different
design decisions, but implements the same 2FA system. For this though
I’ll stick with
Once installed nothing will change. You can run
sudo apt-get install libpam-google-authenticator in complete safety.
Nothing in the authentication system will change at this point.
So run that and we’ll go about activating it.
A Little More Background
Now, before activating it, one last bit of theory about what we’re doing. GA will protect you from someone stealing your password. But remember, if they have physical access to your machine all bets are off. You can enable it for console and GUI logins if you wish, but for protecting a physical machine you should use full disk encryption (easiest to do at install).
What you really want GA for is for protecting ssh. And specifically you want it for ssh sessions that are authenticated by password. If you authenticate with your ssh key, you don’t need OTP.
Activate Server Software
Note: Authentication is changing. Be careful.
You will not require an OTP yet - you haven’t generated an OTP key
yet! However keep a few terminals connected and sudo’d to
when you do this step and then check logins to confirm you can still
connect. Also you should have ssh public key authentication already
In one of those
root sessions run the following. And note that
restarting the ssh server will not disconnect any ssh sessions.
Now try logging in via ssh via public key in another terminal. This should work just fine. Now try it without public key auth:
Note that it’s not asking you for a one time password. This is
because when we enabled
pam_google_authenticator we set the
nullok option. This enables you to bypass an OTP if you don’t
have an OTP configured. Brilliant!
But let’s do the generate key thing:
Note: Authentication switches over to OTP here. Test!
In addition to installing that PAM GA module, that package also
installed a tool called
google-authenticator to generate your OTP
key. So let’s run that - make sure your mobile GA client is installed
and ready for a new key.
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 28 29
google-authenticator Do you want authentication tokens to be time-based (y/n) y https://www.google.com/chart?chs=200x200&chld=M|0&cht=qr&chl=otpauth://totp/kevin@bo%3Fsecret%3D2MVLIBJG4I6ZVCAN [...deleted ascii barcode...] Your new secret key is: 2MVLIBJG4I6ZVCAN Your verification code is 526265 Your emergency scratch codes are: 69073925 94405654 13765959 67453424 43597161 Do you want me to update your "/home/kevin/.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, tokens are good for 30 seconds and 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. If you experience problems with poor time synchronization, you can increase the window from its default size of 1:30min to about 4min. 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
Note that this is not my OTP. It’s just an example session to explain the questions you’ll get. To explain my answers:
First I picked a time based OTP (TOTP). Sequence based OTP (HOTP) are a bit more secure. You can detect if people have used your OTPs, but you’re really limited to a single device. Which is kind of a hassle.
Once picked you’ll get a barcode and the key - enter one or the other into your GA mobile app. Make sure to record the “emergency scratch codes” somewhere safe.
Once done, save the file. Next up disallow reuse (self-explanatory) and then let OTPs be valid for a wider window. This allows your server and phone to drift a bit time-wise. Not too much though so make sure your clocks are in sync with time servers.
Lastly turn off rate limiting. If you want to rate limit ssh connections, use fail2ban. And you should rate-limit failed ssh connections to stop brute-forcing attacks that just suck up bandwidth.
OTP is now active on your account. Attempt to ssh in without your
public key (
ssh -oPubkeyAuthentication=no YOUR-SERVER) and you
should be prompted for a password and your OTP. If it fails, it’s
likely the clock on your phone and on the server are not in sync.
Make them sync with a time server.
Lastly those emergency scratch codes. I haven’t tried it, but I
suspect you can generate more by appending them to your
~/.google_authenticator file. It follows this paragraph. As you
log in using OTPs it will change - mainly adding times to the
relevant lines. Or you can just rerun
create a new OTP key - don’t forget to update the mobile app.
1 2 3 4 5 6 7 8 9
2MVLIBJG4I6ZVCAN " WINDOW_SIZE 17 " DISALLOW_REUSE " TOTP_AUTH 69073925 94405654 13765959 67453424 43597161
Now would be a good time to review the README for the
project to learn more about the options you have in your
/etc/pam.d/sshd entry for the
auth required pam_google_authenticator.so nullok line.
From simple things like changing the token prompt (
to requiring OTP (removing
nullok) there are a number of things
you can tweak. Just do so carefully.