docker-library / mongo

Docker Official Image packaging for MongoDB

Home Page:https://www.mongodb.org/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Cant use --clusterAuthMode with initdb in docker-compose

pelzerim opened this issue · comments

When running 3.4 with command --clusterAuthMode and env MONGO_INITDB_ROOT_USERNAME set it throws
BadValue: cannot have x.509 cluster authentication in allowSSL mode. It seems docker-entrypoint.sh does not remove clusterAuthMode when doing its initdb thing.

When moving clusterAuthMode to a config file it works (Not with 3.6 though, gives warning: database is not yet initialized, and "--config" is specified the initdb database startup might fail as a result!)

This fails for example:

version: '2.1'
services:
  mongodb:
    image: mongo:3.6
    command: 
     - '--sslMode'
     - 'requireSSL'
     - '--clusterAuthMode'
     - 'x509'
     - '--dbpath' 
     - '/data/db'
     - '--replSet'
     - 'mongo-rs-1'
     - '--sslPEMKeyFile'
     - '/data/certs/servers/mongo/mongodb.pem'
     - '--sslCAFile'
     - '/data/certs/ca/ca.crt'
     - '--sslClusterFile'
     - '/data/certs/servers/mongo/mongodb.pem'
    volumes:
        - ./certs:/data/certs
        - ./db:/data/db
    environment:
      MONGO_INITDB_ROOT_USERNAME: admin
      MONGO_INITDB_ROOT_PASSWORD: apassword

I guess I'm a little bit confused about why you'd want to combine --clusterAuthMode with MONGO_INITDB_ROOT_USERNAME/MONGO_INITDB_ROOT_PASSWORD -- isn't the point of --clusterAuthMode that you don't have a password, and instead use TLS client certs for authentication?

I couldn't get the initial auth through certificates working and just assumed it could not work that way. Got it working now and will not be needing the above mentioned behaviour anymore (If anyone wonders: connect with mongo using the certificate used to start the server and do use $external ; db.auth({mechanism: 'MONGODB-X509'}); ). Thanks for pointing that out, i will close this.

@pelzerim did you use the client certificate to connect to mongo? I'm able to connect to mongo using client certificate but I get an error after executing:
db.auth({mechanism: 'MONGODB-X509'});
Error: Could not find user CN=client1,OU=MyClients,O=MongoDB-Cluster,L=Austin,ST=TX,C=US@$external
Any thoughts what could be wrong?

@cxww107 You need to use the $external library:

use \$external
db.auth({mechanism: 'MONGODB-X509'});

It is also possible to do this during connection using mongo-shell:
mongo --ssl --sslPEMKeyFile /bla.pem --sslCAFile /ca.key --sslAllowInvalidHostnames --authenticationMechanism=MONGODB-X509 --authenticationDatabase='$external'

@pelzerim yes, I use $external. But still I get an error. It seems that mongo accepts the client certificate but user associated with certificate hasn't been created yet.

When I use my laptop as a host my script looks like:

  1. create three mongo instances in non-auth mode.
  2. initiate a replica set of three with creation of default user with the name equals to the subject of client certificate: CN=client1,OU=MyClients,O=MongoDB-Cluster,L=Austin,ST=TX,C=US)
  3. restart mongo instances in SSL auth mode (using three server certificates)
  4. Enable default client user via:
mongo _... ssl flags ..._ <- EOJS 
db.getSiblingDB("$external").auth(
   {
     mechanism: "MONGODB-X509",
     user: "CN=client1,OU=MyClients,O=MongoDB-Cluster,L=Austin,ST=TX,C=US"
   }
 )
 EOJS

Did you change official docker-entrypoint or Dockerfile to get it working?

@cxww107 So with 2. you mean you did add a user like this at point 2? Or a user for your database? Can you show me what you did?

Also did you make sure to use the same ca to sign the certificates of the server? What error do the mongod instances show in their logs when you try to authenticate on them?

You should not need any changes to the docker-entrypoint or dockerfile to make this work (in development).

@pelzerim correct, I add a user like in documentation. Basically I follow this tutorial: https://www.mongodb.com/blog/post/secure-mongodb-with-x-509-authentication

I have the following certificates:

  1. ca.pem -> intermediate.pem -> ca-chain (chained ca and intermediate)
  2. server certificates x3 (1 pro replica set), clients certificate x 2
    Please find my script here https://gist.github.com/cxww107/663615ae8586819d67dcb0d0dfc8a612

When I try to connect to docker container I receive following message:
2018-04-09T20:22:39.713+0200 W NETWORK [thread1] The server certificate does not match the host name. Hostname: localhost does not match CN: server1

I think that is the problem. But I can't see what I did wrong.

The host names should not be an issue as you are ignoring invalid host names both in mongod and in mongo-shell.

Where are you running this script inside the docker container? Then you would be running 3 mongod instances inside one container. What you want with a replica set is one container runnin one mongod each.
Nonetheless did you expose the mongod port to your machine? Also what are the logs for the mongod instance you are connecting to?

@pelzerim as I mentioned above I run this script locally on my macOS. It creates successfully a replica set of three mongodb instances in x509 auth mode on localhost ports 27017, 27018 and 27019. Then authentication with client certificate works fine.

Back to docker: I understand that it is pointless to create replica set on the same host. But I still can't authenticate even if I start just one docker container with following docker-compose.

screen shot 2018-04-10 at 21 06 58

(on screenshot localhost:27017 is linked to 27017 of docker container)

This missing user I create in my script like in official documentation at point 2 before I restart mongodb instance in ssl mode. But how I can achieve the same in docker container?

You are trying to connect with the client certificate (/data/certs/clients/default.pem) but you started the container with the server certificate (/data/certs/servers/server1.pem). As you did not yet initialize the replica or add any users, your client certificate has no user yet. Try connecting with the servers certificate. (--sslPEMKeyFile /data/certs/servers/server1.pem)

@pelzerim I start container with server1.pem:
screen shot 2018-04-11 at 19 34 00

And then I get an error trying to connect with server1.pem:
screen shot 2018-04-11 at 19 34 44

It seems not working this way as well.

Well, I manage to solve the problem by workaround. Firstly I start mongodb container with authentication disabled using docker-compose, and then I connect to mongodb and run a script to create admin user with subject from its certificate (e.g. "CN=client1,OU=MyClients,O=MongoDB-Cluster,L=Austin,ST=TX,C=US").
In order to restart mongodb in x509 mode, I have to stop container, commit changes to a temporary image and start from this image a new container using docker run command with ssl options.
Obviously it is ugly, but it works.

One last thing you should try: Execute into the docker container and then try connecting using mongos with the servers certificate.