[ https://issues.apache.org/jira/browse/HADOOP-16245?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16819245#comment-16819245 ]
Erik Krogen commented on HADOOP-16245: -------------------------------------- I agree that storing the values in a static class is not ideal, but I was unable to find any other way. Looking at the definition of [{{SocketFactory}}|https://docs.oracle.com/javase/8/docs/api/index.html?javax/net/SocketFactory.html], I don't see any possible way for JNDI to pass in a context. I also couldn't find any examples that did anything better than what I'm doing here. But if anyone has ideas, please chime in. I think in this case it's safe to use the static configurations, given that the only place in which {{LdapGroupsMappingService}} is used is from the context of {{Groups}}, which is a singleton (stored in the static field {{Groups#GROUPS}}). Even if you call {{getUserToGroupsMappingService()}} with a new {{Configuration}}, in which case you might expect it to construct a new {{Groups}}, it simply returns the old one. > Enabling SSL within LdapGroupsMapping can break system SSL configs > ------------------------------------------------------------------ > > Key: HADOOP-16245 > URL: https://issues.apache.org/jira/browse/HADOOP-16245 > Project: Hadoop Common > Issue Type: Bug > Components: common, security > Affects Versions: 2.9.1, 2.8.4, 2.7.6, 3.1.1, 3.0.3 > Reporter: Erik Krogen > Assignee: Erik Krogen > Priority: Major > Attachments: HADOOP-16245.000.patch > > > 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. > {code:title=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); > } > {code} > 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|https://stackoverflow.com/a/4615497/4979203]. -- This message was sent by Atlassian JIRA (v7.6.3#76005) --------------------------------------------------------------------- To unsubscribe, e-mail: common-issues-unsubscr...@hadoop.apache.org For additional commands, e-mail: common-issues-h...@hadoop.apache.org