Get sonar-scanner-cli-docker to work with self-signed cert SonarQube server

Jan 29, 2020Docker, SonarQubehttps://git.io/JvE05

sonar-scanner-cli-docker contains the Dockerfile to download sonar-scanner-cli jar file bundled with minimal JRE executables and perform tasks such as setting the user permission and installing extra dependencies.

When the SonarQube server is deployed with self-signed SSL certificate, the sonar-scanner has to trust the root CA in order to connect to the server by setting the javax.net.ssl.trustStore option.

The trust store here can be a key store created by the Java keytool, but the sonar-scanner-cli bundled JRE doesn't include keytool. So one solution can be locally preparing the key store and mount the key store file to the sonar-scanner-cli-docker. However, the sonar-scanner-cli is actually running with a non-root user in the docker container (UID 1000), so if the source code to be scanned is created by root user the sonar-scanner-cli is not able to create the temporary caching directory when running.

Previously I came up with a workaround by forking the sonar-scanner-cli-docker and change the base image to openjdk JRE, as I mentioned in the comment. But it's not a good one since the docker image is not official and hard to keep it up to date.

So here's another solution with the help of openjdk docker image and instead of preparing the key store locally, we can encode the root CA and pass through environment variable instead to make it easier to run sonar-scanner in CI. And one side product of this approach is the root CA can be reused by other tasks if they need to connect to services that are signed with the same root CA.

Step 1

Export the root CA to PEM format and base 64 encode it:

cat root-ca.pem | base64

Step 2

Add a prepare step before sonar-scanner-cli-docker, here I'm using pseudo (the correct format for command is a single string) docker-compose syntax as an example, you can change to any CI job or pipeline definition according to it.

sonar_prepare:
  image: openjdk:11-jre-stretch
  environment:
    SONAR_ROOT_CA: $ROOT_CA
  command:
    - echo $SONAR_ROOT_CA | base64 -d | keytool -import -noprompt -trustcacerts -alias sonarqube -storepass changeit -keystore sonarqube.jks
    - mkdir .scannerwork && chown 1000 .scannerwork

The image is a JRE docker image based on the same Java and Linux version with sonar-scanner-cli. The $ROOT_CA is the base64 encoded root CA from the first step. The first command line is to create the key store file (sonarqube.jks in the current directory) with keytool. The second is to create the temporary caching directory for sonar-scanner-cli to run.

Step 3

The actual sonar-scanner-cli-docker container.

sonar_scan:
  image: sonarsource/sonar-scanner-cli
  environment:
    SONAR_SCANNER_OPTS: -Djavax.net.ssl.trustStore=sonarqube.jks -Djavax.net.ssl.trustStorePassword=changeit
    SONAR_TOKEN: $SONAR_TOKEN
  command:
    - sonar-scanner -Dsonar.login=$SONAR_TOKEN

Powered by Gatsby. Theme inspired by end2end.

© 2014-2020. Made with by mdluo.