Sonar-scanner fails with self-signed certificate

We’re using Sonar-Scanner 3.3.0.1492 with OpenJDK 1.8.0_212.

I’ve configured SonarQube (7.5) behind an AWS Loadbalancer to redirect http to https using a self signed Certificate (without an own or valid CA).

I have imported the crt file into the JVM Cacerts and also created a jks file containing the certificate.

No matter how I try, I alway get the following error:

INFO: SonarQube Scanner 3.3.0.1492
INFO: Java 1.8.0_212 Oracle Corporation (64-bit)
INFO: Linux 4.15.0-1032-aws amd64
INFO: SONAR_SCANNER_OPTS=-Djavax.net.ssl.trustStore=/var/jenkins_home/my.subdomain.cloud.jks -Djavax.net.ssl.trustStorePassword=changeit
DEBUG: keyStore is :
DEBUG: keyStore type is : jks
DEBUG: keyStore provider is :
DEBUG: init keystore
DEBUG: init keymanager of type SunX509
DEBUG: Create: /var/jenkins_home/.sonar/cache
INFO: User cache: /var/jenkins_home/.sonar/cache
DEBUG: Create: /var/jenkins_home/.sonar/cache/_tmp
DEBUG: Extract sonar-scanner-api-batch in temp...
DEBUG: Get bootstrap index...
DEBUG: Download: https://my.subdomain.cloud/batch/index
ERROR: SonarQube server [https://my.subdomain.cloud] can not be reached
INFO: ------------------------------------------------------------------------
INFO: EXECUTION FAILURE
INFO: ------------------------------------------------------------------------
INFO: Total time: 0.319s
INFO: Final Memory: 5M/477M
INFO: ------------------------------------------------------------------------
ERROR: Error during SonarQube Scanner execution
org.sonarsource.scanner.api.internal.ScannerException: Unable to execute SonarQube
 at org.sonarsource.scanner.api.internal.IsolatedLauncherFactory.lambda$createLauncher$0(IsolatedLauncherFactory.java:85)
 at java.security.AccessController.doPrivileged(Native Method)
 at org.sonarsource.scanner.api.internal.IsolatedLauncherFactory.createLauncher(IsolatedLauncherFactory.java:74)
 at org.sonarsource.scanner.api.internal.IsolatedLauncherFactory.createLauncher(IsolatedLauncherFactory.java:70)
 at org.sonarsource.scanner.api.EmbeddedScanner.doStart(EmbeddedScanner.java:181)
 at org.sonarsource.scanner.api.EmbeddedScanner.start(EmbeddedScanner.java:122)
 at org.sonarsource.scanner.cli.Main.execute(Main.java:73)
 at org.sonarsource.scanner.cli.Main.main(Main.java:61)
Caused by: java.lang.IllegalStateException: Fail to get bootstrap index from server
 at org.sonarsource.scanner.api.internal.BootstrapIndexDownloader.getIndex(BootstrapIndexDownloader.java:42)
 at org.sonarsource.scanner.api.internal.JarDownloader.getScannerEngineFiles(JarDownloader.java:58)
 at org.sonarsource.scanner.api.internal.JarDownloader.download(JarDownloader.java:53)
 at org.sonarsource.scanner.api.internal.IsolatedLauncherFactory.lambda$createLauncher$0(IsolatedLauncherFactory.java:76)
 ... 7 more
Caused by: javax.net.ssl.SSLPeerUnverifiedException: Hostname my.subdomain.cloud not verified:
    certificate: sha256/6h6rxxxxxxxxxxxxxxxxxxxxxxxxGB/y/hxxxxxxxxx=
    DN: EMAILADDRESS=me@work.com, CN=my.subdomain.cloud, OU=myOrgUnit, O=MyCompany, L=MyCity, ST=MyDistrict, C=AT
    subjectAltNames: []
 at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.connection.RealConnection.connectTls(RealConnection.java:329)
 at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.connection.RealConnection.establishProtocol(RealConnection.java:282)
 at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.connection.RealConnection.connect(RealConnection.java:167)
 at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:257)
 at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:135)
 at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.connection.StreamAllocation.newStream(StreamAllocation.java:114)
 at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42)
 at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
 at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
 at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
 at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
 at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
 at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
 at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
 at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:126)
 at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
 at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
 at org.sonarsource.scanner.api.internal.shaded.okhttp.RealCall.getResponseWithInterceptorChain(RealCall.java:200)
 at org.sonarsource.scanner.api.internal.shaded.okhttp.RealCall.execute(RealCall.java:77)
 at org.sonarsource.scanner.api.internal.ServerConnection.callUrl(ServerConnection.java:113)
 at org.sonarsource.scanner.api.internal.ServerConnection.downloadString(ServerConnection.java:98)
 at org.sonarsource.scanner.api.internal.BootstrapIndexDownloader.getIndex(BootstrapIndexDownloader.java:39)
 ... 10 more    

The certificate is definitely correct and also the JKS was created correct as I tried a

curl --cacert my.subdomain.cloud.crt https://my.subdomain.cloud

and have even written a small Java Class, which requests https://my.subdomain.cloud using the JKS File. Both work without any problems.

The JKS File is also taken correct from sonar-scanner as I tried to provide an invalid password or invalid JKS Location which leads into the following error:

Non-Existing JKS File:

Caused by: java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty

Invalid JKS password:

java.lang.AssertionError: java.security.KeyStoreException: problem accessing trust storejava.io.IOException: Keystore was tampered with, or password was incorrect

I also tried to use the command line parameters -Djavax.net.ssl.trustStore and -Djavax.net.ssl.trustStorePassword instead of the SONAR_SCANNER_OPTS (and both) without any effect.

Changing to another scanner (Gradle, Maven) is currently no option.

Any help woud be appreciated

Thanks,
Christoph

1 Like

From my experience sonar-scanner has a bundled jre (and i don’t know why)
So you have to install you cert in that bundled java truststore. (been there too)
sonarscanner/sonar-scanner-3.2.0.1227-linux/jre/lib/security/cacerts

Hi @andgru ,

thx for response.
I use the “sonarqube scanner” Tool from Jenkins which does not have it’s own JRE.
Nevertheless I found out, that it uses okhttp API which needs a separate implementation for self signed certificates which I guess was not implemented.

If you need OkHttpClient to accept self signed SSL, you need to pass it custom javax.net.ssl.SSLSocketFactory instance via setSslSocketFactory(SSLSocketFactory sslSocketFactory) method. → java - Does OkHttp support accepting self-signed SSL certs? - Stack Overflow

1 Like

Hi,

I am having the same problem and also managed to import the certificate into the keystore - So it works :slight_smile: . However my feeling is that this is s pretty complicated thing and not very handy.

So what to you think about adding a flag to the sonarcube client (–ignore-ssl-error) to ignore SSL errors. For my use case, where we are using sonarcube only internal with self signed certificates but not want to miss encryption such a flag would be nice to have. What do you think?

1 Like

Hi,

(edit) Some distributions of sonar-scanner have a bundled JRE. The reasons behind it can be found here: https://jira.sonarsource.com/browse/MMF-779

In the past we had an option to bypass checking the server certificate. This was dropped at one point since it’s an obvious security vulnerability. We have no plans to bring that option back.
The correct way is indeed to install the server’s certificate in the truststore if needed and if the server is authenticating the client by checking it’s certificate, it needs to be imported into the keystore.
This is not simple but the sonar-scanner relies on the standard mechanism in Java.

1 Like

Are you sure? You have OS-specific downloads with a bundled JRE… :wink:

https://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner

You’re right, I’ll correct my post, thanks.

Update: I fixed this issue by adding SAN to the self signed Certificate.

That’s definitely the stupidest thing I’ve read today after wasting 2 days trying to get it work…
Like the alternatives would be really better. Especially when using sonar-scanner in docker container where you have absolutely no rights to change sonar-scanner truststore…
It should be up to users how they wan’t to connect to the sonar server. Especially the option to bind external trust store with javax.net.ssl.trustStore was useful. Pretty legit solution. Now only option is to unsecure the route and use plain http. As requesting the certificate for development purposes in this case makes no sense.

4 Likes

This forum is a place for polite and constructive community discussions. The FAQ is at your disposal for guidelines on how to behave on this forum. Please feel free to review them, and consider this a warning.

Best regards,

Colin

3 Likes