SonarQube LDAP 插件 StartTLS
SonarQube LDAP Plugin StartTLS
我们使用带有 LDAP 插件 2.2.0 的 SonarQube 5.6.6 根据我们的 Active Directory 服务器对用户进行身份验证。这对 non-SSL/StartTLS 连接工作正常。
我看到 2.1 版有一个新选项可用于启用 StartTLS。
当我将以下行添加到 sonar.properties
ldap.StartTLS=true
我的日志文件中出现以下异常:
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.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
我认为我可能必须提供一个信任库,所以我添加了
sonar.web.https.truststoreFile=/usr/local/sonarqube-5.6.6/conf/mycacert.jks
sonar.web.https.truststorePass=<password>
sonar.web.https.truststoreType=JKS
但我仍然遇到同样的异常。 (看来这个选项无论如何都是针对 HTTPS 连接的。)
那么如何正确配置LDAP+StartTLS呢?
编辑:
我在作者的 github repository 中找到了 docker-compose.yml
。看起来他正在通过设置这个环境变量来加载 LDAP 的证书:
SONARQUBE_WEB_JVM_OPTS=-Djavax.net.ssl.keyStore=/root/keystore -Djavax.net.ssl.keyStorePassword=changeit
我对我的密钥库做了同样的事情,但结果和以前一样。我尝试将其导出到 sonar
用户的 .profile
以及将其放入 sonar.properties
文件中。
我发现 another post 有人通过将文件加载为 trustStore
而不是 keyStore
来使它工作。同样,无论我将它放在用户环境还是 sonar.properties
文件中,我都会遇到与以前相同的异常。
顺便说一句。这就是我创建密钥库文件的方式:
keytool -importcert -noprompt -trustcacerts -alias <alias> -file <cert> -keystore /usr/local/sonarqube-5.6.6/conf/mycacert.jks -storepass <password>
如果我理解 this thread 正确,5.6.6 不再支持 SONARQUBE_WEB_JVM_OPTS
。
通过将信任库添加到 sonar.properties
文件
中的以下行,我还是让它工作了
sonar.web.javaAdditionalOpts=-Djavax.net.ssl.trustStore=/usr/local/sonarqube-5.6.6/conf/mycacert.jks
我们使用带有 LDAP 插件 2.2.0 的 SonarQube 5.6.6 根据我们的 Active Directory 服务器对用户进行身份验证。这对 non-SSL/StartTLS 连接工作正常。
我看到 2.1 版有一个新选项可用于启用 StartTLS。
当我将以下行添加到 sonar.properties
ldap.StartTLS=true
我的日志文件中出现以下异常:
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.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
我认为我可能必须提供一个信任库,所以我添加了
sonar.web.https.truststoreFile=/usr/local/sonarqube-5.6.6/conf/mycacert.jks
sonar.web.https.truststorePass=<password>
sonar.web.https.truststoreType=JKS
但我仍然遇到同样的异常。 (看来这个选项无论如何都是针对 HTTPS 连接的。)
那么如何正确配置LDAP+StartTLS呢?
编辑:
我在作者的 github repository 中找到了 docker-compose.yml
。看起来他正在通过设置这个环境变量来加载 LDAP 的证书:
SONARQUBE_WEB_JVM_OPTS=-Djavax.net.ssl.keyStore=/root/keystore -Djavax.net.ssl.keyStorePassword=changeit
我对我的密钥库做了同样的事情,但结果和以前一样。我尝试将其导出到 sonar
用户的 .profile
以及将其放入 sonar.properties
文件中。
我发现 another post 有人通过将文件加载为 trustStore
而不是 keyStore
来使它工作。同样,无论我将它放在用户环境还是 sonar.properties
文件中,我都会遇到与以前相同的异常。
顺便说一句。这就是我创建密钥库文件的方式:
keytool -importcert -noprompt -trustcacerts -alias <alias> -file <cert> -keystore /usr/local/sonarqube-5.6.6/conf/mycacert.jks -storepass <password>
如果我理解 this thread 正确,5.6.6 不再支持 SONARQUBE_WEB_JVM_OPTS
。
通过将信任库添加到 sonar.properties
文件
sonar.web.javaAdditionalOpts=-Djavax.net.ssl.trustStore=/usr/local/sonarqube-5.6.6/conf/mycacert.jks