duosecurity / duo_unix

Duo two-factor authentication for Unix systems
http://www.duosecurity.com
349 stars 136 forks source link

Autopush with password pushes prompt twice #274

Open tilghman opened 6 months ago

tilghman commented 6 months ago

Description

When pam_duo.conf specifies autopush, and the sshd AuthenticationMethods include a combination of "password,keyboard-interactive", Duo pushes the request twice before authentication can succeed. This does NOT occur if a publickey is offered and authenticates. Also, turning off autopush similarly allows a single push to authenticate the user.

We are currently running RHEL 7 and RHEL 9, with the behavior observable on both. RHEL 7 is likely less of a concern, as it reaches EOL in under 60 days.

Expected Behavior

When autopush is turned on in combination with a password, Duo should authenticate the user after a single push.

Actual Behavior

Two pushes are sent to the user device, after which authentication succeeds.

Steps to Reproduce

  1. Configure sshd_config with AuthenticationMethods set to "publickey,keyboard-interactive password,keyboard-interactive" (order of these options does not change the result).
  2. Configure autopush=yes in /etc/duo/pam_duo.conf
  3. ssh in as a user without a publickey set
  4. Observe double push
  5. Configure autopush=no in /etc/duo/pam_duo.conf
  6. ssh in as a user without a publickey set
  7. Observe a single push is sufficient for authentication.
  8. Set an SSH key for the user.
  9. Set autopush=yes in /etc/duo/pam_duo.conf
  10. ssh in as a user
  11. Observe that a single push is sufficient with a publickey providing the other half of authentication.

Workarounds

Turning off autopush is sufficient to work here. However, we would prefer to have autopush turned on.

AaronAtDuo commented 6 months ago

@tilghman I have a hunch that the issue is duo to your pam stack being run twice when not using the publickey. In that case, the "password,keyboard-interactive" clause of the sshd config is being used, and each of those options will run the PAM stack. Without more details about your pam config, I can't say for sure if that's the cause, or why exactly the autopush config changes the behavior.

Since keyboard-interactive can do everything password can do plus more, it's fairly unusual to need both things for a ssh login. Are you able to accomplish all the authentication steps under a single keyboard-interactive requirement?

tilghman commented 6 months ago

Our pam config is (almost) identical to the recommendation on the duo_unix page. Here it is: auth required pam_sepermit.so auth required pam_env.so

auth substack password-auth

auth sufficient pam_duo.so auth sufficient pam_unix.so auth required pam_deny.so auth include postlogin

If we comment out pam_unix.so, then password+Duo authentication fails before the Duo push is attempted.

No, we cannot use just keyboard-interactive. That would allow Duo-only to be sufficient for authentication, and we are explicitly required to use two-factor (password plus Duo or publickey plus Duo) for all administrator-privileged logins.

AaronAtDuo commented 6 months ago

@tilghman Ah, I see. We have found that if your authentication requirement for ssh is (either pubkey OR password) AND Duo that is virtually impossible to accomplish with pam_duo, because you need a single pam stack that does two different things in different circumstances.

Our recommendation for this use case is to implement login_duo as a ForceCommand, see https://duo.com/docs/loginduo#enable-login_duo

tilghman commented 6 months ago

I'm reading through the caveats on ForceCommand, and it scares me a bit. The point of having two-factor is to theoretically make logins more secure, not less. And the line right in the documentation is that the mitigation is to use pam_duo, not login_duo.

Also, I'm rather confused at why, when we turn autopush OFF, the problematic behavior disappears.

It sounds like autopush is buggy, and this should be either noted in the documentation or fixed.

AaronAtDuo commented 6 months ago

@tilghman I agree that login_duo is less desirable overall, but due to the behavior of sshd and PAM, that is the only way to allow either pubkey or password as a first factor, without trying to write a very complicated pam module that can persist state across pam invocations and/or detect the ssh context.

I suspect the difference in the autopush behavior comes down to your failmode configuration. With autopush disabled, during password authentication, pam_duo is unable to display the prompt (since password is non-interactive), and thus failmode is triggered. If you are failing "safe" aka "open", pam_duo will succeed.

With autopush enabled, pam_duo does not need to display the prompt and so is able to do 2FA.

Then, in either case, the keyboard-interactive authentication runs the PAM stack. pam_duo is able to display the prompt (autopush disabled) or send the push (autopush enabled) and auth resolves.