6

For some reason my client needs to log into two kerberos realms..let's say REALM1 and REALM2. My principal has been signed in both realms, with two different keytabs created(principal/host@REALM1 with keytab1 and principal/host@REALM2 with keytab2). In another word, I can kinit and klist my principal against two different realms.

Now I need to run an application in which first of all a few tasks needed to be done in the realm1, and then other tasks needed to be done in realm2, so I have to log in realm1 first,finish some work and then log in realm2. I tried to do it by resetting System property "java.security.krb5.conf" in the middle of my program but failed to switch from realm1 to realm2(failed at log-in, it seemded the default realm remained the same.)

I searched over and saw a relevant post's answer(Kerberos Auth with JAAS and multiple realms) and I understand a keytab is bound to a realm--what I do not understand is -- I have generated two keytabs for two realms --why can't log in two realms consequently? is the only way to do it through cross-realm authentication..?

Cœur
  • 37,241
  • 25
  • 195
  • 267
user2117843
  • 63
  • 1
  • 3

5 Answers5

3

Don't do that. Establish a cross-realm trust and you can use the original keytab of your client to perform all tasks in the foreign realm. We have at least 30 realms here and my Unix machine is joined in one realm of course. This works pretty neat.

Michael-O
  • 18,123
  • 6
  • 55
  • 121
  • 1
    Thanks Michael, Can you explain a little bit why you think cross-realm is a better solution? I just did not get: what if these realms, as well as these tasks are totally irrelevant? Does accessing two realms with two keytabs consequently break any security code? – user2117843 Feb 28 '13 at 17:26
  • First of all, are you able to establish a trust? If so, these would be the benefits. Users from those realms can access resouces in either direction. You can delegate credentials as you think fit and impersonate. You don't need to manage two keytabs and looking for errors. A machine, can and should always be member of one Kerberos only (if you joined with Samba). Everything else is trusts. One big problem you'll hit is when you want to host services for both realms on this machine, you will distinct IPs for both realms and correct DNS entries. This will cause a lot of trouble. – Michael-O Feb 28 '13 at 17:56
  • Many thanks Michael. I understand these benefits now. Somehow for my application scenario, my two realms can not be guaranteed to establish a trust between them---that's why I had my client end registered two principals respectively in two realms. I will apply your solution if they can establish trust. I will really appreciate if you can shed some light on the case that these realms can't establish trust. – user2117843 Feb 28 '13 at 18:55
  • please report back when you have checked for the trust. I will provide further input. – Michael-O Feb 28 '13 at 19:11
  • 1
    Hi Michael, I think I can build the trust b/w two of my realms..it is a one way trust from Realm A to Realm B--now my question is, for some reason, I want one and only one of my principals in realm A to get transitive ticket to authenticate with realm B, not other principals..is it possible to do so? Thanks! – user2117843 Mar 06 '13 at 06:02
  • If you are using Active Directory you might succeed with contrained delegation. You should check that with your admin. – Michael-O Mar 06 '13 at 07:29
  • Hi Michael, I have established a bi-direction trust b/w Realm A and Realm B. My client has the keytab to log into Realm A --after logging in it is going to use service of Realm B ... from the perspective of java programming is there anything I need to specify for cross-realm log in? or i just simply log into realm A as usual and submit request to realmB, the rest will be taken care by the trust? Thanks very much for your help! – user2117843 Mar 11 '13 at 18:45
  • Actually not but your `krb5.conf` must contain at least one KDC per realm or appropriate DNS entries which I would prefer and the hostname to realm name mapping. – Michael-O Mar 11 '13 at 19:15
  • Hi Michael, I have added both realms and their trust relation in the krb5.conf. After I logged into realm A using keytab as user@RealmA and trying to request the service of Service@RealmB which trusts A--- I kept on getting error "no server Service@RealmA" becoz those two realms are considered at the "same realm" which I do not understand why. I think I probably missed something in DNS entries. How does the java krb5 determines "same realms" or "different realms"? – user2117843 Mar 13 '13 at 21:30
  • Please show your `krb5.conf`, the UPNs, SPNs involved and the exact error message. – Michael-O Mar 13 '13 at 21:36
2

In your case you might be able to get away with simply forcing a reload on the configuration before each use using the refreshKrb5Config=true option in KRB5LoginModule in JAAS login.conf (See Reload Kerberos config in JAVA without restarting JVM).

This won't work well in a multi-threaded application though as you'll have to serialize access to this shared resource. The fact that the Java Kerberos implementation uses System properties (and a single configuration file) is an unnecessary restriction, perhaps even a bug.

The accepted answer of use cross domain trusts might be good sometimes, but not always. For example if your network administrators don't want ALL services to trust the other domain, just this one particular service then you are out of luck. Say you have a multi-threaded application that is written in Java and provides a service that wants to accept tickets from multiple realms you would have to run one instance of this application per realm (krb5.conf hostname is static, just keytab and kdc changes). This becomes a big headache if this one specific application is a web service running on port 443 using SPNEGO. Now you'll need two application server instances on different ports? Ouch.

Community
  • 1
  • 1
Ryan
  • 7,499
  • 9
  • 52
  • 61
  • 1
    Another options is to actually use separate JVMs and communicate via RMI. I've got this setup working, but it is somewhat fragile in that I have to deal with the RMI Registry, one remote service JVM per extra realm, and my original JVM. – Ryan Aug 21 '15 at 15:02
0

I would recommend you look at the oVirt open source project.

Look at the java code of oVirt engine, and look at the bll module (ovirt-engine/backend/modules/bll) for the authentication code (look at DirectorySearcher.java) - we do support login in to several kerberos realms.

We have a tool called engine-manage-domains that let you add a "domain user" (which we use mainly for searching users and groups in the added realm) for a domain - for example:

You can add user "aaa" from domain "example.com" which is ActiveDirectory. This modifies the krb5.conf defined which is held at /etc/ovirt-engine/krb5.conf, and which the ovirt-engine uses.

Look at the place in the code where we create a JAAS login object and perform login (we perform explicit login if we don't a valid ticket to the realm).

I think too that cross realm authentication is better solution, but you might face scenarios in which you will not be able to create such trust. For example, at the case of oVirt - it's an open source virtualization management system, and it should not "interfere" or force changing of setups of other systems installed at user's organization.

slm
  • 15,396
  • 12
  • 109
  • 124
Yair Zaslavsky
  • 4,091
  • 4
  • 20
  • 27
0

I'm late to the party but this might help other people who find this question in a search.

Using cross-realm authentication is best but it's not always possible. E.g., you might be acting as a trusted third party to copy data from one organization to another and neither may be open to it.

The javax.security.auth.login.LoginContext class normally uses an external configuration file that is able to support multiple entries. It's a good approach if your devops supports it but there are many environments where it's not possible, e.g., if you're deployed as a .war file on an appserver. (Classic example: your application is autoscaling on an AWS elastic beanstalk.)

In our case we used the LoginContext constructor that takes a Configuration object. We have to maintain the necessary information ourselves but we can handle pretty much everything ourselves. (We can download and write our keytab file to a temporary directory and point to it in the Configuration object. Remember to nuke that file as your application exits!)

In this case it helps to remember is that a Configuration object is a bag and the AppConfigurationEntry is the information for a single service.

Edited to add: you may want to specify different credential cache file (ccache) locations in your options. I can't remember if the ccache files support more than one entry but it wouldn't hurt to specify different files.

bgiles
  • 1,200
  • 11
  • 12
0

In case it helps others:

You can specify which realms should be used for which domains in krb5.conf. Example:

[libdefaults]
  default_realm = A.COM

[realms]
  A.COM = {
    kdc = ...
  }
  B.COM = {
    kdc = ...
  }

[domain_realm]
  .b.com = B.COM

Then when you connect to *.b.com, it will use the B.COM realm instead of A.COM, and otherwise default to A.COM.

More here: https://web.mit.edu/kerberos/krb5-1.12/doc/admin/conf_files/krb5_conf.html#domain-realm

djozis
  • 69
  • 5