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/
Related
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?
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.
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
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" ] } )
I'm trying to connect from a java application to a mongodb database in openshift and I'm having some trouble with roles and actions allowed.
I run the rch port-forward command like so:
rhc port-forward -a test
it all goes great and I'm able to connect to the database using:
mongo admin -u admin -p '*******' --host 127.0.0.1 --port 44506
and I can execute commands like:
> use test
> show databases
But if i connect directly to my database using:
mongo test -u admin -p '*******' --host 127.0.0.1 --port 44506
I'm unable to run the show databases command
listDatabases failed:{ "ok" : 0, "errmsg" : "unauthorized" } at src/mongo/shell/mongo.js:47
How can i give action listDatabases to this user in this database?
I found this page in the mongodb documentation http://docs.mongodb.org/manual/reference/privilege-actions/#security-user-actions
Which talks about Diagnostic Actions but does not mention how to give such action to a user.
Thanks for the help.
As mentioned by wdberkeley, you have to have a user in the admin database with the ability to list databases.
To do this, you first have to create a very minimal "role" for this user allowing them to list databases, and then create a user with both this role and the role for reading and writing your other database:
use admin
db.runCommand({ createRole: "listDatabases",
privileges: [
{ resource: { cluster : true }, actions: ["listDatabases"]}
],
roles: []
})
db.createUser({
user: "<userName>",
pwd: "<passwd>",
roles: [
{ role: "readWrite", db: "test" },
{ role: "listDatabases", db: "admin" }
]
})
The MongoDB documentation has references for both createRole and createUser, if you want to learn more about these commands.
You're logging in as two different users. Users are scoped by namespace, so user John who lives in test is not the same as user John who lives in admin, though both Johns may have rights in the test database. I think this much you may already understand, but I wanted to clarify it just in case.
I don't believe you can give a user scoped to a non-admin database the listDatabases action in a privilege because the listDatabases action must go with the cluster resource (listDatabases is a cluster-wide sort of operation), and a privilege with a cluster resource can only be scoped to a role on the admin database. Cutting out the jargon of MongoDB's authorization model, a non-admin database user can't use listDatabases because it's a cluster-wide operation and only admin database users should be able to do cluster-wide things.
Just want to add the approach mentioned by i80and works on MongoDB 3.2.3
create custom role that contain listDatabase and specify cluster:true, I did it when specify resource as db, it doesn't work
grant this role to user
Note: make sure you are connected to the correct db when performing security task because you will need to be authenticated using this specific db where the user is created