MongoDB: Understand createUser and db admin - mongodb

My MongoDB is hosted on compose.io and is called ScroungeBA.
I try to create a user with some built-in roles which by the documentary only work in the admin database:
MongoDB provides all other built-in roles only on the admin database
So my question: What is that admin db about? Is it the standard db which always exists?
Furthermore I have trouble with (using MongoDB shell version: 3.0.5):
$ use admin
switched to db admin
$ db.auth("user", "secret")
Error: 18 Authentication failed.
I guess my user does exist in the ScroungeBA db but not in the admin db? How can I create a user in the admin db since
db.createUser({user:"hello", pwd:"world", roles:[{role: "userAdmin", db: "admin"}]})
results in the error:
Error: couldn't add user: not authorized on admin to execute command { createUser: "hello", pwd: "xxx", roles: [ { role: "userAdmin", db: "admin" } ], digestPassword: false, writeConcern: { w: "majority", wtimeout: 30000.0 } }
at Error (<anonymous>)
at DB.createUser (src/mongo/shell/db.js:1101:11)
at (shell):1:4 at src/mongo/shell/db.js:1101

The admin database is a special database that you automatically have with a MongoDB instance. It contains things like the users of your databases, with roles, custom data, etc.
To create a user in the admin database, you have to temporarily disable auth on your MongoDB instance. I don't know how compose.io works specifically, but I usually modify the mongod.conf file, and comment the line auth=true.
After that, you can connect to your MongoDB shell and create a user in the admin database.
Give the user the role userAdminAnyDatabase instead of just useAdmin.
use admin
db.createUser({ user:"admin", pwd: "pass", roles: [{role: "userAdminAnyDatabase", db: "admin"}] })
An user with the role userAdminAnyDatabase can manage the users of all the databases.
Now enable auth again and restart the service.
As I said, I'm not sure how compose.io actually works and how much control it gives to you. If you don't have an admin account, this should be the way to go.
By the way, I've published an article on Medium about MongoDB 3.0 auth.

This solved my problem:
I finally got it to work on compose.io! So here it what my oplog url ended up looking like:
"MONGO_OPLOG_URL": "mongodb://username:password#single.18.mongolayerhost.com:1111/local?authSource=myDB"
I keep the MONGO_URL exactly the same as the URL compose.io provides with ?replicaSet
But for the OPLOG_URL you can only use a single host, not multiple. So you have to edit the URL compose.io gives you to only have one host. And you can't end the oplog with ?replicaSet. you can only have the ?replicaSet in the MONGO_URL.
source

Flow to set authentication :
Start MongoDB without access control.
mongod --port 27017 --dbpath /data/db1
Connect to the instance.
mongo --port 27017
Create the user administrator.
use admin
db.createUser(
{
user: "myUserAdmin",
pwd: "abc123",
roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
}
)
Re-start the MongoDB instance with access control.
mongod --auth --port 27017 --dbpath /data/db1
Authenticate as the user administrator.
Start a mongo shell with the -u , -p , and the --authenticationDatabase command line options:
mongo --port 27017 -u "myUserAdmin" -p "abc123"
--authenticationDatabase "admin"
An user with the role userAdminAnyDatabase can manage the users of all the databases.
For routine user creation, you must possess the following permissions:
To create a new user in a database, you must have the createUser action on that database resource.
To grant roles to a user, you must have the grantRole action on the role’s database.
MongoDB stores all user information, including name, password, and the user's authentication database, in the system.users collection in the admin database.
More Details : https://docs.mongodb.com/manual/tutorial/enable-authentication/

You can try this:
use admin
db.createUser( { user: "user", pwd: "password", roles: [
"readWriteAnyDatabase","dbAdminAnyDatabase","clusterAdmin" ] } )

Related

How can I access my MongoDB on my Linode VPS?

I have a nodejs app running on my Linode VPS, with MongoDB installed. I cannot connected to the database on the same VPS as it gives me 'Unauthorised' error.
SETTING UP THE DB AND USER ON THE VPS
To set up the database on my MongoDB instance I SSH'd into my VPS and entered into the mongo shell:
$ mongo
I then switched to the admin database, and tried to view the users of it. The first stranage thing was it wouldnt let me do that:
use admin
switched to db admin
show users
The error I got was as follows:
2020-05-22T12:13:25.362+0100 E QUERY [js] Error: not authorized on admin to execute command { usersInfo: 1.0, lsid: { id: UUID("bbb18683-839f-4c7d-b453-f774cbc94efd") }, $db: "admin" } :
_getErrorWithCode#src/mongo/shell/utils.js:25:13
DB.prototype.getUsers#src/mongo/shell/db.js:1763:1
shellHelper.show#src/mongo/shell/utils.js:859:9
shellHelper#src/mongo/shell/utils.js:766:15
#(shellhelp2):1:1
I carried on, to create a user in the admin database, so that I could then create a user in my app's database to enable me to connect to the app's database:
db.createUser({user: "superAdmin",pwd: "admin123",roles: [ { role: "root", db: "admin" } ]})
Which was successfull:
Successfully added user: {
"user" : "superAdmin",
"roles" : [
{
"role" : "root",
"db" : "admin"
}
]
}
So I then re-loaded the mongod service and logged into the shell with the user I just made:
mongo --port 27017 -u "superAdmin" -p "admin123" --authenticationDatabase "admin"
I then switched to my app's db and made the user as follows:
use appDB
switched to db appDB
db.createUser({user: "DBuser",pwd: "DBpassword",roles: ["readWrite"]})
Successfully added user: { "user" : "DBuser", "roles" : [ "readWrite" ] }
ACCESSING THE DB WITH THE CREATED USER FROM THE APP ON SAME LINODE
Within my node.js app, which is on the same linode VPS I use the following connection URI:
'mongodb://DBuser:DBpassword#localhost:27017/appDB'
Now when I run the seeds file, whilst SSH'd into the VPS, to populate the database on the VPS I get an unauthorized error:
errmsg:
'not authorized on appDB to execute command { dropDatabase: 1, lsid: { id: UUID("b2c1ffc7-1912-42e3-8f74-ab3726dff3f2") }, $db: "appDB" }',
code: 13,
codeName: 'Unauthorized',
This error even happens when I try to use my frontend app to create a new record in the database.
I cannot even access my database instance on VPS via Insomnia.
This was all working locally without (the user name and password) in the DB URL.
How do I set my MongoDB instance up correctly to accept connections?
Any help would be greatly appreciated!
PS - I followed this instructions to set up my Linode: https://www.codementor.io/#tomgeraghty/hosting-an-express-server-nodejs-application-with-linode-e1j7wt7mr
You gave your user readWrite role, but that role doesn't allow execution of command dropDatabase, only the dbAdmin role can do that.
See the available built-in roles here: https://docs.mongodb.com/manual/reference/built-in-roles/
Ideally, you'd create yourself a custom role with all the necessary privileges required, and assign that role to your application's user.
More info on user-defined roles here: https://docs.mongodb.com/manual/core/security-user-defined-roles/

MongoDB add database and user after auth

I've an instance of MongoDB 4 running on server with replica set on same machine with differente ports.
I've created a super user using these commands:
use admin
db.createUser({user: "mongo_admin",pwd: "password",roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]);
then I've created a dedicated user for my new db database1
use database1
db.createUser({
user: "user1",
pwd: "password",
roles: ["readWrite", "dbAdmin"]
});
after this, I've enabled auth an so I user db.auth to working with my database1 (using "user1").
That's good and it works.
Now, my problem is: I need to create other database and then create a dedicated user for admin this database but, with auth enabled I can't do anything on the new created database database2. If I try, using my mongo_admin superuser to connect to the new database2 and trying to create a dbAdmin for this database using this command:
mongo
db.auth("mongo_admin", "password")
use database2
db.createUser({user: "user2, pwd: "password",roles: ["readWrite", "dbAdmin"]});
I recive this error:
E QUERY [js] Error: couldn't add user: not authorized on database2 to execute command
So, now I know that I can disable auth and work free on every database but, I don't want to do this because database is on production and I prefer to avoid this.
Any suggestion?

How to access databases if admin db dropped?

While using mongodb I accidentally dropped 'admin' db. Now I cannot access any of the database.
replicaSet1:PRIMARY> db.auth("root","root")
1
replicaSet1:PRIMARY> db.dropDatabase()
{ "dropped" : "admin", "ok" : 1 }
replicaSet1:PRIMARY> db.auth("root","root")
Error: Authentication failed.
0
Follow below steps to restore admin database and access to other database using admin user:
(1) Connect local database with system user using keyfile.
mongo -u __system -p "$(tr -d '\011-\015\040' < path-to-keyfile)"
--authenticationDatabase local
note: path-to-keyfile = this is your key-file path of mongo.
(2) Switch to admin database.
use admin
(3) Create Admin user with 'dbOwner, readWrite and readAnyDatabase' roles.
db.createUser({user: "admin", pwd: "cal#cas", roles: [{ role:
"dbOwner", db: "admin" },{ role: "readWrite", db: "admin" },{ role:
"readAnyDatabase", db: "admin" }]});
(4) View database list using below command.
show dbs;
Deleting admin db means loosing access to all the databases.
Enable localhost authentication bypass(if not enabled) and restart mongod. Now create the users again.

mongodb backup role - mongodump

We have a development team that will periodically take a mongodump out of DEV and then restore it back to their local host for work. We have recently implemented authentication in mongodb and i would like to be able to allow our development team do a mongodump on one DB only so they can restore it to their local host.
I have a role that inherits the backup role from Admin, but that is for our DBA to backup the whole system.
My question, how do I allow for this backup role to be used by a specific user (lets call them "webdev") for a specific DB (lets call it "products")?
You can create an user in the products database with read permissions:
> use products
> db.createUser( {
user: "webdev",
pwd: "password",
roles: [ "read" ]
} )
Just remember to call mongodump with --excludeCollectionsWithPrefix=system
mongodump --excludeCollectionsWithPrefix=system
In order to avoid permission errors (assuming you are using Mongo 3)
I am using MongoDB3.4 version, First of all you want one root access for admin database and connect mongo shell,
$ mongo -u username -p xxxxxx --authenticationDatabase admin
After connecting mongoshell, change the database,
use products
After change the DB create the new user,
db.createUser(
{
user: "webdev",
pwd: "xxxxx",
roles: [
{ role: "read", db: "products" },
{ role: "backup", db: "products"}
]
}
)
Above I mentioned, webdev user can be able to read the all collections and take backup access also.
db.auth('webdev', 'xxxxx')
after successfully authenticate, you can able to read and take backup from DEV server.
Below I mentioned mongodump query with new webdev user.
mongodump --host hostname --port 27017 --username webdev --password xxxxx --authenticationDatabase products --db products --collection collection_name --out mongodump_outpath
Refer: https://docs.mongodb.com/manual/reference/built-in-roles/#backup
Note:
Don't take mongodump frequently in production. It will impacts the
performance issue.
Don't give backup and restore access to any other teams like developer,
tester,..etc
Admin or DBA only do every time Backup/Restore.
Thank You. Please revert for any concern.

Mongodb revoke access to connect test database

I have an ec2 instance with mongodb 3.2.0 installed. I have a user with admin access. I can connect with user and perform operation remotely. But any one can connect the database test from remote if he knows the ip like mongo 11.11.11.11. Although he will not able to make any operations, but I want to restrict this access so that only user with credentials can connect to server.
first you need to create users and grant roles to those users, for example:
use admin
db.createUser(
{
user: "myUserAdmin",
pwd: "abc123",
roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
}
)
then you need to start your server with the --auth parameter
mongod --auth
More Information here