Home > Blockchain >  Adding CA certificate via binding in Spring Boot's maven plugin is failing due to 'failed
Adding CA certificate via binding in Spring Boot's maven plugin is failing due to 'failed

Time:01-31

Following the recommendations here, these recommendations are how to pass SSL certificates into a build image using Spring Boot's plugin for maven.

  • I have this in my pom.xml:
<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
    <image>
        <bindings>
        <binding>${basedir}/bindings/certificates:/platform/bindings/ca-certificates</binding>
        </bindings>
    </image>
    </configuration>
</plugin> 
  • I have the directory structure:
    project
    |-bindings
     |-certificates
       |-type
       |-certificate.crt
    
  • type file contains:
$ cat bindings/certificates/type 
ca-certificates
  • However, I am getting this error:
$ ./mvnw spring-boot:build-image
...
...
...
[INFO]  > Running creator
[INFO]     [creator]     ===> ANALYZING
[INFO]     [creator]     Restoring data for SBOM from previous image
[INFO]     [creator]     ===> DETECTING
[INFO]     [creator]     ======== Output: paketo-buildpacks/[email protected] ========
[INFO]     [creator]     failed to load bindings from '/platform/bindings': failed to read binding 'ca-certificates': missing 'type'
[INFO]     [creator]     err:  paketo-buildpacks/[email protected] (1)
[INFO]     [creator]     ======== Output: paketo-buildpacks/[email protected] ========
[INFO]     [creator]     failed to load bindings from '/platform/bindings': failed to read binding 'ca-certificates': missing 'type'
[INFO]     [creator]     err:  paketo-buildpacks/[email protected] (1)
...
...
...
[INFO]     [creator]         Using Java version 17 extracted from MANIFEST.MF
[INFO]     [creator]       BellSoft Liberica JRE 17.0.5: Contributing to layer
[INFO]     [creator]         Downloading from https://github.com/bell-sw/Liberica/releases/download/17.0.5 8/bellsoft-jre17.0.5 8-linux-amd64.tar.gz
[INFO]     [creator]     unable to invoke layer creator
[INFO]     [creator]     unable to get dependency jre
[INFO]     [creator]     unable to download https://github.com/bell-sw/Liberica/releases/download/17.0.5 8/bellsoft-jre17.0.5 8-linux-amd64.tar.gz
[INFO]     [creator]     unable to request https://github.com/bell-sw/Liberica/releases/download/17.0.5 8/bellsoft-jre17.0.5 8-linux-amd64.tar.gz
[INFO]     [creator]     Get "https://github.com/bell-sw/Liberica/releases/download/17.0.5 8/bellsoft-jre17.0.5 8-linux-amd64.tar.gz": x509: certificate signed by unknown authority
[INFO]     [creator]     ERROR: failed to build: exit status 1
...
...
...
  • As mentioned above, there is most definitely is a bindings/certificates/type file containing the word ca-certificates

  • I have confirmed the 'basedir' property to make sure it wasn't wonky using:

$ mvn help:evaluate -Dexpression=basedir -q -DforceStdout
/my_repo/uservices/restservice_example

And this is correct.

  • I am running this inside a Docker container which I'm trying to use as a gitlab-runner executor. The strangest part about this error is that I can run it on my host machine without issue. For some reason, the identical build with identical certificate does not work inside the container.

Can anyone recommend any tips for troubleshooting/solving?

CodePudding user response:

Can anyone recommend any tips for troubleshooting/solving?

Here are the steps to troubleshoot a paketo-buildpacks/ca-certificates binding issue:

  1. Look at the build output from the CA Certificates buildpack. If it is seeing your certificates, you'll see "Added %d additional CA certificate(s) to system truststore" where %d is the number of certificates it loaded. This will expose certificates to any process that honors the OpenSSL conventions for finding certificates.

  2. Because the JVM does not honor OpenSSL conventions and has its own conventions, the next step is to check if the JVM is also loading the CA certificates into its truststore. Check the output of the JVM Provider buildpack (Bellsoft Liberica, Azul Zulu, etc..) and you should see a line like "Added %d additional CA certificate(s) to system truststore", again where %d is the number of certificates it loaded.

    Note: this number may be way higher than the number of certificates you've added, but you can take the number presented minus the number it loads by default (it is usually around 127 or 128, depending on what CA certificates are shipped by default). The difference is how many certificates the buildpack loaded.

  3. If that does not help, set the env variable BP_DEBUG=true at runtime and enable verbose mode. With pack build, that's done by adding the -v. With Spring Boot build tools, there is a specific setting, verboseLogging which needs to be set to true.

    Example with Maven:

        <image>
            <verboseLogging> true </verboseLogging>
            <env>
                <BP_DEBUG>=true</BP_DEBUG>
            </env>
            <bindings>
            <binding>${basedir}/bindings/certificates:/platform/binding/ca-certificates</binding>
            </bindings>
        </image>
    

    This should give you quite a bit of additional output. Towards the top, you should see output from detection time and further down output from build time.

    Locate the output from the CA certificates buildpack at detection time (it should be towards the very top since that buildpack runs first) and look for these two lines:

    [INFO]     [creator]     Platform contents: [. env env/BP_DEBUG]
    [INFO]     [creator]     Platform Bindings: [. binding binding/ca-certificates binding/ca-certificates/stuff.crt binding/ca-certificates/type]
    

    This indicates the contents of the /platform directory and the /platform/bindings directory. You want to see your binding listed on the second line. If it's listed on the first line or if it's not listed at all, then you have a problem with your binding. Check the binding paths your setting, check file permissions/ownership on the Docker client/server and in the guest container, and check that the binding files are visible on the Docker Server, not just the Docker client (the volume mount happens from the server into the container, if your client is remote that can cause issues).

    If there is a problem with any of the CA certificates you've listed, you should see that logged as well (like if the format is wrong).

  4. The steps above apply to build time only. If you do not see the certificates loaded at runtime, please make sure that you have also included the bindings at runtime. You need them both at build time and runtime, unless you set the env variable BP_EMBED_CERTS=true at build time. This will tell the buildpack to package your CA certificates into the image, which means you won't need the runtime bindings.

CodePudding user response:

I have discovered the reason for this error:

Failed to load bindings from '/platform/bindings': failed to read binding 'ca-certificates': missing 'type'

resulting in the bindings being empty. Apparently, the build pack creates a new container and volume mounts the contents of the bindings. The volume mount wasn't working because I was running this build inside a container. Docker in Docker. Although the build pack was able to create a new container, the volume mount just didn't work. Because my container mounted the Docker daemon's socket (on the host), this is actually "Docker outside Docker", e.g. the build pack's container was a sister container. So the build pack was trying to mount a volume existing in another container.

  • Related