Securing your server with 2FA
2021-10-20
I have a bunch of servers running within the company network. These server running multiple
virtual machines such that these servers can be seen as a hypervisor. I connect to them
using ssh
and for additional security I use a second factor. 2FA or two-factor authentification
can be used to improve the security by forcing the user not only provide the correct ssh key but
also another secret shared by the machine and the user. This corrects the case that a
ssh key of a users gets compromised. On the backend I use the PAM module Google Authenticator
which generates tokens via the TOTP protocoll. This is also called OATH-TOTP which stands for
Open Authentication - Time-Based One-Time Password. Initially the server and the user
exchanges a shared salt which should be unknown to all others. Afterwards, the user can generate
a 6 digit token based on that salt and the current time. The servers has the same informations
and generates the same token for validation.
Installation
First we install an app which supports TOTP on another device (maybe your smartphone). I use FreeOTP which I installed from the F-Droid store. The interface is fairly simple and should be self-explaining. We use QR codes for the initial exchange but one can enter all informations by hand.
On the server-side we install the PAM module with:
|
|
Configuration
After the question time the PAM module is initialised and preconfigured but not active.
Now, we enable 2FA for ssh
by changing the file mg /etc/pam.d/sshd
and adding following the line on the top.
|
|
auth required pam_google_authenticator.so
triggers that these line must be matched to grant access.nullok
means that logins without 2FA are accepted. This can be changed if all users have 2FA enabled.[authtok_prompt=2F-Token: ]
is the prompt used to question the user for 2FA.
Now we make ssh
aware of our 2FA setup by changing the following lines in the configuration (mg /etc/ssh/sshd_config
):
|
|
Reload your ssh
daemon with systemctl reload sshd
. Now you need to use 2FA for your next login.
If you want that new users can setup 2FA on the first login you can use a script which generates
the ~/.google_authenticator
file.
|
|
For automatic creation of 2FA for new users you need the following line in the pam.d/sshd
at the end of the file.
auth required pam_permit.so
This piece of code and the nullok
allow users to bypass the 2FA forever since you can login without the setup.
So, encourage your users to use 2FA and change booth lines later to only allow 2FA. Otherwise, you can
use authorized users or groups lists within PAM to get a more secure setup.
Be aware, that you should backup your 2FA secrets in case you lost your phone or it gets damaged!
Backup TOPT tokens
To backup my tokens I use emacs and followed this guide. It uses a big table to represent all the fields needed to generate the tokens and QR codes.
The table:
|
|
The explaination:
- Issuer: Name of the service or machine
- Label: The account identifier
- Secret: The base32 encoded shared secret
- URI: The configuration content of the QR code. This is created by the
TBLFM
You can either fill the informations into the table from the .google_authenticator
file and
your own knowledge or use a script which fetches the informations from FreeOTP.
Afterwards, put your curser somewhere on the table and run the table function with C-c C-c
.
To generate a nice QR code use python and the tool qrencode
:
|
|
Running this with C-c C-c
generates a result block with the QR code in it. Now, you can simply
scan the code again. If babel complains about python, make sure that python
is within the org-babel-load-languages
list.
The original author provided the following piece of python to fetch the secrets directly from the FreeOTP app.
The secret and the additional informations shall be copied into the table.
I didn’t tried it but would mention it. You need developer mode active on your phone and maybe the cmd
path needs
to be adjusted.
|
|
Thanks for your attention and leave me a comment.