cathive / concourse-sonarqube-resource

performs SonarQube analyses and checks quality gates https://concourse-ci.org/ https://sonarqube.org/
Apache License 2.0
46 stars 50 forks source link

Support custom CA for SSL communication #30

Open xyloman opened 5 years ago

xyloman commented 5 years ago

We are having issues connecting to our sonar and didn't know the best practice for providing our own CA. We have seen the maven resource add support for a custom certificate for a repository: https://github.com/nulldriver/maven-resource/commit/26d48ada6f0309cdc530ec5b6150d55defd83b0c We also had in the past followed the work around done when concourse started clobbering the certs that come with a container. Now I wonder if we are presenting a new use case or maybe I am just missing something in order to configure a custom CA.

headcr4sh commented 5 years ago

I have -- unfortunately -- no idea how a custom set of CAs might be handled. I think, Concourse CI itself implemented a bit of dark magic around CAs and resources a while back... Can't remember any details right now, though....

febinrejoe commented 5 years ago

I played around with this a little bit and I believe taking the CA certificate as an input parameter like nulldriver/maven-resource@26d48ad will help mitigate the SSL issue.

I think this will help,

headcr4sh commented 5 years ago

I think the attempt with the Java Keystore/Truststore might work indeed.

But... ... it shouldn't be necessary, to use an extra parameter, as Concourse CI is already equipped with a mechanism to mount custom CAs into the running resource's containers.

So... ... all the steps, that @febinrejoe mentioned (except the 1st one! All certs have already been placed into /etc/ssl/certs by Concourse CI itself) seem like the way to go.

See https://concourse-ci.org/implementing-resources.html#resource-certs for further details.

febinrejoe commented 5 years ago

Yes, this is not an issue, if Sonar uses a CA certificate. However if Sonar uses a Custom CA certificate, then we will have to make the certificate available to the JVM. For Maven resource, this is done using this PR as pointed out by @xyloman

moepkid-zz commented 5 years ago

Hello,

@febinrejoe @headcr4sh

We are trying the the same thing but to no avail.

&sonar-scan put: code-analysis params: &sonar-scan-params scanner_type: maven maven_settings_file: /root/.m2/settings.xml project_key: com.hbr.hm:astroservice project_path: ./git sources:

Are we missing something? The needed cert is placed in the jre certs of (nulldriver/mvn) and also on the server itself.

headcr4sh commented 5 years ago

Ok... I understand, that your SonarQube instance uses HTTPS but the certificate is (probably) self-signed.

You will have to start your Concourse Worker instances that spawn the concourse-sonarqube-instance with the correct paramteres then. Folloing is an excerpt from concourse worker --help:

--certs-dir=                                       Directory to use when creating the resource certificates volume. [$CONCOURSE_CERTS_DIR]

If the worker is started with --certs-dir and this directory contains the public portion of your self-signed certificate, the self-signed cert will be available within the concourse-sonarqube-resource under /etc/ssl/certs. (Documentation of this feature can be found here: https://concourse-ci.org/implementing-resources.html)

Most likeley, this certificate would have to be converted by the resource itself (thus: put stuff in a key store / cert store which can be read by Java),... (the Docker image that we are using already ships a script called "update-ca-certificates" which would probably have to be called prior to perfoming any other steps in check/in/out...)

This solution however is much more robust than extending the input parameters of the resource itself to pass in a custom CA certificate.

moepkid-zz commented 5 years ago

@headcr4sh

Aaah, but we start it with a docker-compose.yml file. We can use an environment property called CONCOURSE_CERTS_DIR=/etc/ssl/certs, but this one is completely ignored i think.

concourse: restart: always image: concourse/concourse:4.2.1 command: quickstart privileged: true depends_on: [concourse-db] ports: ["8080:8080"] volumes:

We added the crt to the /etc/ssl/certs of the main machine (host).

headcr4sh commented 5 years ago

Ok. Seems to be an issue with the concourse quickstart command then, I assume.

Just tried the following command:

concourse quickstart --help 2>&1 |grep certs-dir

The invocation yields exactly 0 result. :-(

headcr4sh commented 5 years ago

Just got a response from Vito (maintainer of Concourse CI). You will have to pass --worker=cert=dir when using the quickstart command to avoid ambiguitis between what's passed to web/atc and the worker.

As far as I can tell, there is no way to set this via environment variable, so you will have to modify your docker-compose unit and add a command line flat.

moepkid-zz commented 5 years ago

thanks for the help! will try it now. One question though, how do i add such a arg? If i remember correctly, docker compose only accepts anv properties right?

moepkid-zz commented 5 years ago

I added the command --worker-cert-dir=/etc/ssl/certs. Lets see if this works!

moepkid-zz commented 5 years ago

Somehow setting this command still does not fix the PKIX issue we have.

' sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target'

I also added a script that puts the .der file with the keytool command on the host worker but to no avail.

headcr4sh commented 5 years ago

I suppose, the certificate will still have to be converted into Java Keystore/Truststore format then... (It's a a subset of the solution that @febinrejoe has already suggested above)

I'll try to look into it... (PRs welcome, if anyone else finds the time prior to me... ;-))

moepkid-zz commented 5 years ago

so for now it is not possible to use this certificate?

(we do it manually now by running keytool import within a build.sh thats being run by the concourse worker)

moepkid-zz commented 5 years ago

aaah, in regards to what @febinrejoe said, does that mean i have to alter the additional proeprties of the runner so thst the keystore points to the host?

 - &sonar-scan
      put: code-analysis
      params: &sonar-scan-params
        scanner_type: maven
        maven_settings_file: /root/.m2/settings.xml
        project_key: ###
        project_path: ./git
        sources:
        - src/main
        tests:
        - src/test
        additional_properties: &sonar-scan-properties
          sonar.java.binaries: ../build-output/classes
          sonar.junit.reportPaths: ../build-output/surefire-reports
          sonar.jacoco.reportPaths: ../build-output/jacoco.exec
          sonar.projectName: '###'

sonar.keystore ### ?

febinrejoe commented 5 years ago

@headcr4sh I have the fix, I just need to clean up the code a little. I can create the PR sometime this week.

moepkid-zz commented 5 years ago

@febinrejoe amazing! that would be awesome

moepkid-zz commented 5 years ago

is there any update on this issue?

mjarends commented 4 years ago

Trying to add Sonarqube into our pipeline and ran into this same issue.

Was there a workaround to the issue? Another option that I have seen implemented on resources is to set the insecure flag on the curl requests.

headcr4sh commented 4 years ago

An insecure flag (although definitely not something that I would like to see in a production environment) might be a viable solution for test scenarios, indeed.

Anyone willing to submit a patch?

cyclump commented 4 years ago

For future people, a possible work around is to create a derivative of this docker image and in a new layer, add your certificate authorities to the java trust store using keytool as well as to the linux store using /usr/sbin/update-ca-certificates. I am doing this now with much success in an enterprise environment. Maybe not the best solution but it gets the job done.

cyclump commented 4 years ago

After reading about the CURL_CA_BUNDLE environment variable at https://curl.haxx.se/docs/sslcerts.html I am beginning to noodle a fix for this. It would involve declaring trusted CAs in the source definition and those CAs would be dynamically added to the Java trust store in out and the CURL_CA_BUNDLE set in in and check. With an array of certificates this may be possible to have many. CURL_CAL_BUNDLE should be able to support multiple certificates in the same file.

JulesVerne22 commented 3 years ago

Any updates on this?