libmongoc を介して SSL 経由でローカル 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)
最初は自分のコードに問題があると思っていたので、オプションを指定して libmongoc ライブラリを再構築し、-DENABLE_TRACING=1
役立つものを特定できるかどうかを確認しました。しかし、驚いたことに、これで問題が「修正」されました。 でハングすることはなくmongoc_cursor_next()
なり、ドキュメントは正常に返されますが、トレースによって stdout が過剰なデバッグ情報でいっぱいになり、送受信された TCP パケットがダンプされます。トレースを有効にすると、問題はなくなります。トレースを無効にすると、元に戻ります。
関数を介して SSL オプションを設定しようとしましたmongoc_client_pool_set_ssl_opts
が、結果は URI を介してそれらを渡すのと同じです。クライアントでも証明書を使用しようとしましたが、うまくいきませんでした。機能した唯一のことは、クライアントで SSL を使用して libmongoc を構築するか、-DENABLE_TRACING=1
SSL を使用しないことでした。
私は信頼署名証明書を持っていないので、自己署名証明書を使用していることに関連するものかどうかはわかりません。しかし、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']
また、mongo CLI と Compass を使用して、SSL 経由で正常に接続できます。