Не удается подключиться к базе данных AWS с использованием TLS с проверкой CA сервера
В документации AWS говорится, что для подключения к моему кластеру DocumentDB мне нужно использовать строку запроса, которая заканчивается следующим образом ?ssl_ca_certs=rds-combined-ca-bundle.pem&replicaSet=rs0
, Это цепочка корневых сертификатов, которую должен проверить мой клиент. Мне не нужен сертификат клиента.
Используя драйвер MongoDB C# и этот конкретный запрос, с .pem
файл в том же каталоге, я не могу установить соединение. Если я использую то же самое .pem
файл и строку запроса из оболочки Mongo, я могу правильно подключиться к моей базе данных. Он не работает только с моим основным приложением.net, которое также работает на AWS.
Удаление TLS из кластера и удаление ssl_ca_certs
Опция из запроса, я могу правильно подключиться к моему кластеру.
Я думал, что смогу преобразовать .pem
подать в .pfx
с помощью openssl
, но я должен дать .pfx
пароль и документация MongoDB гласит, что
Обязательно, чтобы при загрузке сертификата с паролем свойство PrivateKey не было нулевым. Если свойство имеет значение null, это означает, что ваш сертификат не содержит закрытого ключа и не будет передан на сервер.
Как я могу использовать .pem
файл, предоставленный Amazon AWS для подключения к моей базе данных с помощью драйвера C# MongoDB?
3 ответа
### Подключение к БД документов с помощью простого.Net консольного приложения с SSL.
-> Прежде всего, включите SSL в вашем кластере БД документов, установив для параметра tls значение "включено". Обязательно перезагрузите узел записи вашего кластера, чтобы перезагрузить весь кластер, чтобы применить изменения группы параметров. По умолчанию TLS включен, когда вы запускаете новый кластер Doc DB.
-> Настройка SSL-сертификата в вашей среде:
1) Загрузите SSL-сертификат PKCS#7 на вашем компьютере с Windows по ссылке ниже:
https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.p7b
2) Нажмите на меню "Пуск", нажмите "Выполнить" и введите mmc
3) В MMC Файл-> Добавить / Удалить оснастку.
4) Выберите Certificates из списка оснасток и нажмите Add.
5) Сертификаты доверенного ЦС должны находиться в хранилище локального компьютера, поэтому выберите переключатель "Учетная запись компьютера", нажмите "Далее" и затем выберите "Локальный компьютер". Нажмите Далее, а затем Готово.
6) Теперь из левой панели (в разделе Корень консоли вы увидите опцию "Сертификаты". Нажмите на нее.
7) Появится список, щелкните правой кнопкой мыши "Доверенные корневые центры сертификации" и выберите "Все задачи" -> "Импорт".
8) В открывшемся окне нажмите кнопку "Далее", найдите файл сертификата (.p7b), загруженный на шаге 1(если вы не можете его найти, в раскрывающемся списке "Тип файла" выберите "Все файлы"), а затем нажмите "Продолжить". нажмите Next и наконец Finish. Затем сохраните конфигурацию.
-> Затем написал следующий код:
---------------------------------------------------
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" }
Таким образом, выполнив вышеуказанные шаги, я успешно смог подключиться к БД документов с помощью драйвера Mongo для.Net.
Стоит добавить, что в настоящее время драйвер 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 мне не удалось добавить
P7B
сертификат в хранилище ключей программно из-за
access denied
проблема. Обновлю ответ, если мне удастся его решить.
Последнее, что стоит упомянуть, ответ, предоставленный Кенни Дики, по существу отключает проверку сертификата и делает установку небезопасной. Эта строка кода
clientSettings.SslSettings.ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true;
всегда вернусь
true
.
У меня была похожая проблема, у меня был открыт билет с AWS, и он был решен с помощью шагов, аналогичных ответу Пулькита Агарвала.
Основным изменением была строка подключения, даже после добавления сертификата в локальное хранилище я все еще использовал строку запроса как "? Ssl_ca_certs=rds-комбинированный-ca-bundle.pem&replicaSet=rs0", которую необходимо изменить на "? Ssl=true&sslVerifyCertificate=true&replicaSet". = rs0"
Вот примеры того, как программно подключиться к Amazon DocumentDB с помощью C# (и других драйверов) с включенным / отключенным TLS.
https://docs.aws.amazon.com/documentdb/latest/developerguide/connect.html
Попробуйте добавить файл 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();
}
Вот другой способ. Однако я обнаружил, что при использовании 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());
@Karthirk, вы можете поделиться кодом, использованным для создания MongoClient. В подозрении проблема есть. Можете ли вы попробовать следующее в URI: ?ssl=true&replicaSet=rs0
ssl_ca_certs=rds-combined-ca-bundle.pem
не работает для драйверов Java/C#/Scala. Для них вам необходимо импортировать файл CA RDS в хранилище доверенных языков (для C# этот код приведен выше)
У меня похожая проблема.
1) Я добавил сертификат в пользовательский магазин сертификатов
2) пробовал строку подключения с опцией ssl cert? Ssl_ca_certs =rds-комбинированный-ca-bundle.pem & replicaSet=rs0 и без опции ssl cert? ReplicaSet =rs0
Ниже приведен код, который я пытаюсь выполнить.
IMongoDatabase db = client.GetDatabase("Test");
var collList = db.ListCollections().ToList();
Console.WriteLine("The list of collections are :");
foreach (var item in collList)
{
Console.WriteLine(item);
}
Любая помощь для устранения неполадок это будет оценено.