0

Using Mongo Atlas M0 free tier.

I have recently implemented mongo client side field level encryption (csfle). The implementation was successful but problem started after that.

As par documentation, to implement csfle, we have to provide the connection setting when we create new mongoClient instance. The settings include KMS Provider, KeyVaultNamespace and Schemamap.

I wanted to implement encryption for three different collections, so i have to create new mongoclient instance everytime as the settings parameters are different.

I have implemented all this successfully but after deployment, i have started receiving mongo connection error.

Encryption related exception: A timeout occurred after 10000ms selecting a server using CompositeServerSelector{ Selectors = MongoDB.Driver.MongoClient+AreSessionsSupportedServerSelector, LatencyLimitingServerSelector{ AllowedLatencyRange = 00:00:00.0150000 }, OperationsCountServerSelector }. Client view of cluster state is { ClusterId : "3", Type : "Unknown", State : "Disconnected", Servers : [{ ServerId: "{ ClusterId : 3, EndPoint : "Unspecified/localhost:27020" }", EndPoint: "Unspecified/localhost:27020", ReasonChanged: "Heartbeat", State: "Disconnected", ServerVersion: , TopologyVersion: , Type: "Unknown", HeartbeatException: "MongoDB.Driver.MongoConnectionException: An exception occurred while opening a connection to the server.
 ---> System.Net.Internals.SocketExceptionFactory+ExtendedSocketException (111): Connection refused 127.0.0.1:27020
   at System.Net.Sockets.Socket.EndConnect(IAsyncResult asyncResult)
   at System.Net.Sockets.Socket.<>c.<ConnectAsync>b__274_0(IAsyncResult iar)
--- End of stack trace from previous location where exception was thrown ---
   at MongoDB.Driver.Core.Connections.TcpStreamFactory.ConnectAsync(Socket socket, EndPoint endPoint, CancellationToken cancellationToken)
   at MongoDB.Driver.Core.Connections.TcpStreamFactory.CreateStreamAsync(EndPoint endPoint, CancellationToken cancellationToken)
   at MongoDB.Driver.Core.Connections.BinaryConnection.OpenHelperAsync(CancellationToken cancellationToken)
   --- End of inner exception stack trace ---
   at MongoDB.Driver.Core.Connections.BinaryConnection.OpenHelperAsync(CancellationToken cancellationToken)
   at MongoDB.Driver.Core.Servers.ServerMonitor.InitializeConnectionAsync(CancellationToken cancellationToken)
   at MongoDB.Driver.Core.Servers.ServerMonitor.HeartbeatAsync(CancellationToken cancellationToken)", LastHeartbeatTimestamp: "2021-11-03T08:46:10.0467929Z", LastUpdateTimestamp: "2021-11-03T08:46:10.0467932Z" }] }.., stacktrace:    at MongoDB.Driver.Encryption.AutoEncryptionLibMongoCryptController.EncryptFieldsAsync(String databaseName, Byte[] unencryptedCommandBytes, CancellationToken cancellationToken)
   at MongoDB.Driver.Core.WireProtocol.CommandMessageFieldEncryptor.EncryptFieldsAsync(String databaseName, CommandRequestMessage unencryptedRequestMessage, CancellationToken cancellationToken)
   at MongoDB.Driver.Core.WireProtocol.CommandUsingCommandMessageWireProtocol`1.AutoEncryptFieldsIfNecessaryAsync(CommandRequestMessage unencryptedRequestMessage, IConnection connection, CancellationToken cancellationToken)
   at MongoDB.Driver.Core.WireProtocol.CommandUsingCommandMessageWireProtocol`1.ExecuteAsync(IConnection connection, CancellationToken cancellationToken)
   at MongoDB.Driver.Core.Servers.Server.ServerChannel.ExecuteProtocolAsync[TResult](IWireProtocol`1 protocol, ICoreSession session, CancellationToken cancellationToken)
   at MongoDB.Driver.Core.Operations.RetryableReadOperationExecutor.ExecuteAsync[TResult](IRetryableReadOperation`1 operation, RetryableReadContext context, CancellationToken cancellationToken)
   at MongoDB.Driver.Core.Operations.ReadCommandOperation`1.ExecuteAsync(RetryableReadContext context, CancellationToken cancellationToken)
   at MongoDB.Driver.Core.Operations.FindCommandOperation`1.ExecuteAsync(RetryableReadContext context, CancellationToken cancellationToken)
   at MongoDB.Driver.Core.Operations.FindOperation`1.ExecuteAsync(RetryableReadContext context, CancellationToken cancellationToken)
   at MongoDB.Driver.Core.Operations.FindOperation`1.ExecuteAsync(IReadBinding binding, CancellationToken cancellationToken)
   at MongoDB.Driver.OperationExecutor.ExecuteReadOperationAsync[TResult](IReadBinding binding, IReadOperation`1 operation, CancellationToken cancellationToken)
   at MongoDB.Driver.MongoCollectionImpl`1.ExecuteReadOperationAsync[TResult](IClientSessionHandle session, IReadOperation`1 operation, ReadPreference readPreference, CancellationToken cancellationToken)
   at MongoDB.Driver.MongoCollectionImpl`1.UsingImplicitSessionAsync[TResult](Func`2 funcAsync, CancellationToken cancellationToken)
   at MongoDB.Driver.IAsyncCursorSourceExtensions.ToListAsync[TDocument](IAsyncCursorSource`1 source, CancellationToken cancellationToken)

Also i have started receiving Alerts from mongo atlas about the connections threshold "You are receiving this alert email because connections to your cluster(s) have exceeded 500, and is nearing the connection limit for the M0 cluster "

My question is:

  1. Is there a way we can create singleton instance of mongoClient while using csfle?
  2. Is there a way i can set the connection settings once i create the mongoClient instance. I tried but look like it is a readonly property.

Any help will be appreciated.

Djordje Nedovic
  • 559
  • 8
  • 20
Brijen Patel
  • 23
  • 2
  • 8

1 Answers1

0

Is there a way we can create singleton instance of mongoClient while using csfle?

yes, you just need to specify different collection in schemaMap, see how autoEncryptionSettings are set here (add a different collection into schemaMap dictionary)

Is there a way i can set the connection settings once i create the mongoClient instance. I tried but look like it is a readonly property.

no, you can set settings only before starting MongoClient, after that all settings are readonly

"Unspecified/localhost:27020"

the issue you have is related to the fact that mongocryptd (not mongo server) which is internal process for fle logic is unresponsible. I'm not sure why it happens, try changing schemaMap first and see whether it will help

dododo
  • 3,872
  • 1
  • 14
  • 37
  • Still getting same error after changing the schemaMap. Also validated that mongocryptd is available on sever. – Brijen Patel Nov 08 '21 at 14:49
  • can you check that mongocryptd that you validate is actually spawned on 27020 port? Sometimes, 27020 is not available due a shard configuration server or similar replication configuration – dododo Nov 08 '21 at 14:54
  • Not sure how to check that but i tried adding `{ "mongocryptdSpawnArgs", new [] { "--port=27020" } }` in `AutoEncryptionOptions` but again run into same error. – Brijen Patel Nov 08 '21 at 15:31
  • Finally able to run this. Look like the `MongoDB Enterprise` was installed but not started. Restarted using `sudo systemctl restart mongod` command and everything started working. Thanks for your help. – Brijen Patel Nov 08 '21 at 15:47
  • if you use atlas as you mentioned in the description, it should not be issue – dododo Nov 08 '21 at 16:16
  • I am using mongo atlas to host my db. I had to install `Mongodb Enterprise` on web server and had to run `mongocryptd` command. If the `mongocryptd` is not running on webserver, it started throwing above exception. – Brijen Patel Nov 09 '21 at 10:32
  • what I'm saying, that atlas(as cloud) manages mongocryptd/mognod/mognos and other mongo processes by himself. You don't need to install anything else anywhere in this case – dododo Nov 09 '21 at 12:08
  • note: I was wrong about mongocryptd and atlas, based on this https://www.mongodb.com/community/forums/t/is-client-side-field-level-encryption-supported-with-atlas/5712, surprisingly it should be managed on the application side – dododo Dec 01 '21 at 23:56
  • Actually on M0(free) plan, you need to install mongodb enterprise on application server and also you have to spawn mongocryptd manually. For M20 (paid) plan, you still need to install mongodb enterprise but it will spawned mongocryptd. – Brijen Patel Dec 06 '21 at 14:17