12

I am facing problems connecting with my DocumentDB cluster with plain Java over TLS/SSL

The procedure I followed as per the AWS docs is this:

I downloaded the .pem file from AWS and copied in the root of my java project, from where I executed:

keytool -importcert -trustcacerts -file rds-combined-ca-bundle.pem -alias certAlias -keystore rds-ca-certs -storepass keyStorePassword

This has created the rds-ca-certsat the root of my project which now looks like this:

enter image description here

And, the java code in Main.java is:

package com.example.documentdb;

import com.mongodb.MongoClient;
import com.mongodb.MongoClientURI;
import com.mongodb.ServerAddress;
import com.mongodb.MongoException;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.MongoCollection;
import org.bson.Document;


public final class Main {
    private Main() {
    }
    public static void main(String[] args) {

        String template = "mongodb://%s:%s@%s/test?ssl=true&replicaSet=rs0&readpreference=%s";
        String username = "myUsernameInCluster";
        String password = "myPasswordInCluster";
        String clusterEndpoint = "mycluster.node.us-east-1.docdb.amazonaws.com:27017";
        String readPreference = "secondaryPreferred";
        String connectionString = String.format(template, username, password, clusterEndpoint, readPreference);

        String keystore = "rds-ca-certs";
        String keystorePassword = "keyStorePassword";

        System.setProperty("javax.net.ssl.trustStore", keystore);
        System.setProperty("javax.net.ssl.trustStorePassword", keystorePassword);

        MongoClientURI clientURI = new MongoClientURI(connectionString);
        MongoClient mongoClient = new MongoClient(clientURI);

        MongoDatabase testDB = mongoClient.getDatabase("test");
        MongoCollection<Document> numbersCollection = testDB.getCollection("numbers");

        Document doc = new Document("name", "pi").append("value", 3.14159);
        numbersCollection.insertOne(doc);

        MongoCursor<Document> cursor = numbersCollection.find().iterator();
        try {
            while (cursor.hasNext()) {
                System.out.println(cursor.next().toJson());
            }
        } finally {
            cursor.close();
        }

    }
}

It gives me this ugly error:

com.mongodb.MongoSocketWriteException: Exception sending message

Caused by: javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

Interestingly, when I use the mongo CLI to connect over SSL/TLS, like this:

mongo --ssl --host mycluster.node.eu-central-1.docdb.amazonaws.com:27017 --sslCAFile rds-combined-ca-bundle.pem --username myUsernameInCluster --password myPasswordInCluster

It works perfectly, so I have discarded a networking issue and I think the problem is in the Java code itself or in the keytool command executed.

Additionally, with TLS disabled in the cluster this java code provided by AWS (that only differs in the keystore configuration) works.

PD: I know there are a bunch of other questions regarding SSL/TLS connection with AWS DocumentDB, but none of them address my issue specifically. Moreover, I have also checked plain mongodb TLS/SSL connection questions and the process differ so they are not valid for me.

4

3 回答 3

11

该问题似乎与在同一别名下在bundle中导入证书的过程有关。

所以我不得不停止使用捆绑选项(rds-combined-ca-bundle.pem)并开始使用这个rds-ca-2019-root.pem

使用以下命令导入密钥库后:

keytool -importcert -trustcacerts -file rds-ca-2019-root.pem -alias rds19 -keystore rds-ca-certs -storepass keyStorePassword

实现了与 TLS 下的数据库的连接。

于 2020-02-12T09:47:06.617 回答
1

您可以将 AWS 提供的证书添加到 java 的信任存储中,然后 java 将默认信任对 AWS 服务的请求。
您必须找到您的 java cacerts 文件。根据您的操作系统和 java 版本,它应该是..lib/security/cacerts.
我正在使用 OSX,它在
/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/lib/security/cacerts

然后你让 keytool 导入它,默认的 java keystore 密码是改变它:

keytool -import -trustcacerts -keystore /Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/lib/security/cacerts -storepass changeit -noprompt -alias aws-rds -file rds-combined-ca-bundle.pem

要检查证书是否已导入,您可以使用:
keytool -list -keystore /Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/jre/lib/security/cacerts | grep aws

如果有效,请回帖。

于 2020-01-15T16:25:31.870 回答
0

https://github.com/hungbang/spring-boot-aws-docdb 我创建了一个示例,用于从启用 SSL 的 spring boot 连接到 amazon docdb。

于 2021-08-21T14:24:18.420 回答