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