配置传输层安全性(TLS)
概述
在本指南中,您可以学习如何使用TLS 协议来确保您与MongoDB部署的连接安全。
当您为连接启用TLS时,C++驱动会执行以下操作
使用TLS连接到MongoDB部署
验证部署的证书
确保证书已验证部署
有关如何配置MongoDB部署的TLS的说明,请参阅MongoDB服务器手册中的TLS配置指南。
注意
本页面假定您已了解TLS/SSL以及如何获取有效证书。TLS/SSL、PKI(公共密钥基础设施)证书和证书颁发机构(CA)的完整描述超出了本文档的范围。
提示
C++驱动将大多数TLS行为委托给MongoDB C驱动。有关C驱动如何处理TLS的信息,包括配置步骤和预期行为,请参阅C驱动文档中的配置TLS。
启用TLS
要为连接到您的MongoDB实例启用TLS,请在连接字符串中将tls
连接选项设置为true
,如下例所示
mongocxx::uri uri("mongodb://<hostname>:<port>/?tls=true");
提示
如果您的连接字符串包含+srv
修改,指定SRV连接格式,则默认启用连接中的TLS。
有关SRV连接格式的更多信息,请参阅MongoDB服务器文档中的SRV连接格式。
指定CA文件
在TLS握手过程中,MongoDB部署向您的应用程序展示证书密钥文件以建立其身份。通常,部署的证书已由知名的CA签名,您的应用程序依赖于此CA来验证证书。
然而,在测试期间,您可能想充当自己的CA。在这种情况下,您必须指示C++驱动使用您的CA证书,而不是由其他CA签名的证书。
为此,指定包含根证书链的.pem
文件的路径。您可以通过两种方式完成此操作:通过在mongocxx::options::tls
对象上设置属性,或通过在连接字符串中使用tlsCAFile
参数。
mongocxx::options::client client_options; mongocxx::options::tls tls_options; tls_options.pem_file("/path/to/file.pem"); client_options.tls_opts(tls_options); mongocxx::uri uri("mongodb://<hostname>:<port>/?tls=true"); mongocxx::client client(uri, client_options);
mongocxx::uri uri("mongodb://<hostname>:<port>/?tls=true&tlsCAFile=/path/to/file.pem");
指定CA目录
如果您使用OpenSSL或LibreSSL(libtls)进行TLS支持,也可以指示C++驱动程序在目录中搜索CA文件。如果驱动程序在tlsCAFile
或pem_file
选项指定的路径中找不到CA文件,则会搜索此目录。
以下代码示例展示了如何使用ca_dir
选项指定驱动程序应搜索的目录
mongocxx::options::client client_options; mongocxx::options::tls tls_options; tls_options.ca_dir("/path/to/search/"); client_options.tls_opts(tls_options); mongocxx::uri uri("mongodb://<hostname>:<port>/?tls=true"); mongocxx::client client(uri, client_options);
提示
此选项对应于OpenSSL的SSL_CTX_load_verify_locations参数和LibreSSL的tls_config_set_ca_path参数。
检查证书吊销
当X.509证书不再可信时——例如,如果其私钥已被泄露——CA会吊销该证书。C++驱动程序提供了两种方法来检查服务器的证书是否已被吊销。
OCSP
在线证书状态协议(OCSP)的过程取决于您连接到的MongoDB服务器版本
MongoDB v4.4或更高版本:服务器将带有时间戳的OCSP响应附加到其证书。C++驱动程序将证书与OCSP响应进行验证。如果CA已吊销证书,或OCSP响应无效,TLS握手将失败。
MongoDB v4.3或更早版本:服务器提供OCSP端点,C++驱动程序直接联系该端点。然后C++驱动程序将证书与OCSP响应进行验证。如果CA未吊销证书,即使OCSP响应无效或格式错误,TLS握手也会继续。
要阻止C++驱动程序联系OCSP端点,在连接字符串中将tlsDisableOCSPEndpointCheck
连接选项设置为true
,如下面的代码示例所示
mongocxx::uri uri("mongodb://<hostname>:<port>/?tls=true&tlsDisableOCSPEndpointCheck=true");
证书吊销列表
您可以使用证书吊销列表(CRL)代替OCSP,让C++驱动程序检查服务器的证书是否与CA发布的CRL相匹配。
以下代码示例显示了如何使用crl_file
选项来指定CA的.pem
文件的路径
mongocxx::options::client client_options; mongocxx::options::tls tls_options; tls_options.crl_file("/path/to/file.pem"); client_options.tls_opts(tls_options); mongocxx::uri uri("mongodb://<hostname>:<port>/?tls=true"); mongocxx::client client(uri, client_options);
提示
您可以在.pem
或.der
格式中指定一个CRL文件。
提供客户端证书
某些MongoDB部署要求每个连接的应用程序都提供客户端证书以证明其身份。为了指定C++驱动程序提供的客户端证书,请指定包含您的证书和私钥的.pem
文件的路径。
您可以通过以下两种方式完成此操作:通过在mongocxx::options::tls
对象上设置属性,或者通过在您的连接字符串中使用tlsCertificateKeyFile
参数。
mongocxx::options::client client_options; mongocxx::options::tls tls_options; tls_options.pem_file("/path/to/file.pem"); client_options.tls_opts(tls_options); mongocxx::uri uri("mongodb://<hostname>:<port>/?tls=true"); mongocxx::client client(uri, client_options);
mongocxx::uri uri("mongodb://<hostname>:<port>/?tls=true&tlsCertificateKeyFile=/path/to/file.pem");
重要
您的客户端证书和私钥必须在同一个.pem
文件中。如果它们存储在不同的文件中,您必须将它们连接起来。以下示例显示了如何在Unix系统上将密钥文件和证书文件连接到第三个文件combined.pem
中。
cat key.pem cert.pem > combined.pem
提供密钥密码
如果您的证书文件中的私钥被加密,您必须提供密码。您可以通过以下两种方式完成此操作:通过在mongocxx::options::tls
对象上设置属性,或者通过在您的连接字符串中使用tlsCertificateKeyFilePassword
参数。
mongocxx::options::client client_options; mongocxx::options::tls tls_options; tls_options.pem_file("/path/to/file.pem"); tls_options.pem_password("<password>"); client_options.tls_opts(tls_options); mongocxx::uri uri("mongodb://<hostname>:<port>/?tls=true"); mongocxx::client client(uri, client_options);
mongocxx::uri uri("mongodb://<hostname>:<port>/?tls=true&tlsCertificateKeyFile=/path/to/file.pem&tlsCertificateKeyFilePassword=<password>");
允许不安全的TLS
当启用TLS时,C++驱动程序会自动验证服务器提供的证书。在测试代码时,您可以禁用此验证。这被称为不安全TLS。
当不安全TLS启用时,驱动程序只要求服务器提供一个X.509证书。即使以下任何一项为真,驱动程序也接受证书
服务器的主机名与证书上的主题名(或主题备用名)不匹配。
证书已过期或尚未生效。
证书链中没有受信任的根证书。
证书用途对服务器识别无效。
注意
即使启用了不安全TLS,客户端与服务器之间的通信也是通过TLS加密的。
要启用不安全TLS,将连接字符串中的tlsInsecure
连接选项设置为true
,如下面的代码示例所示
mongocxx::uri uri("mongodb://<hostname>:<port>/?tls=true&tlsInsecure=true");
要仅禁用证书验证,将tlsAllowInvalidCertificates
选项设置为true
,并将tlsInsecure
选项设置为false
(或省略它)
mongocxx::options::client client_options; mongocxx::options::tls tls_options; tls_options.allow_invalid_certificates(true); client_options.tls_opts(tls_options); mongocxx::uri uri("mongodb://<hostname>:<port>/?tls=true"); mongocxx::client client(uri, client_options);
mongocxx::uri uri("mongodb://<hostname>:<port>/?tls=true&tlsAllowInvalidCertificates=true");
要仅禁用主机名验证,将tlsAllowInvalidHostnames
选项设置为true
,并将tlsInsecure
选项设置为false
(或省略它)
mongocxx::uri uri("mongodb://<hostname>:<port>/?tls=true&tlsAllowInvalidHostnames=true");
警告
不要在生产环境中使用
在生产环境中,始终将tlsInsecure
、tlsAllowInvalidCertificates
和tlsAllowInvalidHostnames
选项设置为false
。
在生产环境中设置任何这些选项为true
会使您的应用程序不安全,并可能容易受到过期证书和伪装成有效客户端实例的外部进程的攻击。
API文档
有关为C++驱动程序配置TLS的更多信息,请参阅以下API文档