Quick Guide

Recently I started making use of Oracle Cloud, due to their very generous “Always Free” tier. I’ve been pushing to learn more about Linux at large instead of staying within the Debian or CentOS guardrails.

Currently I have an ARM Ampere instance with Oracle Linux 8 that I use as a remote development box with VSCode. Occasionally it’ll serve a dual purpose of a beta host of software I’m working on.

Since this box holds development code and potentially unsecured software I wanted to ensure I protect it as much as possible. I realized it’s probably time to implement 2FA on SSH. I was hesitant due to VSCode integration concerns along with general maintenance ability with a verification implemented. Thankfully after testing, I found out VSCode natively handles keyboard-interactive type authentications.

Turns out on a traditional CentOS or Debian based system, it’s fairly trivial to setup with numerous guides available. The trick was however, my ARM instances run Oracle Linux 8. Oracle Linux doesn’t have google-authenticator within it’s repos and SELinux wasn’t configured to allow SSH to edit similar files in a user’s directory.

Obtaining the compiled RPM for google-authenticator is easy thankfully, you can access the full epel repo here. The exact package you want will vary depending on your setup. In my instance, I am running Oracle Linux 8 on ARM Ampere which is based off CentOS 8 with an architecture of aarch64, so I navigate to epel/8/Everything/aarch64/Packages/g and copy the link for google-authenticator

A major stump point according to StackExchange is getting SELinux to allow the SSHD process access to /home/username/.google_authenticator. We could go through some heavy SELinux configuration and apply it in the hopes another update doesn’t undo it. The alternative, is to store .google_authenticator file within the .ssh folder of a users profile. SSHD does have permission to that folder and it makes logical sense to store 2FA files alongside SSH files

Thankfully the PAM modules allows us to change the default location of the secret file, so our final PAM configuration line to for 2FA looks like:
auth required pam_google_authenticator.so secret=/home/${USER}/.ssh/.google_authenticator

Finally we need to let the SSHD know what we’re requiring to login, moving forward I’m going to require SSH key AND 2FA on my WAN accessible servers. Internally, I’m not convinced it will provide a benefit worth the extra time given how much I log in and out of my internal boxes.

The SSHD config is fairly straight forward with only changing values and adding 1 new option AuthenticationMethods, with this configuration option you can set multiple authentication schemes or enforce only one. If you wanted to require a password, ssh key, and a 2FA method your line may look like:
AuthenticationMethods password,publickey,keyboard-interactive
If you wanted to allow password and public key OR public key and 2FA it would look like:
AuthenticationMethods password,publickey publickey,keyboard-interactive

Before we restart the SSHD service, we need to generate the actual 2FA configuration for our user. Run google-authenticator as the user you wish to enable 2FA on. Follow through the prompts ending up with it presenting you a QR code in the terminal for you to scan with your Google Authenticator app. Make sure copy your .google_authenticator file to ~/.ssh before restarting the SSHD service

The overall process was quick once I understood the SELinux error, it helps to check systemctl status sshd to see what errors it may be presenting if you have a hard time logging in.

Keep an eye out for a new post of my Ansible Playbook that automates this process for you, to further cut down the cost of entry to better security for you and your services!