How to add SSL certificate to Bluemix java cloud f

2019-07-09 11:41发布

I am developing microservices using Spring Boot, Java JDK 1.8, MongoDB driver for Java, and MongoDB. I have created MongoDB instance on Bluemix and I am connecting to this instance from Java microservices.

The MongoDB instance on Bluemix is SSL enabled and it provides the SSL certificate. For local development, I have Base64 decoded this certificate and I have imported this SSL certificate to the my local java keystore. So locally I am able to connect to the MongoDB instance on Bluemix without any issues.

When I am deploying my spring boot microservices as jar file to Bluemix using cf CLI, the microservices are unable to connect to the MongoDB on Bluemix because I haven't uploaded the SSL certificate which was provided by MongoDB.

Can someone please let me know the steps needed to upload the SSL certificate to Bluemix so my microservices can connect to the MongoDB instance?

1条回答
forever°为你锁心
2楼-- · 2019-07-09 12:23

Option 1a

If you have a single certificate, you can use the spring-boot-ssl-truststore-gen which adds the certificate to the system truststore inside the buildpack:

First you need this in your pom.xml (or alternative):

<repositories>
   <repository>
      <id>jcenter</id>
      <url>http://jcenter.bintray.com </url>
      <snapshots>
        <enabled>true</enabled>
        <updatePolicy>never</updatePolicy>
        <checksumPolicy>warn</checksumPolicy>
      </snapshots>
       <releases>
         <enabled>true</enabled>
         <checksumPolicy>warn</checksumPolicy>
      </releases>
   </repository>
</repositories> 

and

<dependency>
    <groupId>com.orange.clara.cloud.boot.ssl-truststore-gen</groupId>
    <artifactId>spring-boot-ssl-truststore-gen</artifactId>
    <version>2.0.21</version>
</dependency>

If you are creating a cloud foundry app, next declare the certificate in your manifest.yml:

env:
    TRUSTED_CA_CERTIFICATE: |-
        -----BEGIN CERTIFICATE-----
        changeme
        -----END CERTIFICATE-----

When you cf push your application, the certificate will get added to the truststore.

If you aren't creating a cloud foundry app, set the enivonment variable TRUSTED_CA_CERTIFICATE with the value of your certificate, e.g.

$ export TRUSTED_CA_CERTIFICATE=<TRUSTED_CA_CERTIFICATE_VALUE>

Option 1b

The spring-boot-ssl-truststore-gen library does not support loading multiple certificates from the TRUSTED_CA_CERTIFICATE environment variable. If you have multiple certificates, you can try directly calling the ssl-truststore-gen api, e.g. from a static block in one of your classes:

package helloworld;

import com.orange.clara.cloud.boot.ssl.CertificateFactory;
import com.orange.clara.cloud.boot.ssl.DefaultTrustStoreAppender;
import com.orange.clara.cloud.boot.ssl.TrustStoreInfo;

public class CertLoader {

    public static final String SSL_TRUST_STORE_SYSTEM_PROPERTY = "javax.net.ssl.trustStore";
    public static final String SSL_TRUST_STORE_PASSWORD_SYSTEM_PROPERTY = "javax.net.ssl.trustStorePassword";

    static {
        String[] certs = {
            System.getenv("CERTIFICATE_1"),
            System.getenv("CERTIFICATE_2")
        };

        for (String cert : certs) {
            DefaultTrustStoreAppender trustStoreAppender = new DefaultTrustStoreAppender();
            TrustStoreInfo trustStoreInfo = trustStoreAppender.append(CertificateFactory.newInstance(cert));
            System.setProperty(SSL_TRUST_STORE_SYSTEM_PROPERTY, trustStoreInfo.getTrustStorefFile().getAbsolutePath());
            System.setProperty(SSL_TRUST_STORE_PASSWORD_SYSTEM_PROPERTY, trustStoreInfo.getPassword());
        }
    }
}

You would then need something like the following in your manifest.yml:

env:
    CERTIFICATE_1: |-
        -----BEGIN CERTIFICATE-----
        changeme
        -----END CERTIFICATE-----

    CERTIFICATE_2: |-
        -----BEGIN CERTIFICATE-----
        changeme
        -----END CERTIFICATE-----

Option 1c

Add the following to your pom.xml to automatically load the ssl certificates when your application starts up using https://github.com/snowch/spring-boot-ssl-truststore-gen:

<repository>
   <id>jitpack.io</id>
   <url>https://jitpack.io</url>
</repository>

<dependency>
   <groupId>com.github.snowch</groupId>
   <artifactId>spring-boot-ssl-truststore-gen</artifactId>
   <version>master</version>
</dependency>

or to your Gradle:

allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}

compile 'com.github.snowch:spring-boot-ssl-truststore-gen:master'

Option 2

If you are creating a cloud foundry app and using the liberty buildpack see this question and the accepted answer for adding a ssl certificate: Add certificate to truststore to enable SSL communication

Option 3

If you have access to the socket, e.g. You are instantiating a MongoClient() instance yourself rather than letting a library such as spring cloud connectors handle this for you, you could try https://www.compose.com/articles/easier-java-connections-to-mongodb-at-compose-2/

查看更多
登录 后发表回答