簡體   English   中英

無法使用帶有服務器 CA 驗證的 TLS 連接到 AWS 數據庫

[英]Cannot Connect to AWS Database using TLS with Server CA Validation

AWS 文檔指出,要連接到我的 DocumentDB 集群,我需要使用以?ssl_ca_certs=rds-combined-ca-bundle.pem&replicaSet=rs0結尾的查詢字符串。 這是我的客戶應該驗證的根證書鏈 我不應該需要客戶證書

使用 MongoDB C# 驅動程序和此特定查詢,並且.pem文件位於同一目錄中,我無法建立連接。 如果我使用相同的.pem文件和來自 Mongo Shell 的查詢字符串,我可以正確連接到我的數據庫。 它僅不適用於我的 .net 核心應用程序,該應用程序也在 AWS 上運行。

通過從集群中刪除 TLS 並從查詢中刪除ssl_ca_certs選項,我可以正確連接到我的集群。

我以為我可以使用openssl將我的.pem文件轉換為.pfx ,但我必須給.pfx一個密碼, MongoDB 文檔指出

加載帶有密碼的證書時,PrivateKey 屬性必須不為空。 如果該屬性為空,則表示您的證書不包含私鑰,不會傳遞給服務器。

如何使用Amazon AWS 提供的.pem文件通過C# MongoDB 驅動程序連接到我的數據庫?

###Connection to Document DB with simple .Net console Application with SSL。

->首先,通過將參數 tls 設置為“已啟用”,在文檔數據庫集群上啟用 SSL。 確保重新啟動集群的編寫器節點以重新啟動整個集群以應用參數組更改。 默認情況下 TLS 在您啟動新的 Doc 數據庫集群時啟用。

-> 在您的環境中設置 SSL 證書:

1) 從以下鏈接下載源 Windows 計算機上的 PKCS#7 SSL 證書:

https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.p7b

2)點擊開始菜單,點擊運行,輸入mmc

3) 在 MMC 中,文件->添加/刪除管理單元。

4) 從管理單元列表中選擇證書,然后單擊添加。

5) 受信任的 CA 證書應該在本地計算機存儲中,因此選擇“計算機帳戶”單選按鈕,單擊下一步,然后選擇“本地計算機”。 單擊下一步,然后單擊完成。

6)現在從左側窗格(在控制台根目錄下,您將看到“證書”選項。單擊它。

7)將出現一個列表,右鍵單擊“受信任的根證書頒發機構”,然后選擇“所有任務”->“導入”

8)在打開的窗口中,點擊下一步,瀏覽步驟1中下載的證書(.p7b)文件(如果找不到,從文件類型下拉菜單中選擇所有文件),然后繼續單擊“下一步”,最后單擊“完成”。 然后保存配置。

->然后寫了下面的代碼:

---------------------------------------------------

using MongoDB.Bson;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
namespace FirstDocDB
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var connectionString = "mongodb://pulkit:password@ClusterID:27017/?ssl=true&sslVerifyCertificate=true&replicaSet=rs0";
            var client = new MongoClient(connectionString);
            var database = client.GetDatabase("test");
            var collection = database.GetCollection("stuff");
            var document = collection.Find(new BsonDocument()).FirstOrDefault();
            Console.WriteLine(document.ToString());
        }
    }
}

---------------------------------------------------

->在構建和運行之后,我成功地獲得了名為“stuff”的集合中的文檔作為輸出: { "_id" : ObjectId("5c5a63b10cf861158c1d241c"), "hello" : "world" }

因此,按照上述步驟操作后,我成功地使用 .Net 的 Mongo 驅動程序連接到文檔數據庫。

我遇到了類似的問題,在 AWS 上開了一張票,並通過與 Pulkit Agarwal 的回答類似的步驟解決了這個問題。

主要變化是連接字符串,即使在將證書添加到本地存儲后,我仍然使用查詢字符串作為“?ssl_ca_certs=rds-combined-ca-bundle.pem&replicaSet=rs0”,需要更改為“?ssl=true&sslVerifyCertificate=true&replicaSet =rs0"

以下示例介紹了如何在啟用/禁用 TLS 的情況下使用 C#(和其他驅動程序)以編程方式連接到 Amazon DocumentDB。

https://docs.aws.amazon.com/documentdb/latest/developerguide/connect.html

這是另一種方式。 但是我發現通過將 SSL 與 C# Mongo 驅動程序一起使用不會進行連接池並為每個調用打開一個新連接。 您可以通過包括 MaxConnectionIdleTime 來減少活動連接,但如果您的應用程序創建了大量連接,它仍然不理想。

    var connectionString = "username:password@cluster_endpoint:27017/?replicaSet=rs0";
    var clientSettings = MongoClientSettings.FromUrl(new MongoUrl("mongodb://" + connectionString));
    var certificatePath = "ssl\rds-combined-ca-bundle.pem";

    var pem = System.IO.File.ReadAllText(AppDomain.CurrentDomain.BaseDirectory + certificatePath);
    byte[] certBuffer = GetBytesFromPEM(pem, "CERTIFICATE");

    clientSettings.UseSsl = true;
    clientSettings.SslSettings = new SslSettings()
    {
        ClientCertificates = new List<X509Certificate2>()
        {
            new X509Certificate2(certBuffer)
        },
        EnabledSslProtocols = System.Security.Authentication.SslProtocols.Default,
        CheckCertificateRevocation = true
        };

    clientSettings.VerifySslCertificate = true;

    clientSettings.SslSettings.ClientCertificateSelectionCallback = (sender, host, certificates, certificate, issuers) => clientSettings.SslSettings.ClientCertificates.ToList()[0];
    clientSettings.SslSettings.ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true;

    clientSettings.MaxConnectionIdleTime = new TimeSpan(0, 0, 30);

    _client = new MongoClient(clientSettings);
    _database = _client.GetDatabase(db.ToString());

值得補充的是,目前 MongoDB C# 驅動程序不支持PEM證書。 因此,任何引用PEM證書的內容都將失敗,並出現System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure.

AWS 開發人員指南建議使用P7B證書,可以從這里下載: https : //s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.p7b

這對我們有用。

在 Kubernetes 和 Windows 上,我們需要將rds-combined-ca-bundlee.p7b到本地信任存儲,如AWS C# 示例所示,並且不要在連接字符串中引用它。

在 Mac 上,由於access denied問題,我一直在努力以編程方式將P7B證書添加到密鑰庫。 如果我設法解決它,將更新答案。


最后值得一提的是,Kenny Dickie 提供的答案基本上關閉了證書驗證並使設置不安全。 這行代碼clientSettings.SslSettings.ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true; 將始終返回true

嘗試將 RDS CA 文件添加到您的 C# 信任存儲中。

            X509Store store = new X509Store(StoreName.Root);
            X509Certificate2 ca = new X509Certificate2(<path_to_rds-combined-ca-bundle.pem>);
            try {
                store.Open(OpenFlags.ReadWrite);
                store.Add(ca);
            } catch (Exception ex) {
                Console.WriteLine("Root certificate import failed: " + ex.Message);
                throw;
            } finally {
                store.Close();
            }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM