György Demarcsek Ifj.
2015-May-04 14:08 UTC
OpenSSH two-factor authentication combined with Kerberos / PubKeyAuth
Dear OpenSSH Development Team, I'm writing because I have trouble implementing a relatively straightforward authentication scenario with OpenSSH Server and I could not find any useful information by googling and probably you are my best choice to turn to because you must be the most familiar with the internals of OpenSSH. I'm trying to implement two-factor authentication for OpenSSH. The environment is Centos 7 (kernel: 3.10.0-229.1.2.el7.x86_64) with OpenSSH_6.6.1p1, OpenSSL 1.0.1e-fips 11 Feb 2013. We have Active Directory (LDAP) + Kerberos deployed. The specification is as follows: - A user with an existing, valid Kerberos ticket must be asked only for the second factor - A user without an existing, valid Kerberos ticket must be asked for both his password and a second factor - Local users (no LDAP acc.) should be able to authenticate with their local passwords - The second factor must not be offered before the first one - Besides Kerberos, public key authentication should be also accepted as first factor if available - The feature should be able to be limited to a set of users - others just get let in with their passwords For performing the second factor's authentication process, there is 3rd party a PAM module available that knows nothing about Kerberos. So here is what I did: Put these lines into /etc/ssh/sshd_config: # To enable PAM - this will make sshd use PAM with configuration /etc/pam.d/sshd UsePam yes ChallengeResponseAuthentication yes # To enable Kerberos and public key authentication - it will let sshd use existing Kerberos tickets GSSAPIAuthentication yes # Enable public key authentication PubkeyAuthentication yes # Password validation should be done via the KDC PasswordAuthentication yes KerberosAuthentication yes KerberosOrLocalPasswd yes # Kerberos / Public Key + PAM AuthenticationMethods gssapi-with-mic,keyboard-interactive:pam publickey,keyboard-interactive:pam password,keyboard-interactive:pam # (only supported for OpenSSH 6.2 or higher) The auth section of the PAM configuration for sshd (/etc/pam.d/sshd) auth [success=ignore default=1] pam_localuser.so auth substack password-auth auth [success=1 default=ignore] pam_localuser.so auth required pam_2fa.so [...some arguments...] auth include postlogin The module pam_2fa.so is responsible for prompting for and validating the second factor. Now for Kerberos, this does almost everything I wanted to achieve. However, for local accounts, it results in two subsequent password prompts. This is my main problem here. This is because in this case the path "password,keyboard-interactive:pam" is used,as expected. (I need this auth. path so someone with a Kerberos account but without a valid ticket can get a ticket by entering the password then the OTP.) If I remove the password-auth substack completely from the PAM config, then Kerberos accounts remain working and local accounts remain not working. To me, it seems like the KerberosOrLocalPasswd yes statement gets ignored, because UsePAM yes is also present. However, sshd really keeps using KDC for password validation, because otherwise it would not work for LDAP accounts either. So again, to further clarify what I wish to implement here is the pseudocode that described the desired authentication logic: if gssapi_auth_ok(principal) or pubkey_auth_ok(pubkey): return second_factor_auth(user, read_otp()) else: if is_local_account(user): return local_passwd_auth(user, read_password()) else: if krb5_auth(principal, read_password()): return second_factor_auth(user, read_otp()) return AUTH_ERR So my scenario I think is not too complex or ambitious in any way, but I still could not find a clear way to implement it despite I spent days researching and experimenting. Could you please help me find a solution? Thank you very much in advance! Cheers, Gyorgy Demarcsek
Damien Miller
2015-May-05 02:34 UTC
OpenSSH two-factor authentication combined with Kerberos / PubKeyAuth
On Mon, 4 May 2015, Gy?rgy Demarcsek Ifj. wrote:> Dear OpenSSH Development Team, > > I'm writing because I have trouble implementing a relatively > straightforward authentication scenario with OpenSSH Server and I could not > find any useful information by googling and probably you are my best choice > to turn to because you must be the most familiar with the internals of > OpenSSH. > > I'm trying to implement two-factor authentication for OpenSSH. The > environment is Centos 7 (kernel: 3.10.0-229.1.2.el7.x86_64) with > OpenSSH_6.6.1p1, OpenSSL 1.0.1e-fips 11 Feb 2013. We have Active Directory > (LDAP) + Kerberos deployed. The specification is as follows:It looks like your 2nd factor is going via PAM. This makes things difficult (see below).> - A user with an existing, valid Kerberos ticket must be asked only for > the second factorThis is pretty easy using AuthenticationMethods> - A user without an existing, valid Kerberos ticket must be asked for both > his password and a second factorThis might be tricky if you are using a challenge/response 2nd factor because both would go via PAM and there is no signalling between sshd and the PAM stack that could be used to tell the latter that it needs to ask for password+challenge/response rather than just password.> - Local users (no LDAP acc.) should be able to authenticate with their > local passwordsThe only way this could be expressed in sshd is by putting all local users into a group and then using "Match group" to vary their AuthenticationMethods.> - The second factor must not be offered before the first oneAuthenticationMethods controls the ordering of the methods offered, so this should be possible.> - Besides Kerberos, public key authentication should be also accepted as > first factor if availableSubject to the caveats about, this can be done with AuthenticationMethods too.> - The feature should be able to be limited to a set of users - others just > get let in with their passwordsAgain, you'll need to set this up using groups.> For performing the second factor's authentication process, there is 3rd > party a PAM module available that knows nothing about Kerberos. So here is > what I did: > > Put these lines into /etc/ssh/sshd_config:...> KerberosAuthentication yes > KerberosOrLocalPasswd yesIf PAM is handling the password authentication, them I'm not sure whether this will make much difference.> # Kerberos / Public Key + PAM > AuthenticationMethods gssapi-with-mic,keyboard-interactive:pam > publickey,keyboard-interactive:pam password,keyboard-interactive:pamThe problem here is the last stanza: password,keyboard-interactive:pam since PAM is handling password authentication under the hood too, but PAM password authentication is a bit of a hack and only works when the PAM configuration makes a single password prompt and expects a single reply. Your PAM stack wants a password and a 2FA response, so the 'password' authn method won't work. I don't know how to solve this with the current signalling between sshd and PAM sorry.> Now for Kerberos, this does almost everything I wanted to achieve. However, > for local accounts, it results in two subsequent password prompts. This is > my main problem here. This is because in this case the path > "password,keyboard-interactive:pam" > is used,as expected. (I need this auth. path so someone with a Kerberos > account but without a valid ticket can get a ticket by entering the > password then the OTP.) If I remove the password-auth substack completely > from the PAM config, then Kerberos accounts remain working and local > accounts remain not working. To me, it seems like the KerberosOrLocalPasswd > yes statement gets ignored, because UsePAM yes is also present. However, > sshd really keeps using KDC for password validation, because otherwise it > would not work for LDAP accounts either.It's probably using kerberos via PAM.> So my scenario I think is not too complex or ambitious in any way, but I > still could not find a clear way to implement it despite I spent days > researching and experimenting. Could you please help me find a solution?It might be possible to enhance sshd's signalling to PAM by stashing something in a _SSHD_COMPLETED_AUTH PAM environment variable (or somesuch) that modules could use to decide how to proceed, but I'm years rusty with PAM. Maybe Darren or someone else who's more familiar could suggest something. -d