MongoDB 通过 SSL 连接:我做错了什么?
MongoDB connecting over SSL: What am I doing wrong?
概述:我有一个应用服务器运行ningPHP7、连接到一个单独的数据库服务器运行ningMongoDB 3.6.x 使用 MongoDB PHP 用户空间库。我有防火墙规则阻止从除本地和专用接口之外的所有来源访问 MongoDB 服务器(即不允许 public IP 访问)。
通过 PHP 的连接看起来像这样:
$context_information = array(
"ssl" => array(
"allow_self_signed" => false,
"verify_peer" => true,
"verify_peer_name" => true,
"verify_expiry" => true,
"cafile" => "/path/to/ca_bundle"
));
$context = stream_context_create($context_information);
$connection = new MongoDB\Client(
$host,
array('ssl'=>true),
array('context'=> $context)
);
我的 MongoDB 配置看起来像这样:
net:
port: 27017
bindIp: 127.0.0.1,10.138.196.241
ssl:
mode: requireSSL
PEMKeyFile: /path/to/my_ca_signed_cert
CAFile: /path/to/my_ca_bundle
my_ca_signed_cert
是使用我的 openssl 生成的 RSA 私钥生成的 .pem
文件,以及 CA 提供的 .crt
文件,按照 MongoDB 手册,例如cat mongodb.key mongodb.crt > mongodb.pem
。 my_ca_bundle
是CA提供给我的.ca-bundle
。
此外,PHP 上下文中描述的 ca_bundle
与 MongoDB 配置中的 .ca-bundle
文件相同。
问题: 我继续收到以下错误:
[23-Jul-2018 16:33:33 America/Los_Angeles] PHP Fatal error: Uncaught MongoDB\Driver\Exception\ConnectionTimeoutException: No suitable servers found (serverSelectionTryOnce
set): [TLS handshake failed: error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed calling ismaster on. . .
即使我注释掉 MongoDB 配置的 CAFile
行,这个问题仍然存在。还要注意的是,如果 CAFile
被注释掉,我可以在将 allow_self_signed
设置为 true
时成功连接,但如果未注释则不能。
最后,当尝试通过 MongoDB shell 连接时,出现以下错误:
2018-07-23T23:37:02.992+0000 E NETWORK [thread1] SSL peer certificate validation failed: unable to get issuer certificate
2018-07-23T23:37:02.992+0000 E QUERY [thread1] Error: socket exception [CONNECT_ERROR] for SSL peer certificate validation failed: unable to get issuer certificate :
connect@src/mongo/shell/mongo.js:251:13
@(connect):1:6
exception: connect failed
预期行为:我不想使用客户端证书身份验证来连接到数据库。我现在想要的只是对流量进行加密。这意味着无需允许自签名证书即可连接到数据库。
备注:
我已在应用程序服务器上成功设置了一个用于 HTTPS 连接的证书。此外,在测试这个问题本身引用的证书时,我已经使用 openssl verify -CAfile /path/to/my_ca_bundle /path/to/my_ca_signed_cert
.
成功地 运行 验证了文件
禁用 SSL 或启用 SSL 并允许自签名证书时,我的应用程序代码中的所有内容均有效。
关于所有这些的文档在很多方面都非常模糊,所以我不确定我的配置哪里出了问题。我应该研究什么来解决这个问题?
我认为您可以尝试将选项 allowConnectionsWithoutCertificates
添加到 ssl 配置中。您的连接已加密但忽略了证书身份验证。
net:
port: 27017
bindIp: 127.0.0.1,10.138.196.241
ssl:
mode: requireSSL
PEMKeyFile: /path/to/my_ca_signed_cert
CAFile: /path/to/my_ca_bundle
allowConnectionsWithoutCertificates: true
更多信息在这里:
我决定再次破解这个问题,终于找到了解决办法。
首先,我需要将我的 /path/to/my_ca_bundle
移动到 /usr/share/ca-certificates/my_project/my_ca_bundle
。
其次,我需要用 my_project/my_ca_bundle
行更新 /etc/ca-certificates.conf
。
第三,我需要运行sudo update-ca-certificates
。
最后,我需要从我的 PHP 流上下文中删除 ssl.cafile
选项(我似乎无法让它在适当的位置工作)。
/etc/mongod.conf
中的 CAFile
选项也是不必要的,并且有问题,除非它使用其他答案中提到的 allowConnectionsWithoutCertificates: true
行。
那是一团糟,但现在一切正常!
概述:我有一个应用服务器运行ningPHP7、连接到一个单独的数据库服务器运行ningMongoDB 3.6.x 使用 MongoDB PHP 用户空间库。我有防火墙规则阻止从除本地和专用接口之外的所有来源访问 MongoDB 服务器(即不允许 public IP 访问)。
通过 PHP 的连接看起来像这样:
$context_information = array(
"ssl" => array(
"allow_self_signed" => false,
"verify_peer" => true,
"verify_peer_name" => true,
"verify_expiry" => true,
"cafile" => "/path/to/ca_bundle"
));
$context = stream_context_create($context_information);
$connection = new MongoDB\Client(
$host,
array('ssl'=>true),
array('context'=> $context)
);
我的 MongoDB 配置看起来像这样:
net:
port: 27017
bindIp: 127.0.0.1,10.138.196.241
ssl:
mode: requireSSL
PEMKeyFile: /path/to/my_ca_signed_cert
CAFile: /path/to/my_ca_bundle
my_ca_signed_cert
是使用我的 openssl 生成的 RSA 私钥生成的 .pem
文件,以及 CA 提供的 .crt
文件,按照 MongoDB 手册,例如cat mongodb.key mongodb.crt > mongodb.pem
。 my_ca_bundle
是CA提供给我的.ca-bundle
。
此外,PHP 上下文中描述的 ca_bundle
与 MongoDB 配置中的 .ca-bundle
文件相同。
问题: 我继续收到以下错误:
[23-Jul-2018 16:33:33 America/Los_Angeles] PHP Fatal error: Uncaught MongoDB\Driver\Exception\ConnectionTimeoutException: No suitable servers found (
serverSelectionTryOnce
set): [TLS handshake failed: error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed calling ismaster on. . .
即使我注释掉 MongoDB 配置的 CAFile
行,这个问题仍然存在。还要注意的是,如果 CAFile
被注释掉,我可以在将 allow_self_signed
设置为 true
时成功连接,但如果未注释则不能。
最后,当尝试通过 MongoDB shell 连接时,出现以下错误:
2018-07-23T23:37:02.992+0000 E NETWORK [thread1] SSL peer certificate validation failed: unable to get issuer certificate
2018-07-23T23:37:02.992+0000 E QUERY [thread1] Error: socket exception [CONNECT_ERROR] for SSL peer certificate validation failed: unable to get issuer certificate :
connect@src/mongo/shell/mongo.js:251:13
@(connect):1:6
exception: connect failed
预期行为:我不想使用客户端证书身份验证来连接到数据库。我现在想要的只是对流量进行加密。这意味着无需允许自签名证书即可连接到数据库。
备注:
我已在应用程序服务器上成功设置了一个用于 HTTPS 连接的证书。此外,在测试这个问题本身引用的证书时,我已经使用
成功地 运行 验证了文件openssl verify -CAfile /path/to/my_ca_bundle /path/to/my_ca_signed_cert
.禁用 SSL 或启用 SSL 并允许自签名证书时,我的应用程序代码中的所有内容均有效。
关于所有这些的文档在很多方面都非常模糊,所以我不确定我的配置哪里出了问题。我应该研究什么来解决这个问题?
我认为您可以尝试将选项 allowConnectionsWithoutCertificates
添加到 ssl 配置中。您的连接已加密但忽略了证书身份验证。
net:
port: 27017
bindIp: 127.0.0.1,10.138.196.241
ssl:
mode: requireSSL
PEMKeyFile: /path/to/my_ca_signed_cert
CAFile: /path/to/my_ca_bundle
allowConnectionsWithoutCertificates: true
更多信息在这里:
我决定再次破解这个问题,终于找到了解决办法。
首先,我需要将我的 /path/to/my_ca_bundle
移动到 /usr/share/ca-certificates/my_project/my_ca_bundle
。
其次,我需要用 my_project/my_ca_bundle
行更新 /etc/ca-certificates.conf
。
第三,我需要运行sudo update-ca-certificates
。
最后,我需要从我的 PHP 流上下文中删除 ssl.cafile
选项(我似乎无法让它在适当的位置工作)。
/etc/mongod.conf
中的 CAFile
选项也是不必要的,并且有问题,除非它使用其他答案中提到的 allowConnectionsWithoutCertificates: true
行。
那是一团糟,但现在一切正常!