Uploaded image for project: 'Hadoop Common'
  1. Hadoop Common
  2. HADOOP-16245

Enabling SSL within LdapGroupsMapping can break system SSL configs

    XMLWordPrintableJSON

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 2.9.1, 2.8.4, 2.7.6, 3.1.1, 3.0.3
    • Fix Version/s: 2.10.0, 3.0.4, 3.3.0, 3.2.1, 3.1.3
    • Component/s: common, security
    • Labels:
      None
    • Target Version/s:

      Description

      When debugging an issue where one of our server components was unable to communicate with other components via SSL, we realized that LdapGroupsMapping sets its SSL configurations globally, rather than scoping them to the HTTP clients it creates.

      LdapGroupsMapping
        DirContext getDirContext() throws NamingException {
          if (ctx == null) {
            // Set up the initial environment for LDAP connectivity
            Hashtable<String, String> env = new Hashtable<String, String>();
            env.put(Context.INITIAL_CONTEXT_FACTORY,
                com.sun.jndi.ldap.LdapCtxFactory.class.getName());
            env.put(Context.PROVIDER_URL, ldapUrl);
            env.put(Context.SECURITY_AUTHENTICATION, "simple");
      
            // Set up SSL security, if necessary
            if (useSsl) {
              env.put(Context.SECURITY_PROTOCOL, "ssl");
              if (!keystore.isEmpty()) {
                System.setProperty("javax.net.ssl.keyStore", keystore);
              }
              if (!keystorePass.isEmpty()) {
                System.setProperty("javax.net.ssl.keyStorePassword", keystorePass);
              }
              if (!truststore.isEmpty()) {
                System.setProperty("javax.net.ssl.trustStore", truststore);
              }
              if (!truststorePass.isEmpty()) {
                System.setProperty("javax.net.ssl.trustStorePassword",
                    truststorePass);
              }
            }
      
            env.put(Context.SECURITY_PRINCIPAL, bindUser);
            env.put(Context.SECURITY_CREDENTIALS, bindPassword);
      
            env.put("com.sun.jndi.ldap.connect.timeout", conf.get(CONNECTION_TIMEOUT,
                String.valueOf(CONNECTION_TIMEOUT_DEFAULT)));
            env.put("com.sun.jndi.ldap.read.timeout", conf.get(READ_TIMEOUT,
                String.valueOf(READ_TIMEOUT_DEFAULT)));
      
            ctx = new InitialDirContext(env);
          }
      

      Notice the System.setProperty() calls, which will change settings JVM-wide. This causes issues for other SSL clients, which may rely on the default JVM truststore being used. This behavior was initially introduced by HADOOP-8121, and extended to include the truststore configurations in HADOOP-12862.

      The correct approach is to use a mechanism which is scoped to the LDAP requests only. The right approach appears to be to use the java.naming.ldap.factory.socket parameter to set the socket factory to a custom SSL socket factory which correctly sets the key and trust store parameters. See an example here.

        Attachments

        1. HADOOP-16245.004.patch
          9 kB
          Erik Krogen
        2. HADOOP-16245.003.patch
          9 kB
          Erik Krogen
        3. HADOOP-16245.002.patch
          7 kB
          Erik Krogen
        4. HADOOP-16245.001.patch
          7 kB
          Erik Krogen
        5. HADOOP-16245.000.patch
          6 kB
          Erik Krogen

          Issue Links

            Activity

              People

              • Assignee:
                xkrogen Erik Krogen
                Reporter:
                xkrogen Erik Krogen
              • Votes:
                0 Vote for this issue
                Watchers:
                7 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: