Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8239385

Support the 'canonicalize' setting (krb5.conf) in the Kerberos client

XMLWordPrintable

    • b22
    • x86_64
    • linux_ubuntu
    • Not verified

        As described in the CSR [JDK-8241871], the Kerberos client does not currently support the 'canonicalize' setting in the configuration file (krb5.conf). As a result, Name Canonicalization behavior (described by RFC 6806) cannot be customized: the client will claim support for it in every TGT request if sun.security.krb5.disableReferrals is false, and the KDC service may change the client name. Even though this is RFC-compliant, it can be unexpected for some clients as we can see in the report below:

        ---------------------------------------------------------

        ADDITIONAL SYSTEM INFORMATION :
        $ cat /etc/lsb-release
        DISTRIB_ID=Ubuntu
        DISTRIB_RELEASE=18.04
        DISTRIB_CODENAME=bionic
        DISTRIB_DESCRIPTION="Ubuntu 18.04.4 LTS"

        $ java -version
        openjdk version "1.8.0_242"
        OpenJDK Runtime Environment (build 1.8.0_242-8u242-b08-0ubuntu3~18.04-b08)
        OpenJDK 64-Bit Server VM (build 25.242-b08, mixed mode)

        A DESCRIPTION OF THE PROBLEM :
        With 1.8.0_242 "client:" refers to the sAMAccountName of the object in AD, with 1.8.0_232 it used to refer to the servicePrincipalName (which is now "client alias:")

        >>> DEBUG: ----Credentials----
               client: $V9H200-TAD2F4IK2G09@EXAMPLE.COM
               client alias: kafka/fqdn.example.com@EXAMPLE.COM
               server: zookeeper/fqdn.example.com@EXAMPLE.COM
               ticket: sname: zookeeper/fqdn.example.com@EXAMPLE.COM
               startTime: 1580465010000
               endTime: 1580501010000
               ----Credentials end----

        So in some way with 1.8.0_232 zookeeper authenticated kafka/fqdn.example.com@EXAMPLE.COM while with 1.8.0_242 it is $V9H200-TAD2F4IK2G09@EXAMPLE.COM which leads to ACL problems in zookeeper.

        REGRESSION : Last worked in version 8

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        # This is what we have:

        user@host:~/work$ ls -al
        total 20
        drwxrwx--- 2 user user 4096 Feb 14 17:33 .
        drwxr-xr-x 5 user user 4096 Feb 14 17:29 ..
        -rw-rw---- 1 user user 942 Feb 14 17:29 KerberosDemo.java
        -rw-rw---- 1 user user 101 Feb 13 13:13 jaas_cached.conf
        -rw-rw---- 1 user user 276 Feb 13 13:24 jaas_keytab.conf


        # it's a minimal example

        user@host:~/work$ cat KerberosDemo.java
        import javax.security.auth.login.*;
        import java.util.Iterator;
        import java.util.Set;
        import javax.security.auth.Subject;
        import javax.security.auth.kerberos.KerberosTicket;

        public class KerberosDemo {
                public static void main (String[] args) {
                        LoginContext loginContext = null;
                        try {
                                loginContext = new LoginContext("Demo");
                        }
                        catch (LoginException e) {
                                System.err.println("login context creation failed: "+e.getMessage());
                                System.exit(1);
                        }
                        try {
                                loginContext.login();
                        }
                        catch (LoginException e) {
                                System.out.println("authentication failed");
                                System.exit(1);
                        }
                        Subject subject = loginContext.getSubject();
                        System.out.println("Authenticated principal: " + subject.getPrincipals());
                        Set credentials = subject.getPrivateCredentials();
                        Iterator iterator = credentials.iterator();
                        KerberosTicket kt = (KerberosTicket) iterator.next();
                        System.out.println("Client name: " + kt.getClient());
                }
        }


        # let's compile it

        user@host:~/work$ javac KerberosDemo.java


        # and use it either with a keytab (JAAS is getting the ticket) ...

        user@host:~/work$ cat jaas_keytab.conf # use keytab!
        Demo {
            com.sun.security.auth.module.Krb5LoginModule required
            useKeyTab=true
            keyTab="/etc/security/keytabs/myprincipal.service.keytab"
            storeKey=true
            useTicketCache=false
            serviceName="serviceprincipal"
            principal="myprincipal/fqdn.example.com@EXAMPLE.COM";
        };


        # ... or with a ticket gotten earlier by MIT Kerberos client (kinit)

        user@host:~/work$ cat jaas_cached.conf # use cached!
        Demo {
            com.sun.security.auth.module.Krb5LoginModule required
            useKeyTab=false
            useTicketCache=true;
        };


        # this is how the ticket was placed in the cache

        user@host:~/work$ kinit -kt /etc/security/keytabs/myprincipal.service.keytab myprincipal/fqdn.example.com@EXAMPLE.COM


        # now, this is what happens with OpenJDK 1.8.0_232
        # principal name and client name all refer to myprincipal/fqdn.example.com@EXAMPLE.COM (in AD, this is the servicePrincipalName):

        user@host:~/work$ java -version
        openjdk version "1.8.0_232"
        OpenJDK Runtime Environment (build 1.8.0_232-8u232-b09-0ubuntu1~18.04.1-b09)
        OpenJDK 64-Bit Server VM (build 25.232-b09, mixed mode)
        user@host:~/work$ java -Djava.security.auth.login.config=jaas_keytab.conf KerberosDemo
        Authenticated principal: [myprincipal/fqdn.example.com@EXAMPLE.COM]
        Client name: myprincipal/fqdn.example.com@EXAMPLE.COM
        user@host:~/work$ java -Djava.security.auth.login.config=jaas_cached.conf KerberosDemo
        Authenticated principal: [myprincipal/fqdn.example.com@EXAMPLE.COM]
        Client name: myprincipal/fqdn.example.com@EXAMPLE.COM


        # while this is what we see with OpenJDK 1.8.0_242
        # while for the cached ticket the results are the same, for the ticket gotten by JAAS the names differ!!!
        # Note: $V9H200-TAD2F4IK2G09 is the sAMAccountName of the AD user with servicePrincipalName myprincipal/fqdn.example.com@EXAMPLE.COM

        user@host:~/work$ java -version
        openjdk version "1.8.0_242"
        OpenJDK Runtime Environment (build 1.8.0_242-8u242-b08-0ubuntu3~18.04-b08)
        OpenJDK 64-Bit Server VM (build 25.242-b08, mixed mode)
        user@host:~/work$ java -Djava.security.auth.login.config=jaas_keytab.conf KerberosDemo
        Authenticated principal: [myprincipal/fqdn.example.com@EXAMPLE.COM]
        Client name: $V9H200-TAD2F4IK2G09@EXAMPLE.COM
        user@host:~/work$ java -Djava.security.auth.login.config=jaas_cached.conf KerberosDemo
        Authenticated principal: [myprincipal/fqdn.example.com@EXAMPLE.COM]
        Client name: myprincipal/fqdn.example.com@EXAMPLE.COM

        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        1.8.0_232 should behave the same as 1.8.0_242 so we can still run kafka/zookeeper.
        ACTUAL -
        When debugging Krb5 in Kafka/Zookeeper using OpenJDK 1.8.0_242 (this is where this bug hit me in the first place), the differing parts show up like this:

        >>> DEBUG: ----Credentials----
               client: $V9H200-TAD2F4IK2G09@EXAMPLE.COM
               client alias: kafka/fqdn.example.com@EXAMPLE.COM
               server: zookeeper/fqdn.example.com@EXAMPLE.COM
               ticket: sname: zookeeper/fqdn.example.com@EXAMPLE.COM
               startTime: 1580465010000
               endTime: 1580501010000
               ----Credentials end----

        So in some way with 1.8.0_232 zookeeper authenticated kafka/fqdn.example.com@EXAMPLE.COM while with 1.8.0_242 it is $V9H200-TAD2F4IK2G09@EXAMPLE.COM which leads to ACL problems in zookeeper.

        ---------- BEGIN SOURCE ----------
        import javax.security.auth.login.*;
        import java.util.Iterator;
        import java.util.Set;
        import javax.security.auth.Subject;
        import javax.security.auth.kerberos.KerberosTicket;

        public class KerberosDemo {
                public static void main (String[] args) {
                        LoginContext loginContext = null;
                        try {
                                loginContext = new LoginContext("Demo");
                        }
                        catch (LoginException e) {
                                System.err.println("login context creation failed: "+e.getMessage());
                                System.exit(1);
                        }
                        try {
                                loginContext.login();
                        }
                        catch (LoginException e) {
                                System.out.println("authentication failed");
                                System.exit(1);
                        }
                        Subject subject = loginContext.getSubject();
                        System.out.println("Authenticated principal: " + subject.getPrincipals());
                        Set credentials = subject.getPrivateCredentials();
                        Iterator iterator = credentials.iterator();
                        KerberosTicket kt = (KerberosTicket) iterator.next();
                        System.out.println("Client name: " + kt.getClient());
                }
        }
        ---------- END SOURCE ----------

        CUSTOMER SUBMITTED WORKAROUND :
        There are two workarounds:

        1. Changing the JAAS config to use a ticket in the ticket cache created upfront using kinit. However this workaround can't be used in automated environments where clients authenticate themselves using keytabs.

        2. Downgrade from OpenJDK 8 Update 242 to Update 232. Using the same configuration, the principal is authenticated as kafka/fqdn.example.com@EXAMPLE.COM. However, downgrading a package can only be a temporary solution.

        FREQUENCY : always


              mbalao Martin Balao Alonso
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              8 Start watching this issue

                Created:
                Updated:
                Resolved: