MongoDB self sign certificate

I have…

I’m submitting a…

  • [ ] Regression (a behavior that stopped working in a new release)
  • [ ] Bug report
  • [ ] Performance issue
  • [x] Documentation issue or request

Current behavior

Can’t connect to MongoDB with self signed certificate

I have tried tlsInsecure=true in the connection string but that doesn’t work

Using CA is a requirement for mongodb community setup with external access

Expected behavior

It should work

Environment

App Name:

  • [ ] Self hosted with docker
  • [ ] Self hosted with IIS
  • [X] Self hosted with K8S
  • [ ] Cloud version

Version: 6.4.0

Browser:

  • [ ] Chrome (desktop)
  • [ ] Chrome (Android)
  • [ ] Chrome (iOS)
  • [ ] Firefox
  • [ ] Safari (desktop)
  • [ ] Safari (iOS)
  • [ ] IE
  • [ ] Edge

Others:

I also try to mount the ca and use it like

mongodb://acc:pwd@mongodb-cms.co.com:27017,mongodb-cms.co.com:27018,mongodb-cms.co.com:27019/admin?maxPoolSize=5000&replicaSet=mongodb-cms&authSource=admin&tls=true&tlsCAFile=%2Fapp%2Fcert-ca%2FrootCA.pem

and it still doesn’t work. I can use this with the same ca.pem to connect to the DB from my local machine.

I am pretty sure it is related to the connection string, because if I use a connection that is used inside the k8s, it works fine. However, I can’t do that since my database is on a different cluster.

Error logs is like this

Unhandled exception. System.ArgumentOutOfRangeException: Value is not between 0 and 1024: 5000. (Parameter 'initialCount')
   at MongoDB.Driver.Core.Misc.Ensure.IsBetween[T](T value, T min, T max, String paramName)
   at MongoDB.Driver.Core.Misc.SemaphoreSlimSignalable..ctor(Int32 initialCount)
   at MongoDB.Driver.Core.ConnectionPools.ExclusiveConnectionPool..ctor(ServerId serverId, EndPoint endPoint, ConnectionPoolSettings settings, IConnectionFactory connectionFactory, IEventSubscriber eventSubscriber, IConnectionExceptionHandler connectionExceptionHandler)
   at MongoDB.Driver.Core.ConnectionPools.ExclusiveConnectionPoolFactory.CreateConnectionPool(ServerId serverId, EndPoint endPoint, IConnectionExceptionHandler connectionExceptionHandler)
   at MongoDB.Driver.Core.Servers.Server..ctor(ClusterId clusterId, IClusterClock clusterClock, ClusterConnectionMode clusterConnectionMode, ConnectionModeSwitch connectionModeSwitch, Nullable`1 directConnection, ServerSettings settings, EndPoint endPoint, IConnectionPoolFactory connectionPoolFactory, IEventSubscriber eventSubscriber, ServerApi serverApi)
   at MongoDB.Driver.Core.Servers.DefaultServer..ctor(ClusterId clusterId, IClusterClock clusterClock, ClusterConnectionMode clusterConnectionMode, ConnectionModeSwitch connectionModeSwitch, Nullable`1 directConnection, ServerSettings settings, EndPoint endPoint, IConnectionPoolFactory connectionPoolFactory, IServerMonitorFactory monitorFactory, IEventSubscriber eventSubscriber, ServerApi serverApi)
   at MongoDB.Driver.Core.Servers.ServerFactory.CreateServer(ClusterType clusterType, ClusterId clusterId, IClusterClock clusterClock, EndPoint endPoint)
   at MongoDB.Driver.Core.Clusters.Cluster.CreateServer(EndPoint endPoint)
   at MongoDB.Driver.Core.Clusters.MultiServerCluster.EnsureServer(ClusterDescription clusterDescription, EndPoint endPoint, List`1 newServers)
   at MongoDB.Driver.Core.Clusters.MultiServerCluster.Initialize()
   at MongoDB.Driver.ClusterRegistry.CreateCluster(ClusterKey clusterKey)
   at MongoDB.Driver.ClusterRegistry.GetOrCreateCluster(ClusterKey clusterKey)
   at MongoDB.Driver.MongoClient..ctor(MongoClientSettings settings)
   at MongoDB.Driver.MongoClient..ctor(String connectionString)
   at Squidex.Config.Domain.EventSourcingServices.<>c.<AddSquidexEventSourcing>b__0_4(String s) in /src/src/Squidex/Config/Domain/EventSourcingServices.cs:line 32
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Squidex.Infrastructure.Singletons`1.GetOrAdd(String key, Func`2 factory) in /src/src/Squidex.Infrastructure/Singletons.cs:line 18
   at Squidex.Config.Domain.EventSourcingServices.<>c__DisplayClass0_1.<AddSquidexEventSourcing>b__3(IServiceProvider c) in /src/src/Squidex/Config/Domain/EventSourcingServices.cs:line 32
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite callSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.CreateServiceAccessor(Type serviceType)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.DependencyInjectionExtensions.InterfaceRegistrator`1.<>c.<.ctor>b__2_0(IServiceProvider c)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite callSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitIEnumerable(IEnumerableCallSite enumerableCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite callSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite callSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitIEnumerable(IEnumerableCallSite enumerableCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitRootCache(ServiceCallSite callSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.CreateServiceAccessor(Type serviceType)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetService[T](IServiceProvider provider)
   at Microsoft.Extensions.Hosting.Internal.Host.StartAsync(CancellationToken cancellationToken)
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.Run(IHost host)
   at Squidex.Program.Main(String[] args) in /src/src/Squidex/Program.cs:line 18

Sorry, I am not sure how to help you with that, because I have never used it before.

Do you use the connection string as it is for mongodb drive?

How do you mean that? I think the connection string is unversal across all platforms. But I do not use a certificate, because mongo is the same cluster.

Some tools can generate a connection string for you, e.g. studio3t: https://studio3t.com/

I would try to connect with this tool and then export the connection string there. Could be way faster.

That is what I did actually. And it works from the tool I used. And I tried tlsInsecure=true, it doesn’t work either. Kinda weird.

Do you think the error message is for connection issue to the mongodb? Or there is something else I missed?

From the stacktrace it looks like it has nothing to do with Squidex.

1 Like

So I figured out the whole thing.

The problem are 2 folds.

  1. incorrect maxPoolSize, which is account for “ArgumentOutOfRangeException: Value is not between 0 and 1024: 5000.”

I used 5000 but my host only allow 1024 I think.

  1. Cert issue

This one is more problematic. Because of the mongodb horizon settings, I have to use certificate or it will return the internal host name, which only works inside the same kubernetes cluster.

It seems like I can’t use the following query string with mongodb C# driver, even it works in the mongoshell

tls=true&tlsCAFile=%2Fapp%2Fcert-ca%2FrootCA.pem

Is it possible you can add a configuration for

      clientSettings.UseTls = true;
      clientSettings.AllowInsecureTls = true;

You might have to use

   var clientSettings = MongoClientSettings.FromUrl(new MongoUrl(connURL));
   clientSettings.UseTls = true;
   clientSettings.AllowInsecureTls = true;
   var client = new MongoClient(connURL);

You can default AllowInsecureTls as false and skip useTls/AllowInsecureTls. Only set both true when AllowInsecureTls is true.

Thanks!

1 Like

Just found out this work

&tls=true&sslVerifyCertificate=false

However, I still can’t find a way to use custom CA from the connection string

It would be nice if there is a why to do it.

The setting for AllowInsecureTls seems to be this: tlsInsecure=true

But I guess you have to install your cert to the cert store to get it working.

1 Like

Thanks! That one works too. Either one works. I don’t think mongo use cert store, at lease not with mongoshell. I tested it with mongoshell.

If there is a way to do it in Squidex, that would be great too.

I could not find a way in the mongo driver for C# and I only find the hint to use the cert store: https://scalegrid.io/blog/mongodb-ssl-with-self-signed-certificates-in-c/

Yeah, that is the one I found too.

It’s ok. I can live with tlsInsecure=true right now. I will test the certificate store sometime.

Thanks!

1 Like