ALM Integration for Gitlab does't work

I’m trying to integrate SonarQube Developer Edition v.8.9.1 to Gitlab.
SonarQube is startet as docker image with docker-compose configuration.

I follow the steps from the documentation: GitLab Integration | SonarQube Docs
As far as I go to the step “Importing your GitLab projects into SonarQube” and configure “Setting your global settings” with gitlab-api-URL and my personal access token, I get an error:
Could not validate GitLab url. Got an unexpected answer.

As I can see in console of SonarQube program, there is a reason of it:
Gitlab API call to [https://dev-platform.coremannet.app/api/v4/projects] failed with error message : [Remote host terminated the handshake]

I can check this request in Postman program (REST Client testing tool) with my access token successfully.

Why the SonarQube cannot request the same URL endpoint with correct access token?
How can I solve the problem?
Please help!

The full error message of SonarQube on console:

sonarqube_1  | 2021.06.23 10:59:46 INFO  web[AXo4HKovhdy4HAHJAAXd][o.s.a.c.g.GitlabHttpClient] Gitlab API call to [https://dev-platform.coremannet.app/api/v4/projects] failed with error message : [Remote host terminated the handshake]
sonarqube_1  | javax.net.ssl.SSLHandshakeException: Remote host terminated the handshake
sonarqube_1  | 	at java.base/sun.security.ssl.SSLSocketImpl.handleEOF(Unknown Source)
sonarqube_1  | 	at java.base/sun.security.ssl.SSLSocketImpl.decode(Unknown Source)
sonarqube_1  | 	at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(Unknown Source)
sonarqube_1  | 	at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
sonarqube_1  | 	at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
sonarqube_1  | 	at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.kt:379)
sonarqube_1  | 	at okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.kt:337)
sonarqube_1  | 	at okhttp3.internal.connection.RealConnection.connect(RealConnection.kt:209)
sonarqube_1  | 	at okhttp3.internal.connection.ExchangeFinder.findConnection(ExchangeFinder.kt:226)
sonarqube_1  | 	at okhttp3.internal.connection.ExchangeFinder.findHealthyConnection(ExchangeFinder.kt:106)
sonarqube_1  | 	at okhttp3.internal.connection.ExchangeFinder.find(ExchangeFinder.kt:74)
sonarqube_1  | 	at okhttp3.internal.connection.RealCall.initExchange$okhttp(RealCall.kt:255)
sonarqube_1  | 	at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:32)
sonarqube_1  | 	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
sonarqube_1  | 	at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:95)
sonarqube_1  | 	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
sonarqube_1  | 	at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:83)
sonarqube_1  | 	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
sonarqube_1  | 	at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:76)
sonarqube_1  | 	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
sonarqube_1  | 	at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.kt:201)
sonarqube_1  | 	at okhttp3.internal.connection.RealCall.execute(RealCall.kt:154)
sonarqube_1  | 	at org.sonar.alm.client.gitlab.GitlabHttpClient.checkProjectAccess(GitlabHttpClient.java:84)
sonarqube_1  | 	at org.sonar.alm.client.gitlab.GitlabHttpClient.checkUrl(GitlabHttpClient.java:67)
sonarqube_1  | 	at org.sonar.server.almsettings.ws.ValidateAction.validateGitlab(ValidateAction.java:121)
sonarqube_1  | 	at org.sonar.server.almsettings.ws.ValidateAction.doHandle(ValidateAction.java:94)
sonarqube_1  | 	at org.sonar.server.almsettings.ws.ValidateAction.handle(ValidateAction.java:83)
sonarqube_1  | 	at org.sonar.server.ws.WebServiceEngine.execute(WebServiceEngine.java:110)
sonarqube_1  | 	at org.sonar.server.platform.web.WebServiceFilter.doFilter(WebServiceFilter.java:84)
sonarqube_1  | 	at org.sonar.server.platform.web.MasterServletFilter$GodFilterChain.doFilter(MasterServletFilter.java:139)
sonarqube_1  | 	at org.sonar.server.platform.web.SonarLintConnectionFilter.doFilter(SonarLintConnectionFilter.java:66)
sonarqube_1  | 	at org.sonar.server.platform.web.MasterServletFilter$GodFilterChain.doFilter(MasterServletFilter.java:139)
sonarqube_1  | 	at org.sonar.server.platform.web.MasterServletFilter.doFilter(MasterServletFilter.java:108)
sonarqube_1  | 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
sonarqube_1  | 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
sonarqube_1  | 	at org.sonar.server.platform.web.UserSessionFilter.doFilter(UserSessionFilter.java:81)
sonarqube_1  | 	at org.sonar.server.platform.web.UserSessionFilter.doFilter(UserSessionFilter.java:68)
sonarqube_1  | 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
sonarqube_1  | 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
sonarqube_1  | 	at org.sonar.server.platform.web.CacheControlFilter.doFilter(CacheControlFilter.java:76)
sonarqube_1  | 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
sonarqube_1  | 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
sonarqube_1  | 	at org.sonar.server.platform.web.SecurityServletFilter.doHttpFilter(SecurityServletFilter.java:76)
sonarqube_1  | 	at org.sonar.server.platform.web.SecurityServletFilter.doFilter(SecurityServletFilter.java:48)
sonarqube_1  | 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
sonarqube_1  | 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
sonarqube_1  | 	at org.sonar.server.platform.web.RedirectFilter.doFilter(RedirectFilter.java:58)
sonarqube_1  | 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
sonarqube_1  | 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
sonarqube_1  | 	at org.sonar.server.platform.web.RequestIdFilter.doFilter(RequestIdFilter.java:66)
sonarqube_1  | 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
sonarqube_1  | 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
sonarqube_1  | 	at org.sonar.server.platform.web.RootFilter.doFilter(RootFilter.java:62)
sonarqube_1  | 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
sonarqube_1  | 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
sonarqube_1  | 	at org.apache.catalina.filters.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:109)
sonarqube_1  | 	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
sonarqube_1  | 	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
sonarqube_1  | 	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
sonarqube_1  | 	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
sonarqube_1  | 	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:544)
sonarqube_1  | 	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)
sonarqube_1  | 	at ch.qos.logback.access.tomcat.LogbackValve.invoke(LogbackValve.java:256)
sonarqube_1  | 	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
sonarqube_1  | 	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
sonarqube_1  | 	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:353)
sonarqube_1  | 	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:616)
sonarqube_1  | 	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
sonarqube_1  | 	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:831)
sonarqube_1  | 	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1629)
sonarqube_1  | 	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
sonarqube_1  | 	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
sonarqube_1  | 	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
sonarqube_1  | 	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
sonarqube_1  | 	at java.base/java.lang.Thread.run(Unknown Source)
sonarqube_1  | Caused by: java.io.EOFException: SSL peer shut down incorrectly
sonarqube_1  | 	at java.base/sun.security.ssl.SSLSocketInputRecord.read(Unknown Source)
sonarqube_1  | 	at java.base/sun.security.ssl.SSLSocketInputRecord.readHeader(Unknown Source)
sonarqube_1  | 	at java.base/sun.security.ssl.SSLSocketInputRecord.decode(Unknown Source)
sonarqube_1  | 	at java.base/sun.security.ssl.SSLTransport.decode(Unknown Source)
sonarqube_1  | 	... 74 common frames omitted

Hi, depending on the JVM you use, the SSL certificate could be considered invalid. Did you try to add your SSL certificate to the web process Keystore?

Hi, I have not added any certificates yet.
As I already mentioned the SonarQube is running in docker container, based on docker image “sonarqube:8.9.1-developer”. As I can see on docker hub, there is java 11 on board:
https://hub.docker.com/layers/sonarquBe/library/sonarqube/8.9.1-developer/images/sha256-1bcba9cf46447da41b915a40ebbf9ebb72f41a423c164a41399326bc69c2ec79?context=explore

Where can I read a documentation, how to configure completely to setup Gitlab Integration? Unfortunately I cannot find the part about a SSL certificate within the GitLab Integration | SonarQube Docs, where I expected to find it.
Could you help me to clarify the configuration for it?

Hi, you could extend the docker image to add your certificate to the cacerts keystore.
In your case, I think the SSL certificate is rejected because it does not contain an accurate Subject Alternative Name with the full qualified name.

Hi, it is not working for me unfortunately.
I have processed the following steps:

  1. created new dockerfile
FROM sonarqube:8.9.1-developer

COPY sonar_ssl.cert /tmp/

RUN keytool -import -v -trustcacerts -alias sonarqube -file /tmp/sonar_ssl.cert  \
    -keystore ${JAVA_HOME}/lib/security/cacerts -noprompt -storepass changeit
  1. Started docker-compose with new docker image
  2. Checked ALM Integration for Gitlab

The problem is still the same as I described above.

Could I become a technical support to evaluate the sonar in our system and to integrate it with Gitlab?
Without it our company will not buy a sonar license.

Hi @zaburunov
I’m updating this thread in order for it to possibly benefit other users with a similar pb.

You’ve finally worked around your TLS connectivity problem by temporarily disabling the CRL/OCSP checks with the -Dcom.sun.net.ssl.checkRevocation=false parameter added to the SONAR_WEB_JAVAADDITIONALOPTS and SONAR_CE_JAVAADDITIONALOPTS environment variables for your SonarQube docker instance.

This gives you some time to check with your colleagues from the network team how to allow requests to your certificate authority CRL and OCSP addresses.