I'm using Ubuntu.

I'm just wondering if it's possible to have libpam-google-authenticator (which lets you log in using a code generated by your phone) AND certificate authentication set up to work together, and if it is possible, how I'd go about setting it up. Thus - in order to log into my account, you'd have to have my password, my phone (and its passcode) AND my certificate/private key and its password.

I've gotten both to work independently but have never been able to get them to work together. I'm sure somehow it's possible though.


  • Usually you don't gain much by duplicate factors. A certificate and code generator fit the 'something you have' factor. A password fits the 'something you know'. The other common factor is 'something you are' (biometrics).
    – Zoredache
    Jul 8, 2013 at 23:47

3 Answers 3


It is possible to do this by chaining together PAM modules. But before I get into any details:

Incorrectly configuring PAM can and WILL prevent you from logging into your system

Thankfully you can always boot up into single user mode and fix the problem, but just be warned that PAM is not something you want to mess with more than necessary.

Anyway, the idea behind this is that it is possible to utilize stacking PAM modules to make sure that pam-google-authenticator, pam_unix (this checks your password) and the certificate module all have to succeed to allow you access. By default, PAM is configured to allow any authentication module to authenticate you, skipping the others.

In /etc/pam.d/common-auth, you will see near the top a line that looks similar to the following:

auth    [success=2 default=ignore]  pam_unix.so nullok_secure try_first_pass

This tells PAM that should pam_unix.so succeed, it will skip the next two rules (which are usually another authentication module and then pam_deny.so) and proceed to the optional modules. However, should the module fail, then it will be ignored, and control will pass on to the next module in the chain. This continues down each authentication module until either control skips to the optional block, or PAM hits pam_deny.so and fails right there.

This can be leveraged to ensure that pam-google-authenticator, pam_unix.so and your certificate PAM module all have to succeed to allow you access. I don't know the name of the Google authenticator module or the certificate module you are using, but you should be able to find them in your common-auth file. So by putting something like this at the top:

auth    requisite   pam_unix.so nullok_secure
auth    requisite   pam_google_authenticator.so
auth    requisite   pam_certificate_auth.so
auth    [success=<n>]   pam_permit.so

Replacing <n> with the number of modules between the pam_permit.so module here and the next pam_permit.so module - in other words this should be set to the top-most auth module's [success=n default=ignore] code + 1. This syntax is a bit funky, but essentially skips the auth modules after the above modules have succeeded.

Of course, you may be wondering how to limit this three-step authentication to just your user account. This can be done with a pam_succeed_if.so module, and should be inserted above the three-step auth block described above:

auth    [success=ignore default=4]  pam_succeed_if.so user = <username>

Where <username> is replaced by your username. This line simply says that should pam_succeed_if.so succeed (aka your username matches the username on that line) then PAM should proceed with the next modules, which are the three-step auth modules. Otherwise, PAM should jump to the real modules, which are 4 modules away from this one.

To match multiple things, for example membership of a group along with a certain username, multiple lines must be used, for example:

auth    [success=1 default=ignore]  pam_succeed_if.so user = <username>
auth    [success=ignore default=4]  pam_succeed_if.so user ingroup <group>

Before doing any of this, I would backup the common-auth file, and also get myself familiar with single user mode and how to restore the old file in case of emergency. This configuration has not been tested by me, but it should work.

For testing this the first time, get a root shell or two open, and just leave them alone. These act as fallbacks in case anything goes wrong, since you can easily replace common-auth with the backup. Then, make these changes. Next, try using su to log in to your user account - you should need to go through the three-step authentication process.

Full documentation for the pam_succeed_if.so module can be found at http://linux.die.net/man/8/pam_succeed_if

  • Excellent answer! If I could upvote this more than once, I would. Jul 8, 2013 at 22:43
  • Thanks! Although - For certificate login I'm adding my public key into .ssh/authorized_keys (using the RSAAuthentication and PubkeyAuthentication settings in sshd_config) and for the OTP code I'm using pam_google_authenticator - google-authenticator.googlecode.com/hg. So how would that work?
    – Jesse W
    Jul 11, 2013 at 23:00
  • @JesseW For this to work you need to set SSHD to use PAM as well as a public key. Although I'm not sure on the specifics, you will certainly need to set ChallengeResponseAuthentication and UsePAM to 'yes', then set the lines detailed in my answer above into either /etc/pam.d/sshd or /etc/pam.d/common-auth, depending on if you want to either perform this for all logins or just SSH. Remember to remove the 'pam_certificate_auth.so' filler line and modify the [success=<n> line as a result. Jul 12, 2013 at 18:41

I read this post and thought it sounded cool - here is how I got three-factor authentication to work. I wrote a blog post about it here.

Basically, I set up Google Authenticator and password in PAM, then afterwards set up public key authentication in OpenSSH (this bypasses the the two others), and finally required by OpenSSH to also authenticate through PAM (the last line)

From /etc/ssh/sshd_conf

PubkeyAuthentication yes
ChallengeResponseAuthentication yes
PasswordAuthentication no
UsePAM yes
AuthenticationMethods publickey,keyboard-interactive

Only Pubkey + GoogleAuth you have to add to top of your /etc/pam.d/sshd

#auth    requisite    pam_unix.so nullok_secure #if you want password, too :)
auth    requisite    pam_google_authenticator.so
auth    [success=2]  pam_permit.so

I asume you have OpenSSH >= 6.2 and sshd_config edited

For more paranoid security add some extra configs :D

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .