appsody / stacks

Appsody application stacks. This repo will be archived soon.
https://appsody.dev
Apache License 2.0
89 stars 120 forks source link

java-microprofile to reference pre-built CA database #440

Open nastacio opened 4 years ago

nastacio commented 4 years ago

Is your feature request related to a problem? Please describe. Whenever my application needs to reference a remote service, I get a "PKIX" exception about the certificate not being trusted, so I always need to modify the template server.xml with something like this:

<server description="Liberty server">
    ...

    <keyStore id="defaultTrustStore" 
        password="changeit"
        readOnly="false" 
        type="JKS" 
        location="/opt/java/openjdk/jre/lib/security/cacerts">
    </keyStore>

    <ssl id="defaultSSLSettings" 
         keyStoreRef="defaultKeyStore"
         trustStoreRef="defaultTrustStore"></ssl>

    <sslDefault 
        sslRef="defaultSSLSettings" 
        outboundSSLRef="defaultSSLSettings"></sslDefault>

    ...

</server>

Describe the solution you'd like The default template for java-microprofile could have a CA cert database as the default truststore for outbound connections. Other stacks, such as nodejs, seem to have it.

Describe alternatives you've considered There is no other alternative other than reverse-engineering the stack definition and container structure to figure out what needs to be added to server.xml. Referencng the CA cert database in OpenJDK required me to find out the location of the database in the running container. That solution is fragile, so it led me to think it would be best to build my own CA database, which is even more complicated:

If we wanted to reference a service that is not present in a CA database for some reason, then a new truststore has to created with the OpenJDK keytool utility, the new key added to the new truststore, then referenced in the server.xml file, and included in the running server directory by maven.

Since "/project/user-app" is a mounted folder inside the container after appsody run, it may be more convenient to create the new repository from inside such cointainer.

Launch the application with appsody run and ssh into it:

docker exec -it viz-open-data-dev /bin/sh

keytool -importkeystore -srckeystore /opt/java/openjdk/jre/lib/security/cacerts -keystore /project/user-app/src/main/liberty/config/resources/security/truststore.jks -deststoretype JKS -deststorepass mpKeystore -srcstorepass changeit

Still in the shell inside the container: add the new key to the new truststore. This is just an example for illustration purposes, since that key is already signed by a trusted CA and therefore already implicitly trusted by the client application:

keytool -importcert -file /project/user-app/src/main/resources/us-southdynamic-dashboard-embeddedcloudibmcom.crt -alias ussouthcde -keystore  /project/user-app/src/main/liberty/config/resources/security/truststore.p12 -noprompt -storetype PKCS12 -storepass mpKeystore

Now replace /opt/java/openjdk/jre/lib/security/cacerts in server.xml with truststore.p12. Note that this is not an absolute path anymore, which means Open Liberty will look for it in the default runtime location (/project/target/liberty/wlp/usr/servers/defaultServer/resources/security) . Therefore, we need to tell the appsody build process to place the new truststore in that location, by making a modification to pom.xml.

Add a plugin execution for the maven-resources-plugin, under the build/plugins element:

            <plugin>
                <artifactId>maven-resources-plugin</artifactId>
                <version>2.6</version>
                <executions>
                    <execution>
                        <id>copy-resources</id>
                        <phase>install</phase>
                        <goals>
                            <goal>copy-resources</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${basedir}/target/liberty/wlp/usr/servers/defaultServer/resources/security</outputDirectory>
                            <resources>
                                <resource>
                                    <directory>${basedir}/src/main/liberty/config/resources/security</directory>
                                    <filtering>false</filtering>
                                    <includes>
                                        <include>truststore.p12</include>
                                    </includes>
                                </resource>
                            </resources>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

Additional context None

covener commented 4 years ago

https://github.com/OpenLiberty/open-liberty/issues/9016

scottkurz commented 4 years ago

Though this issue hasn't been solved in the java-microprofile stack, relabeling to the java-openliberty stack, which is where we would prioritize a solution (assuming we were to solve this).