配置传输层安全 (TLS)
Overview
在本指南中,您可以学习;了解如何使用 TLS 协议,以保护与MongoDB 部署的连接。
为连接启用TLS 时, C++驾驶员会执行以下操作:
使用 TLS 连接到 MongoDB 部署
验证部署的证书
确保证书证明部署
要学习;了解如何为 TLS 配置MongoDB 部署,请参阅MongoDB Server手册中的TLS 配置指南。
注意
本页假设您已了解 TLS/SSL 并可访问权限有效证书。 TLS/SSL、PKI(公钥基础设施)证书和证书颁发机构 (CA) 的完整描述超出了本文档的范围。
提示
C++驾驶员将大多数 TLS 行为委托给MongoDB C驱动程序。 有关C驾驶员如何处理 TLS 的信息,包括配置步骤和预期行为,请参阅C驾驶员文档中的配置 TLS 。
启用 TLS
要为与MongoDB实例的连接启用TLS,请在连接string中将 tls
连接选项设立为 true
,如以下示例所示:
mongocxx::uri uri("mongodb://<hostname>:<port>/?tls=true");
提示
如果您的连接string包含 +srv
修饰符(指定 SRV 连接格式),则默认情况下会对您的连接启用 TLS。
要学习;了解有关 SRV 连接格式的更多信息,请参阅MongoDB Server文档中的SRV 连接格式。
指定 CA 文件
在 TLS 握手期间,MongoDB 部署会向您的应用程序提供证书密钥文件,以确定其身份。 通常,部署的证书由知名 CA 签名,并且您的应用程序依赖此 CA 来验证证书。
但是,在测试过程中,您可能希望充当自己的 CA。 在这种情况下,您必须指示C++驾驶员使用您的 CA 证书,而不是其他 CA 签名的证书。
为此,请指定包含根证书链的.pem
文件的路径。 您可以通过两种方式执行此操作:在 mongocxx::options::tls
对象上设置属性,或在连接string中使用 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 Server版本而异:
MongoDB v 4.4或更高版本:服务器将带时间戳的 OCSP 响应装订到其证书中。 C++驾驶员根据 OCSP 响应验证证书。 如果 CA 已撤销证书,或者 OCSP 响应无效,则 TLS 握手失败。
MongoDB v 4.3或更早版本:服务器提供C++驾驶员直接联系的 OCSP 端点。 然后, C++驾驶员会根据 OCSP 响应来验证证书。 如果 CA 尚未吊销证书,则即使 OCSP 响应无效或格式不正确,TLS 握手也会继续。
要阻止C++驾驶员联系 OCSP 端点,请在连接string中将 tlsDisableOCSPEndpointCheck
连接选项设立为 true
,如以下代码示例:
mongocxx::uri uri("mongodb://<hostname>:<port>/?tls=true&tlsDisableOCSPEndpointCheck=true");
证书吊销列表
您可以指示C++驾驶员根据 CA 发布的证书吊销列表 (CRL) 检查服务器的证书,而不是使用 OCSP。
以下代码示例演示如何使用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
对象上设置属性,或在连接string中使用 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
对象上设置属性,或在连接string中使用 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,请在连接string中将 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文档: