I'm using Ubuntu 14.04.1 (with OpenSSH 6.6 and libpam-google-authenticator 20130529-2).

I'm trying to set up SSH logins where the public key authenticates (without a password) and a user is prompted for a code from Google's Authenticator.

Following/adapting these instructions has gotten me a password prompt as well as a Google Auth prompt:

I've installed the package, edited my /etc/ssh/sshd_config and /etc/pam.d/ssh files

In /etc/ssh/sshd_config:

ChallengeResponseAuthentication yes
AuthenticationMethods  publickey,keyboard-interactive
UsePAM yes

and at the bottom of /etc/pam.d/ssh:

auth required pam_google_authenticator.so nullok # (I want to give everyone a chance to set up their 2FA before removing "nullok")

I know PAM is order dependent, but is sshd_config also?

What am I doing wrong? Any help would be appreciated.

up vote 26 down vote accepted

Have got it working well, first did:

apt-get install libpam-google-authenticator

In /etc/pam.d/sshd I have changed/added the following lines (at the top):

# @include common-auth
auth required pam_google_authenticator.so

And in /etc/ssh/sshd_config:

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

Works well and I now receive a "Verification code" prompt after authentication with public key. I am not sure how I would allow authentication with password+token OR key+token, as I have now effectively removed the password authentication method from PAM.

Using Ubuntu 14.04.1 LTS (GNU/Linux 3.8.0-19-generic x86_64) with ssh -v : OpenSSH_6.6.1p1 Ubuntu-2ubuntu2, OpenSSL 1.0.1f 6 Jan 2014

  • So, for posterity's sake, I realized my problem. I also had tried PasswordAuthentication no, but that wasn't it. The problem is/was that I had/have ControlMaster auto and ControlPath directives in my ~/.ssh/config file. I wanted to make sure I didn't lock myself out, so I would always leave an SSH session open. Since my computer would just reuse them, I always got in without the system asking for a token. I marked your answer as correct, since someone following it would indeed get a working setup. Thanks! – JT. Dec 2 '14 at 6:02
  • 2
    I'm using CentOS 7. I have PasswordAuthentication no, ChallengeResponseAuthentication yes, AuthenticationMethods publickey,keyboard-interactive, and UsePAM yes in sshd_config. It validates my key and then asks me for my Google Authenticator token and then also asks me for my password. Makes me do all three—can't skip any of them. I've also tried AuthenticationMethods publickey,keyboard-interactive:pam as suggested by the man page, but that didn't change anything. Any ideas? – Nick Williams Feb 11 '15 at 2:52
  • 6
    @NickWilliams I was having the same issue. What fixed it for me was that I needed to commend out the @include common-auth line that the answers shows. I just thought it was a comment for the pam_google_authenticator line in /etc/pam.d/sshd at first. – freb Feb 27 '15 at 20:14
  • 5
    Thank you! My solution wasn't exactly the same (I needed to comment out auth substack password-auth), but your comment solved my problem! – Nick Williams Feb 27 '15 at 22:04
  • 1

I was finally able to get this working by placing auth [success=done new_authtok_reqd=done default=die] pam_google_authenticator.so nullok at the top of /etc/pam.d/sshd.

According to the pam.d man page:

  • success=done means that if Google Authenticator signs off, no more authentication will be performed, meaning no additional password prompt.
  • default=die means that if Google Authenticator rejects the login attempt, authentication will immediately fail, skipping the password prompt.

So [success=done new_authtok_reqd=done default=die] is sort of a mix between the sufficient and requisite control values, since we want behavior from both: if success, terminate immediately (sufficient), and if failure, also terminate immediately (requisite).

Note that the nullok argument to pam_google_authenticator.so means that if a ~/.google_authenticator file is not found for a user, public-key authentication proceeds as normal. This is useful if I want to lock down only a subset of my accounts with 2FA.

Linus Kendall's answer should work on older systems, but on newer Linux machines it is problematic; on my arch linux based webserver that configuration results in pam asking for my authenticator code and my password after receiving my ssh key (i.e. I need all 3).

A simpler solution that prevents this problem and that should work on every system is to change the entry in /etc/pam.d/sshd to:

auth sufficient pam_google_authenticator.so

And then to make the same edits to ``/etc/ssh/sshd` that Linus mentioned:

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

That should ask you for your authenticator token after the server accepts your public key. It should not ask for your password.

As a side note, if you wish to have an sftp user account, you will probably need to bypass google authenticator in order to get it to work. Here is a suggestion of how to do that securely using an sftp jail. In etc/ssh/sshd_config:

Subsystem sftp internal-sftp
Match User ftp-user
  PasswordAuthentication yes
  AuthenticationMethods password
  ChrootDirectory /path/to/ftp/dir
  ForceCommand internal-sftp

You will need to make the permissions on /path/to/ftp/dir root write only (e.g. chown root:root /path/to/ftp/dir, chmod 755 /path/to/ftp/dir. All of the parents above that directory also need secure permissions. The way I usually do this is by making the chroot directory /home/shared/user, creating a directory in there (e.g. 'data') and then mounting whatever directory I want to share like this: sudo mount -o bind /path/to/ftp/dir /home/shared/user/data

If you follow all of those steps, you will have public key + google authenticator login for your ssh users, and a functional password protected sftp account for data transfer.

  • This works great. And since for some reason I just don't feel comfortable commenting out common-auth, this was more ideal than Linus's solution. – Luke Sapan Jan 11 '16 at 6:32
  • Thanks a lot! wasted a night debugging ssh, wondering why I still have to type password after pubkey+authcode…… – felix021 Apr 22 '17 at 16:14

protected by Community Jul 23 '16 at 0:45

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.