17

OpenSSH won't invoke PAM at all if public key (RSA) authentication is configured and the client presents a valid key. So if you use key-based auth, you can't enforce 2FA easily.

One workaround for this limitation involves writing a helper program that will prompt for a Yubikey OTP. This helper program is arranged to be executed by sshd after the user successfully authenticates using the ForceCommand directive. Example: https://www.berrange.com/posts/2011/12/18/multi-factor-ssh-authentication-using-yubikey-and-ssh-public-keys-together/

Since I don't trust my knowledge of shell programming (handling signals, tty allocation etc) to review the helper program, so I kept looking for something different.

What are the holes in the following alternative approach?

  • Configure yubikey to do 2FA for ssh password-based auth.

  • Every login, 'X', will have a "bastion" login called 'pre-X'.

  • Both logins will exist on the same machine

  • One sshd instance

  • Using the Match sshd configuration directive, the ssh server will be configured to disallow public-key authentication for all logins that match the pattern 'pre-*'.

  • The 'bastion' login will be created with no home directory, login shell set to /bin/false, gid set to 'nogroup' and anything else can we can do to make it as weak as possible. For good measure, use the ForceCommand ssh directive for these logins to always execute /bin/false and use ChrootDirectory to sandbox it.

  • Use the AllowUsers directive to disallow logins other than bastion ones from logging in from any IP except localhost.

  • Use ProxyCommand at the ssh client end to script away the tunneling via the bastion login.

I have done this and it works well, but I'm wondering if I missed something?

Bastion users are created like this:

# password will never be typed in, so need to record it
sudo useradd -M -N -g nogroup -s /bin/false pre-user001 -p $(dd if=/dev/urandom bs=128 count=1 2>/dev/null  | base64 -w0)

sshd_config looks like this:

# Nobody can login from anywhere except localhost
AllowUsers *@localhost
# ... except for logins starting with 0
AllowUsers pre-*@*

# force password auth for bastion logins
Match User pre-*
PasswordAuthentication yes
RSAAuthentication no
PubkeyAuthentication no
ForceCommand /bin/false
user391
  • 171
  • 1
  • 3

2 Answers2

4

As of 2015 (with OpenSSH >= 6.2), your assumption that sshd won't invoke PAM in combination with public key authentication doesn't hold anymore.

With OpenSSH 6.2 you can enforce a second factor or even multiple factors for authentication in addition to public key authentication.

The AuthenticationMethods directive can be used to specify multiple factors on a global or user specific level in the sshd_config, for example:

AuthenticationMethods publickey,keyboard-interactive

keyboard-interactive triggers the PAM chain where e.g. a OTP pam module can be configured for sshd.

maxschlepzig
  • 550
  • 4
  • 10
1

I've used DuoSecurity in the past with great success, it follows a similar method as Yubikey but allows the use of multiple authentication methods.

Very easy to setup with a minimal user learning curve.

user24751
  • 189
  • 6
  • The Yubikey has a couple of advantages compared to receiving a phone call/SMS etc. From a UX point of view, it types in the passcode for you, which makes it convenient to secure even operations which are relatively frequently performed (e.g., sudo). From a security POV, the security of the second factor relies a lot on the second factor being very hard/impossible to clone. A token is WAAAY harder to silently clone than a phone number (most phone companies provide a way to redirect phone calls to another number) or an phone app. – user391 Apr 14 '13 at 16:27
  • 3
    Also, a Yubikey can be run in serverless (challenge-response) mode. Or you can run an auth server yourself. AFAIK Duo doesn't have these. Thanks for mentioning Duo though. Always good to hear other alternatives. My comments are mostly meant for future readers of this question. Note: I am not affiliated with Yubikey except as customer. – user391 Apr 14 '13 at 16:33