Overview
在本指南中,您可以了解如何使用TLS 协议保护与 MongoDB 部署的连接。 TLS 是一种加密协议,可保护应用程序与 MongoDB 之间的通信。 要将连接配置为使用 TLS,请启用 TLS 选项并在创建客户端时提供证书以进行验证。
默认下,驾驶员使用 JDK 提供的 TLS/SSL根本的支持来支持与MongoDB服务器的 TLS/SSL 连接。可以通过使用 Netty API或Java SE API的可扩展性来更改此设置。
提示
异步应用程序首选 Netty
我们建议将 Netty 用于异步应用程序,因为它支持异步 I/O 并有效处理高连接量。要学习;了解如何使用 Netty 配置 TLS 设置,请参阅本指南的使用 Netty SslContext 配置 TLS/SSL部分。
启用 TLS/SSL
您可以通过两种不同的方式为MongoDB实例的连接启用TLS/SSL:通过连接字符串中的参数,或使用 MongoClientSettings.Builder
类中的方法。
注意
DNS 种子列表协议启用 TLS
如果您使用 DNS 种子列表协议(由连接字符串中的mongodb+srv
前缀表示)进行连接,则驱动程序会自动启用 TLS/SSL。 要禁用此功能,请在连接字符串中将tls
参数值设置为false
,或者在创建MongoClientSettings
实例时在SslSettings.Builder
区块中将enabled
属性设置为false
。
要进一步了解使用 DNS 种子列表时的连接行为,请参阅服务器手册中的 SRV 连接格式部分。
在使用 ConnectionString 的连接上启用TLS/SSL ,在传递给string tls
true
的连接 中为连接 参数 分配值string MongoClient.create()
:
val mongoClient = MongoClient.create("mongodb+srv://<db_username>:<db_password>@<cluster-url>?tls=true")
要使用 MongoClientSettings.Builder
类来配置 MongoClient
的 TLS/SSL 连接选项,请调用 applyToSslSettings() 方法。在 SslSettings.Builder
区块中将 enabled
属性设置为 true
以启用 TLS/SSL:
val settings = MongoClientSettings.builder() .applyConnectionString(ConnectionString("<connection string>")) .applyToSslSettings { builder -> builder.enabled(true) } .build() val mongoClient = MongoClient.create(settings)
注意
调试 TLS/SSL
如果在建立 TLS/SSL 连接时遇到问题,您可以使用 -Djavax.net.debug=all
系统属性查看更多日志语句。有关更多信息,请参阅 Oracle TLS/SSL 连接调试指南。
配置证书
发起 TLS/SSL 请求的 Kotlin 应用程序需要访问加密证书,以证明应用程序本身以及与该应用程序交互的其他应用程序的身份。 您可以使用以下机制在应用程序中配置对这些证书的访问权限:
JVM 信任存储区与 JVM 密钥存储区
特定于客户端的信任存储和密钥存储
注意
以下部分基于 Oracle JDK 的文档,因此某些部分可能不适用于您的 JDK 或所使用的自定义 TLS/SSL 实施。
配置 JVM 信任存储区
注意
默认情况下,JRE 包含许多来自 Let's Encrypt 等签名机构的常用公共证书。因此,您可以使用 TLS/SSL 连接到 MongoDB Atlas 实例(或由 JRE 默认证书存储区中的授权机构签署证书的任何其他服务器),而无需配置信任存储区。
JVM 信任存储区保存的证书可安全地标识与您的 Kotlin 应用程序交互的其他应用程序。 使用这些证书,您的应用程序可以证明与另一个应用程序的连接是真实的,并且是安全的,不会被第三方篡改。
如果 MongoDB 实例使用的证书由没有位于 JRE 默认证书存储中的颁发机构进行签名,您的应用程序必须配置两个系统属性以启动 SSL/TLS 请求。这些属性确保应用程序可以验证连接的 MongoDB 实例提供的 TLS/SSL 证书。
javax.net.ssl.trustStore
:包含签名机构证书的信任存储区的路径javax.net.ssl.trustStorePassword
:用于访问以下项中定义的信任库的密码:javax.net.ssl.trustStore
您可以使用 JDK 中提供的 keytool 命令行工具来创建信任库:
keytool -importcert -trustcacerts -file <path to certificate authority file> -keystore <path to trust store> -storepass <password>
配置 JVM 密钥存储库
注意
默认情况下,MongoDB 实例不执行客户端证书验证。如果将 MongoDB 实例配置为验证客户端证书,您必须配置密钥存储。
Java虚拟机(JVM)密钥存储区保存的证书可向其他应用程序安全地标识您的 Kotlin 应用程序。使用这些证书,其他应用程序可以证明与您的应用程序的连接是真实的,并且是安全的,不会被第三方篡改。
发起 TLS/SSL 请求的应用程序需要设置两个 JVM 系统属性,以确保客户端向 MongoDB 服务器提供 TLS/SSL 证书:
javax.net.ssl.keyStore
:包含客户端 TLS/SSL 证书的密钥存储区的路径javax.net.ssl.keyStorePassword
:用于访问以下项中定义的密钥库的密码:javax.net.ssl.keyStore
您可以使用 keytool 或 openssl 命令行工具创建密钥存储。
有关配置 Kotlin 应用程序以使用 TLS/SSL 的更多信息,请参阅 JSSE 参考指南。
配置特定于客户端的信任存储和密钥存储
您可以使用 SSLContext
类的 init()
方法配置客户端对应的信任存储区和密钥存储区。
您可以在本指南的使用 SSLContext 进行自定义 TLS/SSL 配置部分找到展示如何使用 SSLContext
实例配置客户端的示例。
有关SSLContext
类的更多信息,请参阅 SSL 上下文的 API 文档。
禁用主机名验证
默认情况下,驱动程序确保服务器的 TLS/SSL 证书中包含的主机名与构建 MongoClient
时提供的主机名匹配。要为应用程序禁用主机名验证,您可以在 applytoSslSettings()
构建器 Lambda 中将构建器的 invalidHostNameAllowed
属性设置为 true
以明确禁用该功能:
val settings = MongoClientSettings.builder() .applyConnectionString(ConnectionString("<connection string>")) .applyToSslSettings { builder -> builder.enabled(true) builder.invalidHostNameAllowed(true) } .build() val mongoClient = MongoClient.create(settings);
警告
禁用主机名验证可能会使您的配置变得不安全。请仅出于测试目的或没有其他替代方法时禁用主机名验证。
将连接限制为仅使用 TLS 1.2
要将应用程序限制为仅使用 TLS 1.2 协议,请将 jdk.tls.client.protocols
系统属性设置为“TLSv1.2”。
注意
Java 8 之前的 Java 运行时环境 (JRE) 仅在更新版本中启用了 TLS 1.2 协议。如果您的 JRE 未启用 TLS 1.2 协议,请升级到更高版本以使用 TLS 1.2 进行连接。
使用 Netty SslContext 配置 TLS/SSL
包括以下 import 语句:
import com.mongodb.MongoClientSettings import com.mongodb.connection.SslSettings import com.mongodb.connection.TransportSettings import com.mongodb.kotlin.client.coroutine.MongoClient import io.netty.handler.ssl.SslContextBuilder import io.netty.handler.ssl.SslProvider
注意
Netty 包版本
驾驶员使用 Netty包版本进行测试 io.netty:netty-all:4.1.87.Final
指示驱动程序使用 io.netty.handler.ssl.SslContext ,配置 NettyTransportSettings 当您定义MongoClientSettings
时。
使用MongoClientSettings.Builder.transportSettings()
和NettyTransportSettings.Builder.sslContext()
构建设置:
val sslContext = SslContextBuilder.forClient() .sslProvider(SslProvider.OPENSSL) .build() val settings = MongoClientSettings.builder() .applyToSslSettings { builder: SslSettings.Builder -> builder.enabled(true) } .transportSettings( TransportSettings.nettyBuilder() .sslContext(sslContext) .build() ) .build() val mongoClient = MongoClient.create(settings);
通过 Java SE SSLContext 自定义 TLS/SSL 配置
如果您的 TLS/SSL 配置需要进行自定义,您可以在 applyToSslSettings()
Lambda 中将一个 SSLContext 对象传递给生成器以设置 MongoClient
的 sslContext
属性:
// You can customize SSL settings using the SSLContext val sslContext = SSLContext.getDefault() val settings = MongoClientSettings.builder() .applyToSslSettings { builder -> builder.enabled(true) builder.context(sslContext) } .build() val mongoClient = MongoClient.create(settings);
在线证书状态协议 (OCSP)
OCSP 是一种用于检查是否已撤销 X.509 证书的标准。证书颁发机构 (CA) 可以在到期时间之前将 X.509 证书添加到证书撤销列表 (CRL) 中,以使该证书失效。当客户端在 TLS 握手期间发送 X.509 证书时,CA 的撤销服务器检查 CRL 并返回“良好”、“已撤销”或“未知”状态。
该驱动程序支持以下 OCSP 变体:
客户端驱动的 OCSP
OCSP 装订 (Stapling)
以下部分描述了变体之间的差异以及如何为您的应用程序启用这些变体。
注意
Kotlin 驱动程序使用为应用程序配置的 Java虚拟机(JVM)MongoClient
参数,并且无法针对特定的实例进行覆盖。
客户端驱动的 OCSP
在客户端驱动的 OCSP 中,客户端在收到服务器发送的证书后,将 OCSP 请求中的证书发送给 OCSP 响应程序。OCSP 响应程序通过证书颁发机构 (CA) 检查证书的状态,并在发送给客户端的响应中报告证书是否有效。
要为您的应用程序启用客户端驱动的 OCSP,请设置以下 JVM 系统属性:
属性 | 值 |
---|---|
| 将此属性设置为 |
| 将此属性设置为 |
警告
如果 OCSP 响应程序不可用,JDK 提供的 TLS 支持会报告“硬故障”。这与 MongoDB Shell 和其他一些驱动程序的“软故障”行为不同。
OCSP 装订 (Stapling)
OCSP 装订是一种机制,在该机制中,服务器必须从证书颁发机构 (CA) 获取签名证书,并将其包含在对客户端的带时间戳的 OCSP 响应中。
要为您的应用程序启用 OCSP 装订,请设置以下 JVM 系统属性:
属性 | 说明 |
---|---|
| 将此属性设置为 |
| Set this property to true to enable OCSP stapling.If unset or set to false , the connection can proceed regardless of the presence or status of the certificate revocation response. |
有关 OCSP 的更多信息,请查看以下资源:
Oracle JDK 8 文档关于如何为应用程序启用 OCSP