Overview
在本指南中,您可以了解如何使用TLS 协议保护与 MongoDB 部署的连接。 TLS 是一种加密协议,可保护应用程序与 MongoDB 之间的通信。 要将连接配置为使用 TLS,请启用 TLS 选项并在创建客户端时提供证书以进行验证。
注意
本页假设您已了解 TLS/SSL 并可访问权限有效证书。TLS/SSL、PKI(公钥基础设施)证书和证书颁发机构 (CA) 的完整描述超出了本文档的范围。要学习;了解有关 TLS 的更多信息,请参阅传输层安全性的维基百科条目。
为连接启用TLS 时, Scala驱动程序会执行以下操作:
使用 TLS 连接到 MongoDB 部署
验证部署的证书
要学习;了解如何为 TLS 配置MongoDB 部署,请参阅MongoDB Server手册中的TLS 配置指南。
默认情况下,驱动程序使用 JDK 提供的 TLS/SSL 根本支持来支持与 MongoDB 服务器的 TLS/SSL 连接。这可以通过使用Netty API或Java SE API的可扩展性来更改。
提示
异步应用程序首选 Netty
对于异步应用程序,我们建议使用 Netty,因为它支持异步 I/O 并有效处理高连接量。要学习;了解如何使用 Netty 配置 TLS 设置,请参阅本指南的使用 Netty SslContext 配置 TLS/SSL部分。
启用 TLS
您可以通过以下方式为MongoDB 部署的连接启用TLS:
创建
MongoClientSettings实例时使用SslSettings.Builder类中的enabled()方法在连接 URI 中设置
tls参数
选择 MongoClientSettings 或 Connection URI标签页,查看启用 TLS 的相应代码:
val tlsUri = "mongodb://localhost:27017/" val tlsSettings = MongoClientSettings.builder() .applyConnectionString(ConnectionString(tlsUri)) .applyToSslSettings(builder => builder.enabled(true)) .build() val tlsClient1 = MongoClient(tlsSettings)
val tlsClient2 = MongoClient("mongodb://localhost:27017/?tls=true")
提示
如果您的连接string包含 +srv 修饰符(指定 SRV 连接格式),则默认情况下会对您的连接启用 TLS。
要学习;了解有关 SRV 连接格式的更多信息,请参阅MongoDB Server文档中的SRV 连接格式。
配置证书
注意
这些部分中的说明基于Oracle JDK 的文档。 它们可能应用用于您的 JDK 或自定义 TLS/SSL实施。
发起 TLS 请求的Scala应用程序需要访问权限加密证书,以证明应用程序的身份并验证与Scala应用程序交互的其他应用程序。 您可以通过以下方式在应用程序中配置对这些证书的访问权限:
使用Java虚拟机(JVM)信任存储和Java虚拟机(JVM)密钥存储
使用特定于客户端的信任存储和密钥存储
配置 JVM 信任存储区
Java虚拟机(JVM)信任存储保存的证书可安全地标识与您的Scala应用程序交互的其他应用程序。 通过使用这些证书,您的应用程序可以证明与另一个应用程序的连接是真实的,并且是安全的,不会被第三方篡改。
Java运行时环境 (JRE) 提供了一个默认证书存储,其中包括来自签名机构的常用公共证书。 如果您的MongoDB 部署使用由 JRE默认证书存储中不存在的颁发机构签名的证书,则您的应用程序必须配置以下系统属性才能发起 TLS 请求:
javax.net.ssl.trustStore:包含签名机构证书的信任存储区的路径javax.net.ssl.trustStorePassword:用于访问权限由javax.net.ssl.trustStore属性定义的信任存储的密码
您可以使用keytool命令行工具来定义上述属性。以下示例运行 keytool 命令以指定证书颁发机构文件路径、信任存储路径和信任存储密码:
keytool -importcert -trustcacerts -file <path to certificate authority file> -keystore <path to trust store> -storepass <trust store password>
配置 JVM 密钥存储库
注意
默认情况下,MongoDB 实例不执行客户端证书验证。如果将 MongoDB 实例配置为验证客户端证书,您必须配置密钥存储。
发起 TLS 请求的应用程序必须设立以下Java虚拟机(JVM)系统属性,以确保客户端向MongoDB服务器提供 TLS 证书:
javax.net.ssl.keyStore:包含客户端 TLS/SSL 证书的密钥存储区的路径javax.net.ssl.keyStorePassword:用于访问以下项中定义的密钥库的密码:javax.net.ssl.keyStore
您可以使用keytool或openssl命令行工具创建密钥存储。
要学习;了解有关配置Scala应用程序以使用 TLS 的更多信息,请参阅Java语言文档中的JSSE 参考指南。
配置特定于客户端的信任存储和密钥存储
您可以使用SSLContext类的init()方法配置客户端特定的信任存储和密钥存储。
要查看将客户端配置为使用SSLContext 实例的示例,请参阅本指南的“使用 SSLContext 自定义配置”部分。
禁用主机名验证
默认情况下,驱动程序确保服务器的 TLS 证书中包含的主机名与构造 MongoClient 时提供的主机名匹配。您可以通过以下方式禁用主机名验证:
创建
MongoClientSettings实例时使用SslSettings.Builder类中的invalidHostNameAllowed()方法在连接 URI 中设置
tlsAllowInvalidHostnames参数
选择 MongoClientSettings 或 Connection URI标签页,查看禁用主机名验证的相应代码:
val invalidHostUri = "mongodb://localhost:27017/" val invalidHostSettings = MongoClientSettings.builder() .applyConnectionString(ConnectionString(invalidHostUri)) .applyToSslSettings(builder => builder .enabled(true) .invalidHostNameAllowed(true) ) .build() val invalidHostClient1 = MongoClient(invalidHostSettings)
val invalidHostClient2 = MongoClient("mongodb://localhost:27017/?tls=true&tlsAllowInvalidHostnames=true")
警告
禁用主机名验证会使应用程序不安全,并且可能容易受到过期证书和冒充有效客户端实例的外部进程的攻击。
限制与 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 io.netty.handler.ssl.SslContextBuilder import io.netty.handler.ssl.SslProvider import org.mongodb.scala.connection.TransportSettings
注意
Netty 包版本
驱动程序使用 Netty包版本进行测试 io.netty:netty-all:4.1.87.Final
要指示驱动程序使用 io.netty.handler.ssl.SslContext,请在定义 MongoClientSettings 时配置 NettyTransportSettings。
使用MongoClientSettings.Builder.transportSettings()和NettyTransportSettings.Builder.sslContext()构建设置:
val sslContext = SslContextBuilder.forClient() .sslProvider(SslProvider.OPENSSL) .build() val nettySettings = MongoClientSettings.builder() .applyToSslSettings { builder => builder.enabled(true) } .transportSettings( TransportSettings.nettyBuilder() .sslContext(sslContext) .build() ) .build() val mongoClient = MongoClient(nettySettings);
使用 SSLContext 自定义配置
如果您的 TLS 配置需要自定义,您可以设立MongoClient对象的 sslContext属性。 将 SSLContext对象传递给 applyToSslSettings()区块中的 context() 方法构建器,如以下代码所示:
val sslContext = SSLContext.getDefault() val contextSettings = MongoClientSettings.builder() .applyToSslSettings(builder => builder .enabled(true) .context(sslContext) ) .build() val mongoClient = MongoClient(contextSettings);
有关 SSLContext 类的更多信息,请参阅 SSL 上下文 的API文档。
在线证书状态协议 (OCSP)
OCSP 是用于检查 X.509 证书是否已被撤销的标准。 证书颁发机构 (CA) 可以在到期时间之前将 X.509 证书添加到证书吊销列表 (CRL),以使该证书失效。 当客户端在 TLS 握手期间发送 X.509 证书时,CA 的吊销服务器会检查 CRL 并返回 good、revoked 或 unknown 状态。
该驱动程序支持以下 OCSP 变体:
客户端驱动的 OCSP
OCSP 装订 (Stapling)
以下部分描述了这些变体,并展示了如何为您的应用程序启用它们。
注意
Scala驱动程序使用为应用程序配置的Java虚拟机(JVM)参数,这些参数不能针对特定的 MongoClient实例进行覆盖。
注意
Let's Encrypt OCSP 已弃用
Let's Encrypt 已经结束对较新证书的 OCSP 支持。Let's Encrypt 颁发的新证书可能不包含 OCSP 响应端 URL。OCSP 撤销检查仅在证书包含 OCSP URI 时发生,因此,缺失 OCSP URL 是预期的,并不一定表明 MongoDB 部署存在问题。
客户端驱动的 OCSP
在客户端驱动的 OCSP 中,客户端从服务器接收证书,并在 OCSP请求中将此证书发送到 OCSP 响应程序。 OCSP 响应程序通过 CA 检查证书的状态,并向客户端发送有关其有效性的报告。
要为您的应用程序启用客户端驱动的 OCSP,请设置以下 JVM 系统属性:
属性 | 说明 |
|---|---|
| 将此属性设置为 |
| 将此属性设置为 |
警告
如果 OCSP 响应程序不可用,JDK 提供的 TLS 支持会报告“硬故障”。这与 MongoDB Shell 和其他一些驱动程序的“软故障”行为不同。
OCSP 装订 (Stapling)
OCSP 装订是一种机制,服务器必须从 CA 获取签名证书,并将其包含在对客户端的带时间戳的 OCSP 响应中。
要为您的应用程序启用 OCSP 装订,请设置以下 JVM 系统属性:
属性 | 说明 |
|---|---|
| 将此属性设置为 |
| 将此属性设置为 |
要学习;了解有关 OCSP 的更多信息,请查看以下资源:
API 文档
有关本指南中讨论的任何类型的更多信息,请参阅以下API文档: