PAM(Pluggable Authentication Modules) has been on my mind lately. I've been trying to make heads and tails of it all since last week. I decided to try out a 3rd party module to get some context. So I tried plugging in the Google Authenticator module to see what it did.
PAM or Pluggable Authentication Modules are a modular way of securing parts of a Linux system. It was created by Oracle for the Solaris Operating System but now has become a staple for Linux. The sheer extensibility of the PAM system means that you can log in/authenticate with any valid mechanism. Provided there exists a module that can support it. To quote this excellent article: "should someone invent a device that can read your brain waves and determine ill intent, all we need is a PAM module that can use that device". Now that is cool.
The first step is to install google-authenticator. Which you can do from your distro's repositories. I have Fedora so I did:
$ sudo dnf install google-authenticator
Now install the Google Authenticator for Android or FreeOTP for iOS. This application will be used to generate verification codes.
Next we have to set up google-authenticator. To do this run
google-authenticator on a terminal. You will be guided through the entire setup. After you have finished configuring it, you will be provided a QR code which you can scan with the Google Authenticator on Android or FreeOTP on iOS. It will also give you a code that you can enter on the app if you cannot scan the QR code right now. There will also be some emergency codes that you should store very carefully. These will come in handy when you have lost your phone or uninstalled the app.
Next we have to edit the PAM configuration file for the SSH Daemon. Since we installed a third party PAM module, we have to list it in it's PAM configuration for sshd to use it.
For Fedora, this configuration file was in /etc/pam.d, open the sshd file for editing, and comment out the line:
auth substack password-auth
and add the following line at the bottom:
auth sufficient pam_google_authenticator.so secret=~/.ssh/.google_authenticator
The last line does two things. First it says to use the module
pam_google_authenticator.so for authentication. Second, make it so that completing this alone will be enough to auth someone through PAM. The extra argument should be ignored if you are not using Fedora. What this does is tell the module to store it's files at a non-standard location. This is done to appease SELinux. If not done, SELinux denies access to these files during authentication. This results in failed authentication regardless of whether the verification code is valid. If you don't know what SELinux is, google it. It's awesome.
Now, if you did supply the extra arguments then move the .google_authenticator directory from your home directory to the .ssh directory. Then, restore the SELinux context of the files using
restorecon -Rv ~/.ssh/. This step ensures that PAM module has access to the it's configuration files.
After that, we edit the /etc/ssh/sshd_config file to tell sshd to use PAM. What we need to do is change the following lines:
PasswordAuthentication no # disable password based auth (optional) ChallengeResponseAuthentication yes # enable pam based auth # Add the following line at the bottom AuthenticationMethods keyboard-interactive
The last line specifies the authentication methods that a user must complete to be granted access. This setup only requires keyboard-interactive(which just means PAM based auth) to be completed. Realistically, you would use SSH keys in conjunction with this setup for added security. To use SSH keys with it, change the last line to:
Now, restart the sshd service:
sudo systemctl restart sshd.service. Try and SSH into your new setup!