TOTP Secured SSH
Security should be the number one priority of any organization. As the prevalence of ransom-ware and corporate hacks increase, added scrutiny needs to be placed on the systems we use every day.
With any organization, public facing services and endpoints are the most vulnerable. On many Linux systems, the the first service to be publicly available is normally SSH. As the network grows and access matures, this may be placed behind a VPN, however there are many times when SSH is left open on the public internet. Ease of access generally trumps any security implications.
Best practices for public facing SSH include
- Disallowing root login
- Removal of password based auth
- Key based auth only
- Moving to non-standard port (security through obscurity is not real security however it helps decrease log noise)
These basic housekeeping tasks on any new system can help ensure your access from anywhere while mitigating most security concerns.
What if you want added security on top of keys? What if you have many far flung users and key distribution is a problem? Another option that has seen wide spread use in organizations is Time based One Time Password (TOTP) as a means of two factor auth.
TOTP Basics
Time based One Time Password (TOTP) is a simple function that takes the current Unix time as well as a secret key and generates a six digit code (can be more). If this same function is fed the same inputs (time and key), you could expect the same output no matter where the function was ran. Using this as method of second factor authentication is as simple as sharing a key between the user and service they are authenticating to. Each six digit code generated by the TOTP function is calculated on a 30 second window. As long as the user inputs this code within the 30 seconds, the server will have a matching code and allow authentication. This assumes both client and server have their time synced to a source accurate within 30 seconds of each other.
TOTP Auth Steps
- User establishes a secret (normally generated from known random source)
- Secret is shared between user and service they are authenticating to (normally over a TLS channel for web apps)
- User wishing to authenticate generates six digit code using their key and current time (Many apps do this function)
- User shares the six digit code with the service
- The service runs its own TOTP function and compares its six digit output with what was received from the client.
- If codes match, authentication is complete
Server Setup
I am going to configure TOTP on CentOS7 however the principals outlined in this article can be used with minor modification on other linux distributions. TOTP is a IETF standard and there are many implementations. For this example, we are going to use a library provided by Google which has a PAM module and a nice client for creating keys.
Install Software and Set Time
yum install ntp epel-release
yum install google-authenticator
ntpdate time.google.com
systemctl enable --now ntpd
Configure SSHD
Edit the SSHD config file /etc/ssh/sshd_config
to ensure the following directives are correctly set
PasswordAuthentication yes
ChallengeResponseAuthentication yes
UsePAM yes
Configure PAM
We need to add our Google Auth PAM module to the SSHD PAM config file located at /etc/pam.d/sshd
auth requisite /usr/lib64/security/pam_google_authenticator.so
Generate Key
On the server, log in as the user you are looking to setup access for and run the following command
google-authenticator
This will step you through some questions about various configurable options. Make sure to select Yes on the first question about wanting time-based.
You should be presented with a QR code, your secret key, and some backup codes.
Client Setup
Just like the server side, there are many TOTP clients out there, desktop, mobile, even hardware based cards. A nice feature of TOTP is that with the correct secret key, you can configure multiple clients and be able to access your second factor no matter where you are.
For this example we are going to use the Google Authenticator mobile app. I find that having all of my TOTP codes on my phone very handy. The app is available for both Android and iPhone.
Once installed from the app store, you can add your secret key using the + sign at the bottom right corner of the app. If you give the app camera access, you can just scan the bar-code displayed during server config. If not, you can manually input the secret key. Once all setup, Google Authenticator should show you the current code as well as a countdown until that code is invalid and the next is generated.
That is it!
Now, when accessing your server over SSH, you will be prompted for a TOTP code as well as your normal username and password!
Other Fun
HOTP
TOTP is nothing but a cousin of HMAC-based One-Time Password (HOTP). In fact, if you are to look at the RFC for TOTP, it basically says, “see HOTP RFC and include all of that stuff”. HOTP is the same a TOTP except a counter is used instead of time in code generation. This means that each generated code is valid until you use it, afterwords, the counter is incremented by one.
This obviously provides less security than TOTP however is a perfectly useful method of second factor. The Google Auth PAM plugin and key generation utility described above can also be used for HOTP based second factor. One cool thing with HOTP, you can program a hardware dongle like a yubikey to input your code on touch! Yubikeys can be used for TOTP as well but don’t have an internal clock so need a helper program to provide an accurate time.
TOTP with Key Based Auth
Want to go that extra step? Paranoid beyond belief? Holding all your cryptocoin on a server with public SSH? You can enable key based auth on top of TOTP!
Normally, using key based authentication overrides “keyboard-authentication” methods such as password and TOTP. To have both you need to set a further directive in your /etc/ssh/sshd_config
file and restart the service
AuthenticationMethods publickey,keyboard-interactive