SonarQube LDAP Plugin StartTLS

2k views Asked by At

We're using SonarQube 5.6.6 with LDAP Plugin 2.2.0 to authenticate users against our Active Directory server. This is working fine for non-SSL/StartTLS connections.

I saw that with version 2.1 there is a new option available to enable StartTLS.

When I add the following line to my sonar.properties

ldap.StartTLS=true

I get the following exception in my log files:

2017.07.18 15:48:25 ERROR web[o.a.c.c.C.[.[.[/]] Exception sending context initialized event to listener instance of class org.sonar.server.platform.PlatformServletContextListener
org.sonar.plugins.ldap.LdapException: Unable to open LDAP connection
        at org.sonar.plugins.ldap.LdapContextFactory.testConnection(LdapContextFactory.java:211) ~[na:na]
        at org.sonar.plugins.ldap.LdapRealm.init(LdapRealm.java:63) ~[na:na]
        at org.sonar.server.user.SecurityRealmFactory.start(SecurityRealmFactory.java:84) ~[sonar-server-5.6.6.jar:na]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_77]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_77]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_77]
        at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_77]
        at org.picocontainer.lifecycle.ReflectionLifecycleStrategy.invokeMethod(ReflectionLifecycleStrategy.java:110) ~[picocontainer-2.15.jar:na]
        at org.picocontainer.lifecycle.ReflectionLifecycleStrategy.start(ReflectionLifecycleStrategy.java:89) ~[picocontainer-2.15.jar:na]
        at org.sonar.core.platform.ComponentContainer$1.start(ComponentContainer.java:320) ~[sonar-core-5.6.6.jar:na]
        at org.picocontainer.injectors.AbstractInjectionFactory$LifecycleAdapter.start(AbstractInjectionFactory.java:84) ~[picocontainer-2.15.jar:na]
        at org.picocontainer.behaviors.AbstractBehavior.start(AbstractBehavior.java:169) ~[picocontainer-2.15.jar:na]
        at org.picocontainer.behaviors.Stored$RealComponentLifecycle.start(Stored.java:132) ~[picocontainer-2.15.jar:na]
        at org.picocontainer.behaviors.Stored.start(Stored.java:110) ~[picocontainer-2.15.jar:na]
        at org.picocontainer.DefaultPicoContainer.potentiallyStartAdapter(DefaultPicoContainer.java:1016) ~[picocontainer-2.15.jar:na]
        at org.picocontainer.DefaultPicoContainer.startAdapters(DefaultPicoContainer.java:1009) ~[picocontainer-2.15.jar:na]
        at org.picocontainer.DefaultPicoContainer.start(DefaultPicoContainer.java:767) ~[picocontainer-2.15.jar:na]
        at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:141) ~[sonar-core-5.6.6.jar:na]
        at org.sonar.server.platform.platformlevel.PlatformLevel.start(PlatformLevel.java:84) ~[sonar-server-5.6.6.jar:na]
        at org.sonar.server.platform.platformlevel.PlatformLevel4.start(PlatformLevel4.java:655) ~[sonar-server-5.6.6.jar:na]
        at org.sonar.server.platform.Platform.start(Platform.java:216) ~[sonar-server-5.6.6.jar:na]
        at org.sonar.server.platform.Platform.startLevel34Containers(Platform.java:190) ~[sonar-server-5.6.6.jar:na]
        at org.sonar.server.platform.Platform.doStart(Platform.java:113) ~[sonar-server-5.6.6.jar:na]
        at org.sonar.server.platform.Platform.doStart(Platform.java:99) ~[sonar-server-5.6.6.jar:na]
        at org.sonar.server.platform.PlatformServletContextListener.contextInitialized(PlatformServletContextListener.java:44) ~[sonar-server-5.6.6.jar:na]
        at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4812) [tomcat-embed-core-8.0.32.jar:8.0.32]
        at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5255) [tomcat-embed-core-8.0.32.jar:8.0.32]
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147) [tomcat-embed-core-8.0.32.jar:8.0.32]
        at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408) [tomcat-embed-core-8.0.32.jar:8.0.32]
        at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398) [tomcat-embed-core-8.0.32.jar:8.0.32]
        at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_77]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_77]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_77]
        at java.lang.Thread.run(Thread.java:745) [na:1.8.0_77]
Caused by: javax.naming.NamingException: StartTLS failed
        at org.sonar.plugins.ldap.LdapContextFactory.createInitialDirContext(LdapContextFactory.java:124) ~[na:na]
        at org.sonar.plugins.ldap.LdapContextFactory.createBindContext(LdapContextFactory.java:96) ~[na:na]
        at org.sonar.plugins.ldap.LdapContextFactory.testConnection(LdapContextFactory.java:207) ~[na:na]
        ... 33 common frames omitted
Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at sun.security.ssl.Alerts.getSSLException(Alerts.java:192) ~[na:1.8.0_77]
        at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949) ~[na:1.8.0_77]
        at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302) ~[na:1.8.0_77]
        at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296) ~[na:1.8.0_77]
        at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1509) ~[na:1.8.0_77]
        at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216) ~[na:1.8.0_77]
        at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979) ~[na:1.8.0_77]
        at sun.security.ssl.Handshaker.process_record(Handshaker.java:914) ~[na:1.8.0_77]
        at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062) ~[na:1.8.0_77]
        at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375) ~[na:1.8.0_77]
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403) ~[na:1.8.0_77]
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387) ~[na:1.8.0_77]
        at com.sun.jndi.ldap.ext.StartTlsResponseImpl.startHandshake(StartTlsResponseImpl.java:353) ~[na:1.8.0_77]
        at com.sun.jndi.ldap.ext.StartTlsResponseImpl.negotiate(StartTlsResponseImpl.java:217) ~[na:1.8.0_77]
        at com.sun.jndi.ldap.ext.StartTlsResponseImpl.negotiate(StartTlsResponseImpl.java:170) ~[na:1.8.0_77]
        at org.sonar.plugins.ldap.LdapContextFactory.createInitialDirContext(LdapContextFactory.java:122) ~[na:na]
        ... 35 common frames omitted
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:387) ~[na:1.8.0_77]
        at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292) ~[na:1.8.0_77]
        at sun.security.validator.Validator.validate(Validator.java:260) ~[na:1.8.0_77]
        at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324) ~[na:1.8.0_77]
        at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229) ~[na:1.8.0_77]
        at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124) ~[na:1.8.0_77]
        at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1491) ~[na:1.8.0_77]
        ... 46 common frames omitted
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141) ~[na:1.8.0_77]
        at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126) ~[na:1.8.0_77]
        at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280) ~[na:1.8.0_77]
        at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:382) ~[na:1.8.0_77]
        ... 52 common frames omitted
2017.07.18 15:48:25 ERROR web[o.a.c.c.StandardContext] One or more listeners failed to start. Full details will be found in the appropriate container log file

I thought that I will probably have to provide a truststore, so I added

sonar.web.https.truststoreFile=/usr/local/sonarqube-5.6.6/conf/mycacert.jks
sonar.web.https.truststorePass=<password>
sonar.web.https.truststoreType=JKS

but I still get the same exception. (It seems that this option is for HTTPS connections anyway.)

So how do I configure LDAP+StartTLS correctly?

EDIT:

I've found the docker-compose.yml in the author's github repository. It seems like he's loading the LDAP's certificates by setting this environment variable:

SONARQUBE_WEB_JVM_OPTS=-Djavax.net.ssl.keyStore=/root/keystore -Djavax.net.ssl.keyStorePassword=changeit

I did the same with my keystore but with the same results as before. I tried exporting it in the sonar user's .profile as well as putting it in the sonar.properties file.

I found another post where someone got it working by loading the file as a trustStore instead of a keyStore. Again, I get the same exception as before regardless if I put it in the user's environment or the sonar.properties file.

Btw. this is how I created the keystore file:

keytool -importcert -noprompt -trustcacerts -alias <alias> -file <cert> -keystore /usr/local/sonarqube-5.6.6/conf/mycacert.jks -storepass <password>
1

There are 1 answers

0
raidlman On BEST ANSWER

If I understand this thread correctly, SONARQUBE_WEB_JVM_OPTS is not supported anymore in 5.6.6.

I got it working anyway by just adding the trust store to the following line in the sonar.properties file

sonar.web.javaAdditionalOpts=-Djavax.net.ssl.trustStore=/usr/local/sonarqube-5.6.6/conf/mycacert.jks