Two-factor SSH using oathtool on Ubuntu 18.04
July 16, 2018I've been using the Google Authenticator PAM Module for years. It works great, and is easy to set up. But, I generally try to stay away from all things Google, so I wanted to set up two-factor ssh using something else.
After a bit of googling (…), I found OATH Toolkit. Reading their documentation, it seems rather easy to set up. Also, this blog has a nice TL;DR of the setup. I've pretty much followed that, and added a few bits.
Setting up oathtool
# Install oathtool.
sudo apt install oathtool libpam-oath
export HEX_SECRET=$(head -15 /dev/urandom | sha1sum | cut -b 1-30)
oathtool --verbose --totp $HEX_SECRET --digits=8
# Type in the Base32-secret on your phone
sudo touch /etc/users.oath
sudo chmod 0600 /etc/users.oath
# Running subshell so we can send output to file with sudo-permissions
sudo /bin/bash -c "echo HOTP/T30 $USER - $HEX_SECRET \ >> /etc/users.oath"
# Unset your secret
unset HEX_SECRET
Setting up an access-list for two-factor
Now, I want to be able to define who I require two-factor for, and from where I require it. I have a couple of hosts that I trust, where I can log in from in case I lose my two-factor.
Create /etc/security/login_token.conf
. My file has the following contents:
# Do not require two-factor from here:
+ : dennis : 1.1.1.0/24
# lolnope don't need two-factor at all
+ : lolnope : ALL
# Demand two-factor from everywhere and everyone else
- : ALL : ALL
See man 5 access.conf
for details on the format
(link).
Setting up libpam-oath
Add the following to the top of /etc/pam.d/sshd:
# Exceptions from two-factor
auth [success=1 default=ignore] pam_access.so accessfile=/etc/security/login_token.conf
# Two-factor
auth required pam_oath.so usersfile=/etc/users.oath
SSH
Now all we need to do is to enable two-facor in sshd_config
. Set
ChallengeResponseAuthentication
to yes
in /etc/ssh/sshd_config
. Now we can
restart ssh
, and test it!
Testing
This is what it should look like when logging in:
$ # I use ssh-keys, do I need to auth without them
$ ssh -o PubkeyAuthentication=no dennis@host
One-time password (OATH) for `dennis':
Password:
And, when logging in from one of the hosts I've defined in
/etc/security/login_token.conf
, I'm not asked about the OTP!