CACerts is not working in SonarQube 9.9 LTS on K8s helm deployment

Sonarqube Version: 9.9.1 LTS
Sonarqube helm chart: sonarqube 10.0.0+521 · sonarsource/sonarqube

Facing Issue while running the sonarqube analysis see the below debug log:

10:44:11.262 INFO: Scanner configuration file: D:\SonarQube\SonarQube_Project\sonar-scanner-cli-4.7.0.2747-windows\sonar-scanner-4.7.0.2747-windows\bin\..\conf\sonar-scanner.properties
10:44:11.265 INFO: Project root configuration file: D:\SonarQube\SonarQube_Project\stagingservertest-Testing_newcode_noncpp (1)\stagingservertest-Testing_newcode_noncpp\sonar-project.properties
10:44:11.292 INFO: SonarScanner 4.7.0.2747
10:44:11.292 INFO: Java 11.0.14.1 Eclipse Adoptium (64-bit)
10:44:11.294 INFO: Windows 10 10.0 amd64
10:44:11.397 DEBUG: keyStore is :
10:44:11.397 DEBUG: keyStore type is : pkcs12
10:44:11.397 DEBUG: keyStore provider is :
10:44:11.398 DEBUG: init keystore
10:44:11.398 DEBUG: init keymanager of type SunX509
10:44:11.735 DEBUG: Create: C:\Users\.sonar\cache
10:44:11.736 INFO: User cache: C:\Users\.sonar\cache
10:44:11.736 DEBUG: Create: C:\Users\.sonar\cache\_tmp
10:44:11.739 DEBUG: Extract sonar-scanner-api-batch in temp...
10:44:11.741 DEBUG: Get bootstrap index...
10:44:11.741 DEBUG: Download: https://stage.sonarqube.com/batch/index
10:44:12.206 ERROR: SonarQube server [https://stage.sonarqube.com] can not be reached
10:44:12.208 INFO: ------------------------------------------------------------------------
10:44:12.209 INFO: EXECUTION FAILURE
10:44:12.209 INFO: ------------------------------------------------------------------------
10:44:12.210 INFO: Total time: 0.967s
10:44:12.227 INFO: Final Memory: 4M/54M
10:44:12.228 INFO: ------------------------------------------------------------------------
10:44:12.229 ERROR: Error during SonarScanner execution
org.sonarsource.scanner.api.internal.ScannerException: Unable to execute SonarScanner analysis
        at org.sonarsource.scanner.api.internal.IsolatedLauncherFactory.lambda$createLauncher$0(IsolatedLauncherFactory.java:85)
        at java.base/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:185)
        at org.sonarsource.scanner.api.EmbeddedScanner.start(EmbeddedScanner.java:123)
        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.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at java.base/sun.security.ssl.Alert.createSSLException(Unknown Source)
        at java.base/sun.security.ssl.TransportContext.fatal(Unknown Source)
        at java.base/sun.security.ssl.TransportContext.fatal(Unknown Source)
        at java.base/sun.security.ssl.TransportContext.fatal(Unknown Source)
        at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.checkServerCerts(Unknown Source)
        at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.onConsumeCertificate(Unknown Source)
        at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.consume(Unknown Source)
        at java.base/sun.security.ssl.SSLHandshake.consume(Unknown Source)
        at java.base/sun.security.ssl.HandshakeContext.dispatch(Unknown Source)
        at java.base/sun.security.ssl.HandshakeContext.dispatch(Unknown Source)
        at java.base/sun.security.ssl.TransportContext.dispatch(Unknown Source)
        at java.base/sun.security.ssl.SSLTransport.decode(Unknown Source)
        at java.base/sun.security.ssl.SSLSocketImpl.decode(Unknown Source)
        at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(Unknown Source)
        at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
        at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
        at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.connection.RealConnection.connectTls(RealConnection.java:336)
        at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.connection.RealConnection.establishProtocol(RealConnection.java:300)
        at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.connection.RealConnection.connect(RealConnection.java:185)
        at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.connection.ExchangeFinder.findConnection(ExchangeFinder.java:224)
        at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.connection.ExchangeFinder.findHealthyConnection(ExchangeFinder.java:108)
        at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.connection.ExchangeFinder.find(ExchangeFinder.java:88)
        at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.connection.Transmitter.newExchange(Transmitter.java:169)
        at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:41)
        at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
        at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117)
        at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:94)
        at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
        at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117)
        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:142)
        at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:88)
        at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
        at org.sonarsource.scanner.api.internal.shaded.okhttp.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117)
        at org.sonarsource.scanner.api.internal.shaded.okhttp.RealCall.getResponseWithInterceptorChain(RealCall.java:221)
        at org.sonarsource.scanner.api.internal.shaded.okhttp.RealCall.execute(RealCall.java:81)
        at org.sonarsource.scanner.api.internal.ServerConnection.callUrl(ServerConnection.java:115)
        at org.sonarsource.scanner.api.internal.ServerConnection.downloadString(ServerConnection.java:99)
        at org.sonarsource.scanner.api.internal.BootstrapIndexDownloader.getIndex(BootstrapIndexDownloader.java:39)
        ... 10 more
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 java.base/sun.security.validator.PKIXValidator.doBuild(Unknown Source)
        at java.base/sun.security.validator.PKIXValidator.engineValidate(Unknown Source)
        at java.base/sun.security.validator.Validator.validate(Unknown Source)
        at java.base/sun.security.ssl.X509TrustManagerImpl.validate(Unknown Source)
        at java.base/sun.security.ssl.X509TrustManagerImpl.checkTrusted(Unknown Source)
        at java.base/sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
        ... 45 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at java.base/sun.security.provider.certpath.SunCertPathBuilder.build(Unknown Source)
        at java.base/sun.security.provider.certpath.SunCertPathBuilder.engineBuild(Unknown Source)
        at java.base/java.security.cert.CertPathBuilder.build(Unknown Source)
        ... 51 more

It’s not getting the required server cacerts,
What I have tried so far, I’m passing the cacert in values.yaml :

caCerts:
  enabled: true
  image: adoptopenjdk/openjdk11:alpine
  secret: trusted-certs  

I check in the /opt/java/openjdk/lib/security/cacert those certs are not present

Also, truststore define in sonarqube container is **/opt/sonarqube/certs/cacerts**

Environment:

      SONAR_WEB_JAVAOPTS:        -javaagent:/opt/sonarqube/data/jmx_prometheus_javaagent.jar=8000:/opt/sonarqube/conf/prometheus-config.yaml -Djavax.net.ssl.trustStore=/opt/sonarqube/certs/cacerts
      SONAR_CE_JAVAOPTS:         -javaagent:/opt/sonarqube/data/jmx_prometheus_javaagent.jar=8001:/opt/sonarqube/conf/prometheus-ce-config.yaml -Djavax.net.ssl.trustStore=/opt/sonarqube/certs/cacerts

so I also try to pass the persistence

extraVolumes:
    - name: cert-volume
      secret:
        secretName: trusted-certs
  extraVolumeMounts:
    - name: cert-volume
      mountPath: /opt/sonarqube/certs

Didn’t work
Is there something else need to be define to make it work?

Regards,
S

Hi,

Any update on this ???

I would also like to add the below finding :
cacerts are getting stored in truststore define in sonarqube container /opt/sonarqube/certs/cacerts, I have also verified that they are valid.

one thing I have noticed is that in the pod description truststore location is different /tmp/certs/cacerts.
See the below

Init Containers:
  ca-certs:
    Container ID:  containerd://
    Image:         adoptopenjdk/openjdk11:alpine
    Image ID:      docker.io/adoptopenjdk/openjdk11@sha256:
    Port:          <none>
    Host Port:     <none>
    Command:
      sh
    Args:
      -c
      cp -f "${JAVA_HOME}/lib/security/cacerts" /tmp/certs/cacerts; if [ "$(ls /tmp/secrets/ca-certs)" ]; then for f in /tmp/secrets/ca-certs/*; do keytool -importcert -file "${f}" -alias "$(basename "${f}")" -keystore /tmp/certs/cacerts -storepass changeit -trustcacerts -noprompt; done; fi;
    State:          Terminated
      Reason:       Completed
      Exit Code:    0
      Started:      Wed, 10 May 2023 10:07:50 +0530
      Finished:     Wed, 10 May 2023 10:07:51 +0530
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /tmp/certs from sonarqube (rw,path="certs")
      /tmp/secrets/ca-certs from ca-certs (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-8qxm5 (ro)
	  
	  
	  
	  Containers:
  sonarqube:
    Container ID:   containerd://
    Image:          sonarqube:9.9.1-community
    Image ID:       docker.io/library/sonarqube@sha256:
    Ports:          9000/TCP, 8000/TCP, 8001/TCP
    Host Ports:     0/TCP, 0/TCP, 0/TCP
    State:          Running
      Started:      Wed, 10 May 2023 10:07:58 +0530
    Ready:          True
    Restart Count:  0
    Limits:
      cpu:     800m
      memory:  4096M
    Requests:
      cpu:     400m
      memory:  2Gi
    Liveness:  exec [sh -c host="$(hostname -i || echo '127.0.0.1')"
reply=$(wget -qO- --header="X-Sonar-Passcode: $SONAR_WEB_SYSTEMPASSCODE" http://${host}:9000/api/system/liveness 2>&1)
if [ -z "$reply" ]; then exit 0; else exit 1; fi
] delay=60s timeout=1s period=30s #success=1 #failure=6
    Readiness:  exec [sh -c #!/bin/bash
# A Sonarqube container is considered ready if the status is UP, DB_MIGRATION_NEEDED or DB_MIGRATION_RUNNING
# status about migration are added to prevent the node to be kill while sonarqube is upgrading the database.
host="$(hostname -i || echo '127.0.0.1')"
if wget --proxy off -qO- http://${host}:9000/api/system/status | grep -q -e '"status":"UP"' -e '"status":"DB_MIGRATION_NEEDED"' -e '"status":"DB_MIGRATION_RUNNING"'; then
  exit 0
fi
exit 1
] delay=60s timeout=1s period=30s #success=1 #failure=6
    Startup:  http-get http://:http/api/system/status delay=30s timeout=1s period=10s #success=1 #failure=24
    Environment Variables from:
      sonarqube-sonarqube-jdbc-config  ConfigMap  Optional: false
    Environment:
      SONAR_WEB_JAVAOPTS:        -javaagent:/opt/sonarqube/data/jmx_prometheus_javaagent.jar=8000:/opt/sonarqube/conf/prometheus-config.yaml -Djavax.net.ssl.trustStore=/opt/sonarqube/certs/cacerts
      SONAR_CE_JAVAOPTS:         -javaagent:/opt/sonarqube/data/jmx_prometheus_javaagent.jar=8001:/opt/sonarqube/conf/prometheus-ce-config.yaml -Djavax.net.ssl.trustStore=/opt/sonarqube/certs/cacerts
      SONAR_JDBC_PASSWORD:       <set to the key 'password' in secret 'sonarqube-pguser-sonarqube'>                               Optional: false
      SONAR_WEB_SYSTEMPASSCODE:  <set to the key 'SONAR_WEB_SYSTEMPASSCODE' in secret 'sonarqube-sonarqube-monitoring-passcode'>  Optional: false
    Mounts:
      /opt/sonarqube/certs from sonarqube (rw,path="certs")
      /opt/sonarqube/conf/prometheus-ce-config.yaml from prometheus-ce-config (rw,path="prometheus-ce-config.yaml")
      /opt/sonarqube/conf/prometheus-config.yaml from prometheus-config (rw,path="prometheus-config.yaml")
      /opt/sonarqube/data from sonarqube (rw,path="data")
      /opt/sonarqube/extensions/plugins from sonarqube (rw,path="extensions/plugins")
      /opt/sonarqube/logs from sonarqube (rw,path="logs")
      /opt/sonarqube/temp from sonarqube (rw,path="temp")
      /tmp from tmp-dir (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-8qxm5 (ro)

So I have also updated the path in init container ca-certs by adding the below context in values.yaml

InitContainers:
  - name: ca-certs
    image: adoptopenjdk/openjdk11:alpine
    command:
      - sh
    args:
      - -c
      - |
        cp -f "${JAVA_HOME}/lib/security/cacerts" /opt/sonarqube/certs/cacerts
        if [ "$(ls /tmp/secrets/ca-certs)" ]; then
          for f in /tmp/secrets/ca-certs/*; do
            keytool -importcert -file "${f}" -alias "$(basename "${f}")" -keystore /opt/sonarqube/certs/cacerts -storepass changeit -trustcacerts -noprompt
          done
        fi
    volumeMounts:
      - name: sonarqube
        mountPath: /opt/sonarqube
      - name: ca-certs
        mountPath: /tmp/secrets/ca-certs

I thought this will work but it didn’t.

Regards,
S

1 Like

Hi @Joe Any Update on this Issue ???

hello @Sheetal thanks a lot for taking the time to participate in the community.

Can you give me some more details on your setup ?

  • where is running the scanner ? (CI/CD, github action etc)
  • how is your sonarqube server exposed ? ( ingress, pure load balancer service)

Please correct me if i am wrong, but are you trying to expose your sonarqube server with a custom TLS certificate ? if that is the case you should use the ingress.tls section of our helm chart, and then inject the associated root certificate inside the scanner java trust-store (depends on which CI/CD you use).

Regards, jeremy

Issue has been resolved you can close this ticket.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.