AWS DocumentDB TLS соединение с Java - PullRequest
5 голосов
/ 14 января 2020

Я сталкиваюсь с проблемами при подключении к кластеру DocumentDB с обычным Java через TLS / SSL

Процедура, которой я следовал согласно AWS документам , такова:

Я скачал файл .pem из AWS и скопировал в root моего java проекта, откуда я выполнил:

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

Это создало rds-ca-certs в root моего проекта, который теперь выглядит следующим образом:

enter image description here

И код java в Main. java это:

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();
        }

    }
}

Это дает мне эту ужасную ошибку:

com.mongodb.MongoSocketWriteException: исключение при отправке сообщения

Причина: javax. net .ssl. SSLHandshakeException: сбой при создании пути PKIX: sun.security.provider.certpath.SunCertPathBuilderException: невозможно найти допустимый путь сертификации для запрошенной цели

Интересно, когда я использую mon go CLI для подключения через SSL / TLS, вот так:

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

Работает отлично, поэтому я отбросил сетевой вопрос и я думаю, что проблема в самом коде Java или в выполняемой команде keytool.

Кроме того, при отключенном TLS в кластере это java код, предоставленный AWS (который отличается только конфигурацией хранилища ключей), работает.

PD: я знаю, что есть множество других вопросов, касающихся соединения SSL / TLS с AWS DocumentDB, но ни одного из них конкретно касаются моей проблемы. Кроме того, я также проверил простые вопросы подключения TLS / SSL к mongodb, и процесс отличается, поэтому они недействительны для меня.

Ответы [ 2 ]

1 голос
/ 12 февраля 2020

Похоже, проблема связана с процессом импорта сертификатов в связке под тем же псевдонимом.

Так что мне пришлось остановить , используя пакетный параметр (rds-комбинированный-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 установлено.

1 голос
/ 15 января 2020

Вы можете добавить предоставленный AWS сертификат в хранилище доверия java, тогда java будет доверять запросам к службе AWS по умолчанию.
Вам нужно будет найти файл java cacerts , В зависимости от вашей ОС и java версии она должна быть в ..lib/security/cacerts.
Я использую OSX, и она была в
/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/lib/security/cacerts

Затем вы заставляете keytool импортировать его по умолчанию java пароль хранилища ключей: измените его:

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

Публикация обратно, если это работал.

...