我正在尝试通过 SSL 通过 libmongoc 连接到本地 mongodb 实例。如果我不使用 SSL,连接就可以正常工作,并且我可以正常进行 CRUD 操作,但是当我启用 SSL 并尝试检索一些数据时,mongoc_cursor_next()
函数会挂起很长时间,然后以false
.
在服务器端,日志显示,当它卡在函数内部时,客户端连接到服务器,接受连接,断开连接,然后重复,直到几分钟后解除卡住:
2019-02-13T15:34:45.792-0300 I NETWORK [listener] connection accepted from 192.168.25.9:55256 #710 (1 connection now open)
2019-02-13T15:34:45.810-0300 I NETWORK [conn710] received client metadata from 192.168.25.9:55256 conn710: { application: { name: "Test Client" }, driver: { name: "mongoc", version: "1.13.1" }, os: { type: "Linux", name: "Ubuntu", version: "18.10", architecture: "x86_64" }, platform: "cfg=0xa15ea0e9 posix=200809 stdc=201710 CC=GCC 8.2.0 CFLAGS="" LDFLAGS=""" }
2019-02-13T15:34:45.810-0300 I NETWORK [conn710] end connection 192.168.25.9:55256 (0 connections now open)
2019-02-13T15:34:46.311-0300 I NETWORK [listener] connection accepted from 192.168.25.9:55258 #711 (1 connection now open)
2019-02-13T15:34:46.328-0300 I NETWORK [conn711] received client metadata from 192.168.25.9:55258 conn711: { application: { name: "Test Client" }, driver: { name: "mongoc", version: "1.13.1" }, os: { type: "Linux", name: "Ubuntu", version: "18.10", architecture: "x86_64" }, platform: "cfg=0xa15ea0e9 posix=200809 stdc=201710 CC=GCC 8.2.0 CFLAGS="" LDFLAGS=""" }
2019-02-13T15:34:46.328-0300 I NETWORK [conn711] end connection 192.168.25.9:55258 (0 connections now open)
2019-02-13T15:34:46.829-0300 I NETWORK [listener] connection accepted from 192.168.25.9:55260 #712 (1 connection now open)
2019-02-13T15:34:46.843-0300 I NETWORK [conn712] received client metadata from 192.168.25.9:55260 conn712: { application: { name: "Test Client" }, driver: { name: "mongoc", version: "1.13.1" }, os: { type: "Linux", name: "Ubuntu", version: "18.10", architecture: "x86_64" }, platform: "cfg=0xa15ea0e9 posix=200809 stdc=201710 CC=GCC 8.2.0 CFLAGS="" LDFLAGS=""" }
2019-02-13T15:34:46.843-0300 I NETWORK [conn712] end connection 192.168.25.9:55260 (0 connections now open)
我最初认为问题出在我的代码中,因此我使用该-DENABLE_TRACING=1
选项重建了 libmongoc 库,以查看是否可以查明一些可以提供帮助的东西。但是,令我惊讶的是,这“解决了”问题:它不会再挂起mongoc_cursor_next()
,并且文档会正常返回,但跟踪会用过多的调试信息填充标准输出,甚至转储发送/接收的 TCP 数据包。如果我启用跟踪,问题就会消失。如果我禁用跟踪,它会回来。
我尝试通过该mongoc_client_pool_set_ssl_opts
函数设置 SSL 选项,但结果与通过 URI 传递它们相同。我也尝试在客户端上使用证书,但也没有运气。唯一有效的方法是-DENABLE_TRACING=1
在客户端上使用或不使用 SSL 构建 libmongoc。
我不知道使用自签名证书是否与我有关,因为我没有信任签名证书。但我认为这sslAllowInvalidCertificates=true
是忽略这个要求,因为它只是一个带有模拟数据的开发数据库。
我错过了什么吗?
我的环境:
客户端:
Ubuntu 18.10 x64、libmongoc 1.13.1 / 1.9.5(均已测试)、GCC 8.2.0
Windows 10 Pro、libmongoc 1.9.5、MSVC 2015。
服务器:
Ubuntu 18.10 x64
MongoDB 4.0.6(git 版本:caa42a1f75a56c7643d0b68d3880444375ec42e3)
OpenSSL 版本:OpenSSL 1.1.1 2018 年 9 月 11 日
我的示例客户:
int main(int argc, char *argv[])
{
mongoc_init();
mongoc_uri_t *uri = mongoc_uri_new("mongodb://Client:1234@localhost/?authSource=MyDatabase&ssl=true&sslAllowInvalidCertificates=true");
if(!uri)
{
std::cout << "Failed to parse URI";
return 1;
}
mongoc_client_pool_t *pool = mongoc_client_pool_new(uri);
mongoc_client_pool_set_appname(pool, "Test Client");
mongoc_client_pool_set_error_api(pool, MONGOC_ERROR_API_VERSION_2);
mongoc_uri_destroy(uri);
mongoc_client_t *client = mongoc_client_pool_pop(pool);
mongoc_collection_t *col = mongoc_client_get_collection(client, "MyDatabase", "MyCollection");
bson_error_t err;
bson_t *filter = bson_new_from_json(reinterpret_cast<const uint8_t*>("{}"), 2, &err);
bson_t *opts = bson_new_from_json(reinterpret_cast<const uint8_t*>("{}"), 2, &err);
if(!filter || !opts)
return 2;
mongoc_cursor_t *cursor = mongoc_collection_find_with_opts(col, filter, opts, nullptr);
bson_t *bson = nullptr;
while(mongoc_cursor_next(cursor, const_cast<const bson_t **>(&bson)))
std::cout << "Got document!" << std::endl;
mongoc_cursor_destroy(cursor);
mongoc_collection_destroy(col);
mongoc_client_pool_push(pool, client);
mongoc_client_pool_destroy(pool);
mongoc_cleanup();
return 0;
}
我的服务器配置(mongod.conf):
# mongod.conf
# for documentation of all options, see:
# http://docs.mongodb.org/manual/reference/configuration-options/
# Where and how to store data.
storage:
dbPath: /var/lib/mongodb
journal:
enabled: true
# engine:
# mmapv1:
# wiredTiger:
# where to write logging data.
systemLog:
destination: file
logAppend: true
path: /var/log/mongodb/mongod.log
# network interfaces
net:
port: 27017
bindIp: 0.0.0.0
ssl:
mode: allowSSL
PEMKeyFile: /home/tyras/mongodb.pem
allowConnectionsWithoutCertificates: true
allowInvalidCertificates: true
# how the process runs
processManagement:
timeZoneInfo: /usr/share/zoneinfo
#security:
security:
authorization: enabled
#operationProfiling:
#replication:
#sharding:
## Enterprise-Only Options:
#auditLog:
#snmp:
编辑:
经过进一步测试,我发现在没有池的情况下连接时,它不会卡在mongoc_cursor_next()
. 但失败,并mongoc_cursor_error()
返回:
Error 13053: No suitable servers found (`serverSelectionTryOnce` set): [Failed to receive length header from server. calling ismaster on 'localhost:27017']
此外,我可以通过 SSL 与 mongo CLI 和 Compass 正常连接。