Monthly Archives: November 2017

Add Google Authenticator Style 2FA (Two Factor Auth) to FreeBSD SSH

In the current climate we are all concerned with security, so this article will show you how to enforce Google Authenticator style (there are many other apps other than Google’s!) two-factor authentication on FreeBSD servers SSH.

If implemented, this will require that all SSH connections provide a valid 2FA TOTP code to authenticate.

First, we need to install a package which includes the libraries and tools for the authentication:

pkg install oath-toolkit

You could also install this from ports if you prefer ports-based installations.

Next we will create a new token for a user (we’ll call the user twofa):

head -10 /dev/urandom | md5 | cut -b 1-30
oathtool –totp -v <hex code from above cmd>

in the example above, my random hex code was d1ac1a3d57deeefd6b83c3c340feea.

In the output from the oathtool command, the following line shows the code you need to add to your Google Authenticator style app… for me it was:

Base32 secret: 2GWBUPKX33XP224DYPBUB7XK

You can ignore the rest of the output.  If you wanted to use a QR code to scan in your app, this is the text you need to put in your QR generator:

otpauth://totp/<user>@<host>?secret=<base32 secret>

The “<user>@<host>” part of the text is the descriptive name shown in the app and doesn’t need to be in that format, it’s just a useful reminder!

Next we need to add the reference to map this user to this authenticator code.  Using your favourite editor, edit (or create if it’s the first user) the file: /usr/local/etc/users.oath and add:

HOTP/T30/6 <username> – <hex code>

Note: you use the hex code here, not the base32 secret.  For example:

HOTP/T30/6 twofa – d1ac1a3d57deeefd6b83c3c340feea

The “HOTP/T30/6” tells it that we’re using a TOTP code with 30 second rolling window that generates 6 digit codes (this is what Google Authenticator style apps will return to us)

This file needs to be secure, so make sure you set the permissions correctly:

chmod 0600 /usr/local/etc/users.oath

So now we have the code added to our authenticator app, and the reference added to our config file… all we need to do is tell SSH to enforce it!

Using your favourite editor, edit the file: /etc/pam.d/sshd and comment out the following lines:

#auth sufficient no_warn no_fake_prompts
#auth requisite no_warn allow_local

then add the following line after the last “auth” line:

auth required /usr/local/lib/security/ usersfile=/usr/local/etc/users.oath

This tells PAM authentication for SSHD that we need to require an auth token.

Finally, we have to set a few settings in SSHD so that it can prompt for the code… edit the file /etc/ssh/sshd_config and add the following at the bottom of the file:

ChallengeResponseAuthentication yes
PasswordAuthentication no
UsePAM yes

This enforces the use of PAM which will enforce the use of the 2FA module.  Finally we have to restart the SSH service:

service sshd restart

And if we now try to SSH to the server, we will see the following:

% ssh -l twofa
Password for twofa@totp-test.local:
One-time password (OATH) for `twofa’:
Password for twofa@totp-test.local:
One-time password (OATH) for `twofa’:
Last login: Mon Nov 6 19:57:56 2017 from test.local

I deliberately entered an invalid code the first time, so it re-prompted for a code.  The second time I entered a valid code from the authenticator and you can see that it allowed us access.

This will require 2FA for all SSH access (regardless of whether you have an entry in the users.oath file) – it does not allow selective enforcement per-user.

To add a new user token, simply repeat the instructions for generating a hex code, base32 secret and adding to the users.oath file.  No reload of SSH is needed to add new users.

To change an existing user’s token, do the same as adding a new user except update the existing entry in the file.

There can only be a single entry for each user, so you can’t add multiple tokens for a user.  However, you could add the same token onto multiple authenticator devices.

Every attempt to authenticate will modify the users.oath file.  For example the above modifed the entry in the file to this:

HOTP/T30/6 twofa – d1ac1a3d57deeefd6b83c3c340feea 0 217227 2017-11-06T19:58:12L

The additional parameters are:

  • 0 – The sequence number (this is unused in TOTP, it’s only used for HOTP)
  • 217227 – The last valid 2FA code entered
  • 2017-11-06T19:58:12L – The datestamp of the last valid code entry

Be very careful setting this up for the first time.  I would advise having console access available in case you make a mistake and can’t authenticate!

This should help make your FreeBSD system a little more secure by adding two-factor authentication to SSH logins.

For applications, I recommend the Authy app under Android (and perhaps other mobile devices) as it can be used on multiple devices, and migrated between devices easily too.