Securing MongoDB

Today is a summer Saturday morning in the Twin Cities of Minneapolis and St. Paul. It is not as bright as usual, it appears to be cloudy but it is relatively early. I woke up around 04:30 AM and decided to get up, read the news for a few minutes, and then decided to write this posts. My motivation is twofold. The first and most important is due to the fact that I am officially starting a new project at work using MongoDB. I will be using a local version of MongoDB which later will be moved to use Atlas on the cloud. The database will contain sensitive patient data. The second is the number of recent posts regarding data leaks on NoSQL bases. This morning I just read “MongoDB Leak Exposed Millions of Medical Insurance Records” which seems to illustrate the fact that people forgets to secure their MongoDB instance.

Given that I am using a local Windows machine I read the MongoDB on-line documentation “Enable Access Control” and followed the specified steps. As usual I tend to experiment to make sure I understand how the mechanism works and make sure all is working as expected.

Please note that my instance was initially secured after I installed MongoDB for the first time on my Windows machine. That happened a few years ago. Given that I have only been learning and testing with it, I am able to update the software and experiment with it at will.

If you are about to deploy your software, MongoDB has documentation on how to secure it in “Secure your MongoDB Deployment”.

I will now follow the steps provided in the MongoDB documentation to enable access control using usernames and passwords.

(1) From a console, start MongoDB without access control.

I am currently starting MongoDB as a service so I had to open the service manager app, select “MongoDB Server” and select “Stop” from the popup menu. The service takes a few seconds to stop.

From a command prompt we need to start a standalone mongod instance without access control. This can be done as follows:

C:\>mongod
2019-06-28T08:27:55.761-0700 I CONTROL  [main] Automatically disabling TLS 1.0, to force-enable TLS 1.0 specify --sslDisabledProtocols 'none'
2019-06-28T08:27:55.768-0700 I CONTROL  [initandlisten] MongoDB starting : pid=7788 port=27017 dbpath=C:\data\db\ 64-bit host=Condor
2019-06-28T08:27:55.768-0700 I CONTROL  [initandlisten] targetMinOS: Windows 7/Windows Server 2008 R2
2019-06-28T08:27:55.769-0700 I CONTROL  [initandlisten] db version v4.0.9
2019-06-28T08:27:55.769-0700 I CONTROL  [initandlisten] git version: fc525e2d9b0e4bceff5c2201457e564362909765
2019-06-28T08:27:55.769-0700 I CONTROL  [initandlisten] allocator: tcmalloc
2019-06-28T08:27:55.769-0700 I CONTROL  [initandlisten] modules: none
2019-06-28T08:27:55.770-0700 I CONTROL  [initandlisten] build environment:
2019-06-28T08:27:55.770-0700 I CONTROL  [initandlisten]     distmod: 2008plus-ssl
2019-06-28T08:27:55.771-0700 I CONTROL  [initandlisten]     distarch: x86_64
2019-06-28T08:27:55.771-0700 I CONTROL  [initandlisten]     target_arch: x86_64
2019-06-28T08:27:55.771-0700 I CONTROL  [initandlisten] options: {}
2019-06-28T08:27:55.774-0700 I STORAGE  [initandlisten] Detected data files in C:\data\db\ created by the 'wiredTiger' storage engine, so setting the active storage engine to 'wiredTiger'.
2019-06-28T08:27:55.775-0700 I STORAGE  [initandlisten] wiredtiger_open config: create,cache_size=11774M,session_max=20000,eviction=(threads_min=4,threads_max=4),config_base=false,statistics=(fast),log=(enabled=true,archive=true,path=journal,compressor=snappy),file_manager=(close_idle_time=100000),s
tatistics_log=(wait=0),verbose=(recovery_progress),
2019-06-28T08:27:56.187-0700 I STORAGE  [initandlisten] WiredTiger message [1561735676:187261][7788:140706581924944], txn-recover: Main recovery loop: starting at 111/896 to 112/256
2019-06-28T08:27:56.454-0700 I STORAGE  [initandlisten] WiredTiger message [1561735676:454228][7788:140706581924944], txn-recover: Recovering log 111 through 112
2019-06-28T08:27:56.648-0700 I STORAGE  [initandlisten] WiredTiger message [1561735676:648247][7788:140706581924944], txn-recover: Recovering log 112 through 112
2019-06-28T08:27:56.783-0700 I STORAGE  [initandlisten] WiredTiger message [1561735676:783227][7788:140706581924944], txn-recover: Set global recovery timestamp: 0
2019-06-28T08:27:57.124-0700 I RECOVERY [initandlisten] WiredTiger recoveryTimestamp. Ts: Timestamp(0, 0)
2019-06-28T08:27:57.282-0700 I CONTROL  [initandlisten]
2019-06-28T08:27:57.283-0700 I CONTROL  [initandlisten] ** WARNING: Access control is not enabled for the database.
2019-06-28T08:27:57.283-0700 I CONTROL  [initandlisten] **          Read and write access to data and configuration is unrestricted.
2019-06-28T08:27:57.283-0700 I CONTROL  [initandlisten]
2019-06-28T08:27:57.284-0700 I CONTROL  [initandlisten] ** WARNING: This server is bound to localhost.
2019-06-28T08:27:57.284-0700 I CONTROL  [initandlisten] **          Remote systems will be unable to connect to this server.
2019-06-28T08:27:57.284-0700 I CONTROL  [initandlisten] **          Start the server with --bind_ip 
<address> to specify which IP
2019-06-28T08:27:57.284-0700 I CONTROL  [initandlisten] **          addresses it should serve responses from, or with --bind_ip_all to
2019-06-28T08:27:57.284-0700 I CONTROL  [initandlisten] **          bind to all interfaces. If this behavior is desired, start the
2019-06-28T08:27:57.284-0700 I CONTROL  [initandlisten] **          server with --bind_ip 127.0.0.1 to disable this warning.
2019-06-28T08:27:57.284-0700 I CONTROL  [initandlisten]
2019-06-28T10:27:58.047-0500 I FTDC     [initandlisten] Initializing full-time diagnostic data capture with directory 'C:/data/db/diagnostic.data'
2019-06-28T10:27:58.054-0500 I NETWORK  [initandlisten] waiting for connections on port 27017

After executing the command the MongoDB service starts. Note that I am using the default port 27017 and that my data directory was installed in the default location as specified when I installed version 4.0. In my case it is:  C:\data\db

(2) Connect to the instance using a command prompt.

Now that the service is running we need to connect to MongoDB in order to create a user as we will see shortly. The next step is to connect which may be accomplished as follows:

C:\>mongo
MongoDB shell version v4.0.9
connecting to: mongodb://127.0.0.1:27017/?gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("9d01e96d-8603-4fcc-9287-aa7a66197758") }
MongoDB server version: 4.0.9
Server has startup warnings:
2019-06-28T08:27:57.282-0700 I CONTROL  [initandlisten]
2019-06-28T08:27:57.283-0700 I CONTROL  [initandlisten] ** WARNING: Access control is not enabled for the database.
2019-06-28T08:27:57.283-0700 I CONTROL  [initandlisten] **          Read and write access to data and configuration is unrestricted.
2019-06-28T08:27:57.283-0700 I CONTROL  [initandlisten]
2019-06-28T08:27:57.284-0700 I CONTROL  [initandlisten] ** WARNING: This server is bound to localhost.
2019-06-28T08:27:57.284-0700 I CONTROL  [initandlisten] **          Remote systems will be unable to connect to this server.
2019-06-28T08:27:57.284-0700 I CONTROL  [initandlisten] **          Start the server with --bind_ip 
<address> to specify which IP
2019-06-28T08:27:57.284-0700 I CONTROL  [initandlisten] **          addresses it should serve responses from, or with --bind_ip_all to
2019-06-28T08:27:57.284-0700 I CONTROL  [initandlisten] **          bind to all interfaces. If this behavior is desired, start the
2019-06-28T08:27:57.284-0700 I CONTROL  [initandlisten] **          server with --bind_ip 127.0.0.1 to disable this warning.
2019-06-28T08:27:57.284-0700 I CONTROL  [initandlisten]
---
Enable MongoDB's free cloud-based monitoring service, which will then receive and display
metrics about your deployment (disk utilization, CPU, operation statistics, etc).

The monitoring data will be available on a MongoDB website with a unique URL accessible to you
and anyone you share the URL with. MongoDB may use this information to make product
improvements and to suggest MongoDB products and deployment options to you.

To enable free monitoring, run the following command: db.enableFreeMonitoring()
To permanently disable this reminder, run the following command: db.disableFreeMonitoring()
---

>

After issuing the command we get a prompt and are ready to interact with MongoDB. We are now in the mongo shell as it is known.

(3a) Create the user administrator.

Using the mongo shell we may issue the following commands:

> use admin
switched to db admin

> db.createUser(
  {
    user: "john",
    pwd: "secret_password",
    roles: [ { role: "userAdminAnyDatabase", db: "admin" }, "readWriteAnyDatabase" ]
  }
)
Successfully added user: {
        "user" : "john",
        "roles" : [
                {
                        "role" : "userAdminAnyDatabase",
                        "db" : "admin"
                },
                "readWriteAnyDatabase"
        ]
}
>

The first one is to start using the admin database.

The second is used to create a user. In this case I named the user “john” and specified a secret password “secret_password”. As with any password make sure it is at least 12 characters and use a mix of upper and lower case characters, punctuation marks and numerals.

(3b) Verify the user administrator.

As with any software development, I like to verify that what I did is correct. By issuing the following command we can determine if our user was properly created:

> db.getUsers()
[
        {
                "_id" : "admin.john",
                "userId" : UUID("692a21a8-e807-40c4-ac17-aad8897f0537"),
                "user" : "john",
                "db" : "admin",
                "roles" : [
                        {
                                "role" : "userAdminAnyDatabase",
                                "db" : "admin"
                        },
                        {
                                "role" : "readWriteAnyDatabase",
                                "db" : "admin"
                        }
                ],
                "mechanisms" : [
                        "SCRAM-SHA-1"
                ]
        }
]
>

Seems like all is well and we are ready to move on.

(4) Re-start the MongoDB instance with access control.

We will continue using the mongo shell to stop the current instance of the mongod. On the mongo shell enter the following command:

> db.adminCommand( { shutdown: 1 } )
2019-06-29T06:25:33.016-0500 E QUERY     Error: error doing query: failed: network error while attempting to run command 'shutdown' on host '127.0.0.1:27017'  :
DB.prototype.runCommand@src/mongo/shell/db.js:168:1
DB.prototype.adminCommand@src/mongo/shell/db.js:186:16
@(shell):1:1
2019-06-29T06:25:33.034-0500 I NETWORK   trying reconnect to 127.0.0.1:27017 failed
2019-06-29T06:25:34.038-0500 I NETWORK   reconnect 127.0.0.1:27017 failed failed
>

After the command completes the mongod stops and our shell is no longer able to connect to MongoDB.

The following shows what happens on the other command prompt in which mongod was started:

C:\>mongod
2019-06-29T04:24:51.069-0700 I CONTROL  [main] Automatically disabling TLS 1.0, to force-enable TLS 1.0 specify --sslDisabledProtocols 'none'
2019-06-29T04:24:51.077-0700 I CONTROL  [initandlisten] MongoDB starting : pid=12556 port=27017 dbpath=C:\data\db\ 64-bit host=Condor
2019-06-29T04:24:51.078-0700 I CONTROL  [initandlisten] targetMinOS: Windows 7/Windows Server 2008 R2
2019-06-29T04:24:51.079-0700 I CONTROL  [initandlisten] db version v4.0.9
2019-06-29T04:24:51.081-0700 I CONTROL  [initandlisten] git version: fc525e2d9b0e4bceff5c2201457e564362909765
2019-06-29T04:24:51.084-0700 I CONTROL  [initandlisten] allocator: tcmalloc
2019-06-29T04:24:51.085-0700 I CONTROL  [initandlisten] modules: none
2019-06-29T04:24:51.086-0700 I CONTROL  [initandlisten] build environment:
2019-06-29T04:24:51.088-0700 I CONTROL  [initandlisten]     distmod: 2008plus-ssl
2019-06-29T04:24:51.094-0700 I CONTROL  [initandlisten]     distarch: x86_64
2019-06-29T04:24:51.095-0700 I CONTROL  [initandlisten]     target_arch: x86_64
2019-06-29T04:24:51.097-0700 I CONTROL  [initandlisten] options: {}
2019-06-29T04:24:51.164-0700 I STORAGE  [initandlisten] Detected data files in C:\data\db\ created by the 'wiredTiger' storage engine, so setting the active storage engine to 'wiredTiger'.
2019-06-29T04:24:51.165-0700 I STORAGE  [initandlisten] wiredtiger_open config: create,cache_size=11774M,session_max=20000,eviction=(threads_min=4,threads_max=4),config_base=false,statistics=(fast),log=(enabled=true,archive=true,path=journal,compressor=snappy),file_manager=(close_idle_time=100000),s
tatistics_log=(wait=0),verbose=(recovery_progress),
2019-06-29T04:24:51.581-0700 I STORAGE  [initandlisten] WiredTiger message [1561807491:580867][12556:140706581924944], txn-recover: Main recovery loop: starting at 129/896 to 130/256
2019-06-29T04:24:51.857-0700 I STORAGE  [initandlisten] WiredTiger message [1561807491:856793][12556:140706581924944], txn-recover: Recovering log 129 through 130
2019-06-29T04:24:52.077-0700 I STORAGE  [initandlisten] WiredTiger message [1561807492:76780][12556:140706581924944], txn-recover: Recovering log 130 through 130
2019-06-29T04:24:52.218-0700 I STORAGE  [initandlisten] WiredTiger message [1561807492:217771][12556:140706581924944], txn-recover: Set global recovery timestamp: 0
2019-06-29T04:24:52.617-0700 I RECOVERY [initandlisten] WiredTiger recoveryTimestamp. Ts: Timestamp(0, 0)
2019-06-29T04:24:52.819-0700 I CONTROL  [initandlisten]
2019-06-29T04:24:52.819-0700 I CONTROL  [initandlisten] ** WARNING: Access control is not enabled for the database.
2019-06-29T04:24:52.821-0700 I CONTROL  [initandlisten] **          Read and write access to data and configuration is unrestricted.
2019-06-29T04:24:52.822-0700 I CONTROL  [initandlisten]
2019-06-29T04:24:52.824-0700 I CONTROL  [initandlisten] ** WARNING: This server is bound to localhost.
2019-06-29T04:24:52.825-0700 I CONTROL  [initandlisten] **          Remote systems will be unable to connect to this server.
2019-06-29T04:24:52.831-0700 I CONTROL  [initandlisten] **          Start the server with --bind_ip 
<address> to specify which IP
2019-06-29T04:24:52.834-0700 I CONTROL  [initandlisten] **          addresses it should serve responses from, or with --bind_ip_all to
2019-06-29T04:24:52.836-0700 I CONTROL  [initandlisten] **          bind to all interfaces. If this behavior is desired, start the
2019-06-29T04:24:52.837-0700 I CONTROL  [initandlisten] **          server with --bind_ip 127.0.0.1 to disable this warning.
2019-06-29T04:24:52.839-0700 I CONTROL  [initandlisten]
2019-06-29T06:24:54.441-0500 I FTDC     [initandlisten] Initializing full-time diagnostic data capture with directory 'C:/data/db/diagnostic.data'
2019-06-29T06:24:54.453-0500 I NETWORK  [initandlisten] waiting for connections on port 27017
2019-06-29T06:24:54.776-0500 I CONTROL  [free_mon] Free Monitoring is Enabled. Frequency: 60 seconds
2019-06-29T06:25:07.332-0500 I NETWORK  [listener] connection accepted from 127.0.0.1:53844 #1 (1 connection now open)
2019-06-29T06:25:07.335-0500 I NETWORK  [conn1] received client metadata from 127.0.0.1:53844 conn1: { application: { name: "MongoDB Shell" }, driver: { name: "MongoDB Internal Client", version: "4.0.9" }, os: { type: "Windows", name: "Microsoft Windows 10", architecture: "x86_64", version: "10.0 (b
uild 17134)" } }

<==== command issued from the mongo shell 2019-06-29T06:25:29.508-0500 I COMMAND [conn1] terminating, shutdown command received { shutdown: 1.0, lsid: { id: UUID("e326779f-d3af-4300-b0f7-a4d14688664f") }, $db: "admin" } 2019-06-29T06:25:29.509-0500 I NETWORK [conn1] shutdown: going to close listening sockets... 2019-06-29T06:25:29.513-0500 I CONTROL [conn1] Shutting down free monitoring 2019-06-29T06:25:29.513-0500 I FTDC [conn1] Shutting down full-time diagnostic data capture 2019-06-29T06:25:29.529-0500 I STORAGE [conn1] WiredTigerKVEngine shutting down 2019-06-29T06:25:29.581-0500 I STORAGE [conn1] Shutting down session sweeper thread 2019-06-29T06:25:29.582-0500 I STORAGE [conn1] Finished shutting down session sweeper thread 2019-06-29T06:25:29.848-0500 I STORAGE [conn1] Downgrading WiredTiger datafiles. 2019-06-29T06:25:31.011-0500 I STORAGE [conn1] WiredTiger message [1561807531:11420][12556:140706581924944], txn-recover: Main recovery loop: starting at 130/7040 to 131/256 2019-06-29T06:25:31.296-0500 I STORAGE [conn1] WiredTiger message [1561807531:296420][12556:140706581924944], txn-recover: Recovering log 130 through 131 2019-06-29T06:25:31.519-0500 I STORAGE [conn1] WiredTiger message [1561807531:518388][12556:140706581924944], txn-recover: Recovering log 131 through 131 2019-06-29T06:25:31.665-0500 I STORAGE [conn1] WiredTiger message [1561807531:665414][12556:140706581924944], txn-recover: Set global recovery timestamp: 0 2019-06-29T06:25:32.932-0500 I STORAGE [conn1] shutdown: removing fs lock... 2019-06-29T06:25:32.936-0500 I CONTROL [conn1] now exiting 2019-06-29T06:25:32.938-0500 I CONTROL [conn1] shutting down with code:0 C:\>

At some point mongod was started.

I added an “<====” arrow to indicate when the command to shutdown mongod was entered in the mongo shell.

When the command executes, the mongod server shuts down.

We can now exit the mongo shell as follows:

> quit()

C:\>

Next we need to start mongod with authorization enabled as illustrated by the following console capture:

C:\> mongod --auth
2019-06-28T12:48:07.252-0700 I CONTROL  [main] Automatically disabling TLS 1.0, to force-enable TLS 1.0 specify --sslDisabledProtocols 'none'
2019-06-28T12:48:07.259-0700 I CONTROL  [initandlisten] MongoDB starting : pid=4992 port=27017 dbpath=C:\data\db\ 64-bit host=Condor
2019-06-28T12:48:07.260-0700 I CONTROL  [initandlisten] targetMinOS: Windows 7/Windows Server 2008 R2
2019-06-28T12:48:07.261-0700 I CONTROL  [initandlisten] db version v4.0.9
2019-06-28T12:48:07.262-0700 I CONTROL  [initandlisten] git version: fc525e2d9b0e4bceff5c2201457e564362909765
2019-06-28T12:48:07.266-0700 I CONTROL  [initandlisten] allocator: tcmalloc
2019-06-28T12:48:07.267-0700 I CONTROL  [initandlisten] modules: none
2019-06-28T12:48:07.269-0700 I CONTROL  [initandlisten] build environment:
2019-06-28T12:48:07.270-0700 I CONTROL  [initandlisten]     distmod: 2008plus-ssl
2019-06-28T12:48:07.272-0700 I CONTROL  [initandlisten]     distarch: x86_64
2019-06-28T12:48:07.273-0700 I CONTROL  [initandlisten]     target_arch: x86_64
2019-06-28T12:48:07.275-0700 I CONTROL  [initandlisten] options: { security: { authorization: "enabled" } }     <===
2019-06-28T12:48:07.281-0700 I STORAGE  [initandlisten] Detected data files in C:\data\db\ created by the 'wiredTiger' storage engine, so setting the active storage engine to 'wiredTiger'.
2019-06-28T12:48:07.282-0700 I STORAGE  [initandlisten] wiredtiger_open config: create,cache_size=11774M,session_max=20000,eviction=(threads_min=4,threads_max=4),config_base=false,statistics=(fast),log=(enabled=true,archive=true,path=journal,compressor=snappy),file_manager=(close_idle_time=100000),s
tatistics_log=(wait=0),verbose=(recovery_progress),
2019-06-28T12:48:07.701-0700 I STORAGE  [initandlisten] WiredTiger message [1561751287:701484][4992:140706581924944], txn-recover: Main recovery loop: starting at 123/896 to 124/256
2019-06-28T12:48:07.984-0700 I STORAGE  [initandlisten] WiredTiger message [1561751287:984393][4992:140706581924944], txn-recover: Recovering log 123 through 124
2019-06-28T12:48:08.191-0700 I STORAGE  [initandlisten] WiredTiger message [1561751288:191398][4992:140706581924944], txn-recover: Recovering log 124 through 124
2019-06-28T12:48:08.321-0700 I STORAGE  [initandlisten] WiredTiger message [1561751288:321445][4992:140706581924944], txn-recover: Set global recovery timestamp: 0
2019-06-28T12:48:08.549-0700 I RECOVERY [initandlisten] WiredTiger recoveryTimestamp. Ts: Timestamp(0, 0)
2019-06-28T12:48:08.699-0700 I CONTROL  [initandlisten]
2019-06-28T12:48:08.699-0700 I CONTROL  [initandlisten] ** WARNING: This server is bound to localhost.
2019-06-28T12:48:08.702-0700 I CONTROL  [initandlisten] **          Remote systems will be unable to connect to this server.
2019-06-28T12:48:08.704-0700 I CONTROL  [initandlisten] **          Start the server with --bind_ip 
<address> to specify which IP
2019-06-28T12:48:08.706-0700 I CONTROL  [initandlisten] **          addresses it should serve responses from, or with --bind_ip_all to
2019-06-28T12:48:08.707-0700 I CONTROL  [initandlisten] **          bind to all interfaces. If this behavior is desired, start the
2019-06-28T12:48:08.708-0700 I CONTROL  [initandlisten] **          server with --bind_ip 127.0.0.1 to disable this warning.
2019-06-28T12:48:08.710-0700 I CONTROL  [initandlisten]
2019-06-28T14:48:09.460-0500 I FTDC     [initandlisten] Initializing full-time diagnostic data capture with directory 'C:/data/db/diagnostic.data'
2019-06-28T14:48:09.468-0500 I NETWORK  [initandlisten] waiting for connections on port 27017

As we can see the mongod starts and displays that authorization has been enabled.

(5) Connect and authenticate as the user administrator.

We are now ready to verify that our MongoDB database is secure and we can only login by specifying a user and associated password. This is equivalent to logging into your computer system by specifying similar credentials.

C:\>mongo -u "john"
MongoDB shell version v4.0.9
Enter password:
connecting to: mongodb://127.0.0.1:27017/?gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("a53fe1fc-5df5-4385-b93c-b54d15569601") }
MongoDB server version: 4.0.9

> show databases
admin            0.000GB
agg              0.000GB
blog             0.000GB
chat             0.000GB
config           0.000GB
course           0.000GB
dicom            0.000GB
images           0.000GB
local            0.000GB
m101             0.000GB
mongo-exercises  0.000GB
playground       0.000GB
school           0.000GB
students         0.000GB
test             0.041GB
towns            0.000GB
video            0.000GB
vidly            0.000GB

> use admin
switched to db admin

> db.getUsers()
[
        {
                "_id" : "admin.john",
                "userId" : UUID("692a21a8-e807-40c4-ac17-aad8897f0537"),
                "user" : "john",
                "db" : "admin",
                "roles" : [
                        {
                                "role" : "userAdminAnyDatabase",
                                "db" : "admin"
                        },
                        {
                                "role" : "readWriteAnyDatabase",
                                "db" : "admin"
                        }
                ],
                "mechanisms" : [
                        "SCRAM-SHA-1"
                ]
        }
]
>

From a command prompt I specify my user and press the <Enter> key. The mongo shell prompts me for my password. I enter the correct password and we are in.

Next we list / show the databases that I have. They are all listed.

Then we switch to the admin database and get the users. Our admin user is the only entry at this time.

I know this is not required and is out of the scope of the main subject for this blog, but when we initially started the mongo shell the following message was displayed:

---
Enable MongoDB's free cloud-based monitoring service, which will then receive and display
metrics about your deployment (disk utilization, CPU, operation statistics, etc).

The monitoring data will be available on a MongoDB website with a unique URL accessible to you
and anyone you share the URL with. MongoDB may use this information to make product
improvements and to suggest MongoDB products and deployment options to you.

To enable free monitoring, run the following command: db.enableFreeMonitoring()
To permanently disable this reminder, run the following command: db.disableFreeMonitoring()
---

You can get free monitoring by entering the following command in a mongo shell:

> db.enableFreeMonitoring()
{
        "state" : "enabled",
        "message" : "To see your monitoring data, navigate to the unique URL below. Anyone you share the URL with will also be able to view this page. You can disable monitoring at any time by running db.disableFreeMonitoring().",
        "url" : "https://cloud.mongodb.com/freemonitoring/cluster/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
        "userReminder" : "",
        "ok" : 1
}
>

I have edited my URL for obvious reasons.

You can then use your unique URL on your favorite browser and get a set of charts indicating the activity in your MongoDB instance.

OK, back to the subject at hand.

You can now create other users with specific roles with access to specific databases.

(6) Create additional users as needed for your deployment.

The current state of affairs is that we have secured our MongoDB instance but have a single user with all possible roles. In practice we would like to give different users access to different databases with specific roles.

Let’s assume we have a test database and wish to create a tester user with read and write access to conduct tests. We do not wish that user to be meddling intentionally or accidentally in other databases.

C:\>mongo -u john
MongoDB shell version v4.0.9
Enter password:
connecting to: mongodb://127.0.0.1:27017/?gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("3380fd74-c5f6-48f1-bb5e-7500357ee21c") }
MongoDB server version: 4.0.9

> show dbs
admin            0.000GB
agg              0.000GB
blog             0.000GB
chat             0.000GB
config           0.000GB
course           0.000GB
dicom            0.000GB
images           0.000GB
local            0.000GB
m101             0.000GB
mongo-exercises  0.000GB
playground       0.000GB
school           0.000GB
students         0.000GB
test             0.041GB    <==== towns 0.000GB video 0.000GB vidly 0.000GB > use test
switched to db test

> show collections
customer
example
fun
movieDetails
sentences
zips

> db.getUsers()
[ ]

> db.createUser(
...   {
...     user: "tester",             <====
...     pwd: "secret_password",     <==== ... roles: [ { role: "readWrite", db: "test" }] ... } ... ) Successfully added user: { "user" : "tester", "roles" : [ { "role" : "readWrite", "db" : "test" } ] } > db.getUsers()
[
        {
                "_id" : "test.tester",
                "userId" : UUID("72646d75-ca42-4ca9-80f8-66b9dbf1961d"),
                "user" : "tester",
                "db" : "test",
                "roles" : [
                        {
                                "role" : "readWrite",
                                "db" : "test"
                        }
                ],
                "mechanisms" : [
                        "SCRAM-SHA-1"
                ]
        }
]

> quit()

C:\>

In this last screen capture we login using the “john” user name. The proper password is entered.

We then list / show the databases in our MongoDB instance. Of interest is the database named “test”. It contains six collections which our tester should have access to conduct different types of operations.

We check that there are no users associated with the “test” database at this time so we proceed to create it and assign it a private password. We then verify that the user has been created and we are able to access it. All is well so far. We just quit the mongo console.

(7) Connect to the instance and authenticate as tester.

The last step is to log in as the new user and see if it has the proper credentials to access the “test” and only the “test” database.

C:\>mongo -u tester
MongoDB shell version v4.0.9
Enter password: <incorrect password>
connecting to: mongodb://127.0.0.1:27017/?gssapiServiceName=mongodb
2019-06-29T08:46:28.505-0500 E QUERY     Error: Authentication failed. :
connect@src/mongo/shell/mongo.js:343:13
@(connect):2:6
exception: connect failed

C:\>

C:\>mongo -u tester
MongoDB shell version v4.0.9
Enter password: <incorrect password>
connecting to: mongodb://127.0.0.1:27017/?gssapiServiceName=mongodb
2019-06-29T08:46:28.505-0500 E QUERY     Error: Authentication failed. :
connect@src/mongo/shell/mongo.js:343:13
@(connect):2:6
exception: connect failed

C:\>

C:\>mongo -u tester --authenticationDatabase vidly
MongoDB shell version v4.0.9
Enter password: <correct password>
connecting to: mongodb://127.0.0.1:27017/?authSource=vidly&gssapiServiceName=mongodb
2019-06-29T08:47:17.383-0500 E QUERY     Error: Authentication failed. :
connect@src/mongo/shell/mongo.js:343:13
@(connect):2:6
exception: connect failed

C:\>

C:\>mongo -u tester --authenticationDatabase test
MongoDB shell version v4.0.9
Enter password: <correct password>
connecting to: mongodb://127.0.0.1:27017/?authSource=test&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("88f99e95-6cbb-49b9-af15-0ce560fcea5d") }
MongoDB server version: 4.0.9
Server has startup warnings:
2019-06-30T05:50:02.179-0500 I CONTROL  [initandlisten]
2019-06-30T05:50:02.179-0500 I CONTROL  [initandlisten] ** WARNING: Access control is not enabled for the database.
2019-06-30T05:50:02.179-0500 I CONTROL  [initandlisten] **          Read and write access to data and configuration is unrestricted.
2019-06-30T05:50:02.179-0500 I CONTROL  [initandlisten]
---
Free Monitoring URL:
https://cloud.mongodb.com/freemonitoring/cluster/QZVUZFZOWK4T23CIF4K7XSR3DWI737GX
---

> show databases
test  0.041GB

> show collections
customer
example
fun
movieDetails
sentences
zips

> db.customer.find()
{ "_id" : ObjectId("5b648a47814ab611f4084008"), "name" : "Madhura", "_class" : "com.example.bootiful.Customer" }
{ "_id" : ObjectId("5b648a47814ab611f408400a"), "name" : "Onsi", "_class" : "com.example.bootiful.Customer" }
{ "_id" : ObjectId("5b648a47814ab611f4084007"), "name" : "Mia", "_class" : "com.example.bootiful.Customer" }
{ "_id" : ObjectId("5b648a47814ab611f4084009"), "name" : "Dave", "_class" : "com.example.bootiful.Customer" }

> use video     <==== switched to db video > show collections
Warning: unable to run listCollections, attempting to approximate collection names by parsing connectionStatus

> quit()

C:\>

In the first attempt we attempt to login using an incorrect password. That fails.

We then repeat the attempt using the correct password.  That also fails. A database has not been specified.

We repeat the attempt using the correct password but provide a database name “vidly” for which our user has not been granted access. The operation fails.

We then use the proper user, proper password and specify the ”test” database for which our user has access. The login operation succeeds.

 

(8) Set the MongoDB service on Windows 10 to use Authorization.

To enable authorization on MongoDB on Windows 10 you must edit the C:\Program Files\MongoDB\Server\4.0\bin\mongod.cfg file.

!!! NOTE !!!

Do not attempt to specify the –auth parameter in the Services -> MongoDB Server -> Properties -> Start parameters: field. It does not work.

Look for the following line in the mongod.cfg  file:

:::: :::: ::::

#security:

:::: :::: ::::

Change it to:

:::: :::: ::::

security:
    authorization: enabled

:::: :::: ::::

Restart the MongoDB Server using the services app.

If you have comments or questions regarding this or any other post in this blog, or if you would like me to help with any phase in the SDLC (Software Development Life Cycle) of a product or service, please do not hesitate and leave me a note below. Requests for help will remain private.

Keep on reading and experimenting. It is the best way to learn and refresh your knowledge!

John

Follow me on Twitter:  @john_canessa

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.