web-dev-qa-db-ja.com

Javaを使用したAWS DocumentDB TLS接続

DocumentDBクラスターとプレーンJava over TLS/SSLで接続すると問題が発生します。

AWS docs に従って私が従った手順はこれです:

ダウンロードした.pem AWSからのファイルで、私のJavaプロジェクトのルートにコピーしました。実行した場所から:

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

これにより、rds-ca-certsプロジェクトのルートで、次のようになります。

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:要求されたターゲットへの有効な証明書パスが見つかりません

興味深いことに、mongo 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コマンドにあると思います。

さらに、クラスターでTLSdisabledを使用すると、この AWSによって提供されるJavaコード (キーストア構成のみが異なる)が機能します。

PD:AWS DocumentDBとのSSL/TLS接続に関して他にもたくさんの質問があることは知っていますが、特に私の問題に対処するものはありません。さらに、プレーンなmongodb TLS/SSL接続の質問もチェックしましたが、プロセスが異なるため、私にとっては有効ではありません。

5
Arcones

この問題は、bundle内の同じエイリアスで証明書をインポートするプロセスに関連しているようです。

したがって、バンドルされたオプション(rds-combined-ca-bundle.pem)を使用してstopを実行し、これを使用する必要がありました rds-ca-2019-root。 pem

次のコマンドを使用してキーストアをインポートした後:

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

TLSでのデータベースとの接続が達成されました。

2
Arcones

AWS提供の証明書をJavaのトラストストアに追加すると、JavaはデフォルトでAWSサービスへのリクエストを信頼します。
Java cacertsファイルを見つける必要があります。OSとJavaのバージョンによっては、..lib/security/cacerts
OSXを使用していて、
/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/lib/security/cacerts

次に、keytoolにデフォルトをインポートさせますJava keystore password is it it:

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

うまくいったらポストバックしてください。

1
Yan