Loading...spinner

Short PAM introduction

Most applications which require password input use PAM. I'll stick to the SSH daemon (SSHD) as an example.

When a user logs in, SSH attempts authentication using it's own method, namely, publickeys. Then, if this method fails it talks to PAM. PAM, in turn, must read the configuration in /etc/pam.d/sshd to see how it should process authentication requests from SSHD.

The default Gentoo installation includes the following lines in the PAM SSHD configuration file:

   auth       include        system-remote-login
   account    include        system-remote-login
   password   include        system-remote-login
   session    include        system-remote-login

This is line-oriented file in which each line tells PAM what to do. We're only interested in "auth" part, which in this case instructs PAM to include the additional configuration from the system-remote-login file. This file contains the line:

   auth       include        system-login

And, as you can see, it just tells PAM to include more configuration data from yet another file:

   auth       required       pam_tally.so onerr=succeed
   auth       required       pam_shells.so
   auth       required       pam_nologin.so
   auth       include        system-auth

   (account, password, session sections omitted)
There is still one more file (system-auth) to look into:
   auth       required       pam_env.so
   auth       required       pam_unix.so try_first_pass likeauth nullok

When authenticating a user, PAM will read the lines from top to bottom.

   pam_tally    - tracks login failures and can take related action
   pam_shells   - checks if user has a valid shell (listed in /etc/shells)
   pam_nologin  - checks if logins were disabled (shows message)
   pam_env      - does something with environment

and finally:

   pam_unix     - checks password according to /etc/shadow

This is an overview of the default PAM authentication schema (for Gentoo). Somewhere in this process we will need to add our OTP authentication.

The easiest approach is just to modify the first file: /etc/pam.d/sshd. At the end of all the 'auth' entries, we can just add our pam_otpasswd module. The file would then look like this:

   auth       include        system-remote-login
   # Line added for OTP:
   auth       required       pam_otpasswd.so secure

   account    include        system-remote-login
   password   include        system-remote-login
   session    include        system-remote-login

This will cause PAM to ask us for an OTP after we have been asked for our normal UNIX password, regardless of whether the UNIX password was correct or not. This can lead to a Denial of Service issue when the attacker tries to login enough times to use up all of our printed passcards. If we have some other security mechanism (like sshguard - which blocks the SSHD port for people who try dictionary attacks) it might be perfectly okay.

If this risk is not acceptable, then we can change the line with pam_unix.so module from:

   auth       required       pam_unix.so try_first_pass likeauth nullok

to:

   auth       requisite      pam_unix.so try_first_pass likeauth nullok

This configuration will require the correct UNIX password be entered before asking for an OTP.

If we would rather not mess with global PAM configuration files (system-auth, etc), we could move all auth lines to the sshd file, change the pam_unix authentication to 'requisite' (as above), then add the pam_otpasswd line. This would result in following configuration:

   # Include commented out:
   #auth      include        system-remote-login

   # All auths included in sshd:
   auth       required       pam_tally.so onerr=succeed
   auth       required       pam_shells.so
   auth       required       pam_nologin.so
   auth       required       pam_env.so

   # Changed 'required' to 'requisite':
   auth       requisite      pam_unix.so try_first_pass likeauth nullok

   # Our added line for OTP:
   auth       required       pam_otpasswd.so secure

   # And all the rest...
   account    include        system-remote-login
   password   include        system-remote-login
   session    include        system-remote-login

This is exactly what is written in our examples/otpasswd-login file. You can place this file in /etc/pam.d, and then edit your sshd file to use it by modifying auth line:

   auth       include        otpasswd-login
   account    include        system-remote-login
   password   include        system-remote-login
   session    include        system-remote-login

For more information about Linux-PAM, you may consult the PAM(7) man page on your system, or read the PAM System Administrator's Guide, which can be found at: http://www.kernel.org/pub/linux/libs/pam/Linux-PAM-html/Linux-PAM_SAG.html