ymartin59 / java-kerberos-sfudemo

Java 8 Kerberos MS-SFU Demonstration Code
Apache License 2.0
13 stars 8 forks source link

principal property from java.login.config file should be set to SPN not the UPN #6

Open bhushan1987 opened 4 years ago

bhushan1987 commented 4 years ago

Hello YMartin,

Thanks for the excellent example of Kerberos Constrained Delegation. I observed one minor issue regarding principal property from java.login.config file. In given example, you have provided "user@domain" as the value to this property. However, this causes the error - "krb_error 0 Do not have keys of types listed in default_tkt_enctypes available;" I think the value should point to the SPN provided during keytab creation. Example = "HTTP/ServiceName@domain".

Thanks, Bhushan

ymartin59 commented 4 years ago

Hello Bhushan. Thanks. Of course you're right. Fixed. Yves

ymartin59 commented 4 years ago

Your remark is correct: keytab content and service principal must be consistent.

But in fact the "javaservice" account keytab has no requirement to be a "HTTP/" SPN as end-user browser will never request a TGS for it - the service code will impersonate user from its login name (not from a end-user TGT)

bhushan1987 commented 4 years ago

Usually, we take the service user keytab and create a TGT for the service user. Using this TGT, we impersonate the end user using his login name. When creating a TGT for service user, the principal property from java.login.config comes into picture. Remember that ktpass will change the UPN of the user with the given SPN. In that case, service user's TGT can not be created by simply using its login name. We have to use the SPN.

ymartin59 commented 4 years ago

This is correct... but who will request a TGS for the SPN "HTTP/..."? My opinion is the answer is nobody / no browser... So the principal name may be left with only its login name... as far as ktpass, keytab and java.login.config are consistent (meaning without refering to a SPN), it should work. I no longer work on this topic with a "real" environment, so I should invest some time to build a docker-based setup with MIT kdc or keimdal to demonstrate and confirm that idea.

ymartin59 commented 4 years ago

@michael-o Hello. I request your help and advices about this topic. Am I correct to think there is no need to define a "SPN" (typically HTTP/...) when setting up service account with keytab to create initial kerberos context when only doing KCD impersonation?

michael-o commented 4 years ago

@ymartin59 Correct. The Deployment section is wrong. The UPN in the command is wrong. The service account does not require SPNs of any kind. You cannot kinit with SPNs in AD by design. I would recommend using msktutil instead of the crappy ms tool.

michael-o commented 4 years ago

The use case section is also wrong.

michael-o commented 4 years ago

There are also several bugs and conceptual errors in the code.

bhushan1987 commented 4 years ago

@ymartin59 @michael-o There is a need to define SPN while creating keytab, at least when using ktpass on windows. Without SPN, I am not aware of any way of creating keytab. Check this - [https://blogs.technet.microsoft.com/pie/2018/01/03/all-you-need-to-know-about-keytab-files/]

Also, Note that the userPrincipalName get updated with the value you provided in the parameter /princ. You can prevent this with the parameter -SetUPN at the end of the command. In that case, the UPN will not be touched and the value specified with /princ will only be added to the servicePrincipalName (SPN).

Moreover, the keys corresponding to the given SPN will be added to the keytab. You can read the entries using _ktpass /in _ This command shows the keys for the SPN and not the service user name. Without updating the UPN of service user to the SPN, you can not get ticket for service user using the keytab. It throws "Identifier not found in database"

Please let me know if there is any gap in understanding or any basic thing that I am not aware of.

ymartin59 commented 4 years ago

@michael-o Thanks for your answer but statement "You cannot kinit with SPNs in AD by design." is wrong. I can use Java "kinit" and MIT kerberos client tools on Linux to do "kinit HTTP/..." with any SPN I defined in ActiveDirectory - it is an easy way to confirm ktpass succeeded and there is no SPN conflict in KDC, the same way I do "kvno HTTP/..." when command is available.

@bhushan1987 Of course listing entries do not show regular service username, if it has not been added explicitly by command. You can find at https://github.com/tellisnz/collared-kerberos how to do it in "7. Add the MYCOOLSERVICE user principal to the keytab using the command"

This demonstration code is expected to work with Java on Linux or Windows system, with either ActiveDirectory or any other KDC implementation with MS-SFU extension like MIT or Heimdal servers. It has been extracted from a PoC I wrote for a project, but abandoned because of cross-realm environment for which support was lacking in Java Kerberos runtime (now implemented, to notice)

michael-o commented 4 years ago

Don't compare kvno and kinit. AD is not designed to login with SPNs, but UPNs only. In our huge first you cannot. Everything else is out of the concept since all principals on one account share the same longterm key, the principal on the machine does not even know that a SPN has been set. MIT Kerberos is different, I don't have any experience with it as KDC.

@bhushan1987 forget this MS tool, you msktutil. It works perfectly here with MIT Ketberoa and JGSS.

bhushan1987 commented 4 years ago

I've done a lot of investigation on Kerberos constrained delegation, and finally I've figured out the correct way of doing it using Java. I think following post will be helpful to user landing here on this page.

https://stackoverflow.com/questions/39743700/java-spnego-authentication-kerberos-constrained-delegation-kcd-to-backend-se/57377671#57377671