Adding 2FA to your Lightsail instance, my way


3 min read

I was having trouble with sshd on a Lightsail Ubuntu 20.04 instance. I wanted to give One Time Password 2FA with more than 6 digits for authentication a whirl.

You need to have an authentication device that can handle more than 6 authentication digits. Currently, Google nor Microsoft TOTP authentication do not support that (yet?), and I haven't really got the time to air-gap this kind of stuff with a real 8-digit authentication key.

Generating the authorized_keys...

It is probably not a good idea to keep a generated RSA key. I kind of get scared when RSA2048 or less is used.

Generate the private/public keypair on the client. Copy the public key to the server while in the SSH prompt.

SSH Client

$ ssh-keygen -t ed25519

A key password would be useful here... this is how I generate my passphrases ๐Ÿช

$ openssl rand -base64 15

Get the public key, the public one will now go on the server...keep the private key or you'll be locked out.

SSH Server

The public key ends with .pub and needs to be in authorized_keys. Disable the Amazon-generated key if you want to, it is a public key.

A TOTP rule

Install oathtool on both the client and the server, and then libpam-oath on the server.

SSH server

Generate some secrets. Keep these safe.

$ export HEX_SECRET=$(openssl rand 15 | sha1sum | cut -b 1-30)
$ oathtool --verbose --totp $HEX_SECRET --digits=8
$ sudo /bin/bash -c "echo HOTP/T30/8 $USER - $HEX_SECRET \ >> /etc/users.oath"

Each line...

  1. Creates a HEX_SECRET. Keep this handy as it's your "Hex Secret" for logging in by OATH Toolkit.
  2. Displays the initial TOTP parameters based on HEX_SECRET.
  3. Logs the parameters in for $USER which is you, but you can replace it with the user account who needs to log in with TOTP

SSH Client

$ oathtool --verbose --totp $HEX_SECRET --digits=8

You can do that on the client side too and it's how I log in. Here's a result, remember to keep your HEX_SECRET...

$ oathtool --verbose --totp $(openssl rand 15 | sha1sum | cut -b 1-30) --digits=8
Hex secret: **scrubbed, copy this!**
Base32 secret: **scrubbed**
Digits: 8
Window size: 0
TOTP mode: SHA1
Step size (seconds): 30
Start time: 1970-01-01 00:00:00 UTC (0)
Current time: **scrubbed**
Counter: **scrubbed**

**scrubbed, use this section for logging in with OATH Toolkit**

Override password based login

SSH Server: Edit /etc/pam.d/sshd as root

Apply these edits to keep PAM from using passwords and relying on Public Keys and TOTPs only.

If you edit this or the next step(s) wrongly you'll be locked out of your VPS and will have to use a backup.


@include common-auth


auth required usersfile=/etc/users.oath
#@include common-auth

SSH Server: Edit /etc/ssh/sshd_config as root

This doesn't arm PAM just yet, apply these edits.

  1. Set ChallengeResponseAuthentication yes
  2. Set UsePAM yes
  3. Set AuthenticationMethods publickey, keyboard-interactive

The Grand Finale

Keep your SSH window logged in, restart the sshd but do not log out of the SSH window.

Log in to your SSH server through another window using an oathtool generated time-based TOTP.

If this doesn't work simply restore the previous backup and try again.

Extra credit: using the PAM 2FA in sudo

I have not figured out this, I will in a bit though, maybe a next blog post!