Mongos authentication - mongodb

We have 9 mongo nodes in our environment with:
1 mongos
3 config servers (mongod --configSvr)
9 mongod servers (shards or members of sharded replica-sets)
and we are trying to implement authentication on them.
I have done this in the past with a single server and it was really easy:
just add the admin user to the admin database
add a user on each database
I had to restart mongod with --auth option, but here it doesn't seem to work.
I've added the admin account to our mongos and for our sharded databases; I tried to authenticate as the user I had just created, but it didn't work.
I've tried creating an admin user on each database, and the other user accounts that we need, but it still didn't work.
I also tried making sure all of our mongo servers were running with the --keyFile option specified either on the command-line or in their /etc/mongodb.conf files, but that didn't seem to help.
When I try to authenticate as a given user, like so:
db.auth("user","passwd")
it fails and returns 0, as in false; not non-zero.
I seriously need all the help I can get, so please at least leave some suggestions on things I could try--I can't overstress this, any help is more than welcome since I don't seem to be getting anywhere just from following the official docs on managing/administrating mongo sharded clusters.

In a sharded cluster you should use --keyFile to allow all the members of the cluster to authenticate to each other. When you use this option, --auth is "assumed". Since there've been several version changes since you asked this question, the roles assigned to users are more granular now - you would need to have a 'clusterAdmin', 'userAdmin', 'dbAdmin', etc.
This page has more details about how to configure security in MongoDB for a sharded cluster.

Related

I followed the mongoDB docs and now cannot access my DB I get this error: connect ECONNREFUSED 127.0.0.1:27017

Below I list the directions I followed from the docs
Problem
After following the docs listed below I am unable to access my database. I most definitely did not forget my password as I actually saved the query that I ran to create the user I will list the query I ran below.
I get the following error when I try to connect my local host instance in MongoDB compass
connect ECONNREFUSED 127.0.0.1:27017
I think the issue might lie in the fact that I was running these command in the mongodb compass mongosh terminal and not the mongod
use admin
db.createUser(
{
user: "max",
pwd: "max",
roles: [
{ role: "userAdminAnyDatabase", db: "admin" },
{ role: "readWriteAnyDatabase", db: "admin" }
]
}
)
What I need Help with:
I need help accessing my local database and if possible setting up authentication on the schema
Below this line is the docs I followed
Start MongoDB without access control
Start a standalone
mongod
instance without access control.
Open a terminal and run the following command as the mongod user:
mongod --port 27017 --dbpath /var/lib/mongodb
The
mongod instance in this tutorial uses
port 27017
and the /var/lib/mongodb data directory.
The tutorial assumes that the /var/lib/mongodb directory exists and is the default
dbPath
. You may specify a different data directory or port as needed.
TIP
When
mongod
starts, it creates some system files in the /var/lib/mongodb directory. To ensure the system files have the correct ownership, follow this tutorial as the mongod user. If you start
mongod
as the root user you will have to update file ownership later.
Connect to the instance
Open a new terminal and connect to the database deployment with
mongosh
mongosh --port 27017
If you are connecting to a different deployment, specify additional command line options, such as
--host
, as needed to connect.
Create the user administrator
IMPORTANT
Localhost Exception
You can create the user administrator either before or after enabling access control. If you enable access control before creating any user, MongoDB provides a localhost exception which allows you to create a user administrator in the admin database. Once created, you must authenticate as the user administrator to create additional users.
I made sure that I made a user
Using
mongosh switch to the admin database add the myUserAdmin user with the userAdminAnyDatabase
and
readWriteAnyDatabase
roles":
use admin
db.createUser(
{
user: "myUserAdmin",
pwd: passwordPrompt(), // or cleartext password
roles: [
{ role: "userAdminAnyDatabase", db: "admin" },
{ role: "readWriteAnyDatabase", db: "admin" }
]
}
)
With respect to the technical issue, the error message that was provided (connect ECONNREFUSED 127.0.0.1:27017) suggests that the server is actively refusing the connection. Searching with this specific text surfaces lots of results that can probably help you solve the problem. This one, for example, suggests that one common reason for this error message is that the mongod process (the database itself) is not running. This is easy to test and reproduce, such as by trying to connect to a host and port where there is no mongod process running and listening. So I'd recommend taking a look at that question, or similar ones, to help troubleshoot and resolve your issue.
Also from the technical perspective, it is really important that we understand the different between the different processes associated with using MongoDB. As was noted in the comments:
The mongod process itself is the actual executable that needs to be up and running for the database to be accessible. Apart from starting this process with the appropriate parameters you don't do anything else with this. Typically this process needs to be --forked so that it does not stop when the command line is closed (which is what #Wernfried Domscheit was getting at in the comments). More information about this process is here in the documentation.
The shell(s) that are used to connect to and interact with the running database. The legacy one was mongo and the newer one (which is in Compass) is mongosh. This is an interface for connecting to and performing various tasks against the running database. This can include things like creating users or querying data.
This then bridges nicely toward the general advice part of this answer. It is important to keep in mind that, as of the time of writing, this question has been viewed more than 100 times. That represents a significant number of people who are volunteering their time in an attempt to help you without expecting anything in return. Said another way, we are trying to help you.
But in order to do so, we need to have an appropriate level of detail and context. It is great that you attempted to provide that information in the question itself, but ultimately it is not really enough for us to assist you effectively. Moreover, it is important to keep in mind that it is not a goal of this site (as far as I understand) to provide full tutorials or completely walkthrough configuring a new environment. Such guides can be found elsewhere, including in the documentation from the vendor that you linked. Having basic knowledge of the technology that you are working with is the foundation that allows for a "good" question. Such questions are those that allow us to help you in a focused and otherwise reasonable manner.
For MongoDB specifically, if you wanted to try to get additional support then you may try posting to the developer forums here.
The final point to make here is that it is worth considering what your ultimate goal here is. Operationally managing a database is often a task (or full job) that requires a lot of specific knowledge to perform correctly. This includes things like configuring the system properly to provide the high availability, data security, and other requirements needed by your application. Taking the time to learn these things yourself is certainly something that can be done, but the actual place that you should learn about them should probably be done primarily in a different place than this site. If you don't want to spend your time doing this, which is perfectly fine, then I would suggest looking into a hosted solution. Places like DigitalOcean and MongoDB itself offer such 'fully managed' solutions. Usually such solutions help extract away most of these underlying configuration/management details to help get you up and running faster with little upfront knowledge about operating databases being required. It may be something that is worth looking into, especially if you are just starting out on your MongoDB journey and have other tasks that you want to be focusing your time on.
I just uninstalled and reinstalled both MongoDB and MongoDB compass

MongoDB- backing up and restoring users and roles

What are best practices for synching users and roles between Mongo instances?
On the same Windows machine, I am trying to copy MongoDB users and roles in the admin database from one Mongo instance to another. Authentication is 'on' for each instance. No combination of mongodump\mongorestore or mongoexport\mongoimport I have tried works. With mongodump\restore, the restore step displays:
assuming users in the dump directory are from <= 2.4 (auth version 1)
Failed: the users and roles collections in the dump have an incompatible auth version with target server: cannot restore users of auth version 1 to a server of auth version 5
I found no command line option to tell it not to do this silly thing. I have Mongo version 4 and that's it installed.
You would think --dumpDbUsersAndRoles and --restoreDbUsersAndRoles would
be symmetrical, but they are not.
I was able to run this,
mongoexport -p 27017 -u admin --password please -d admin --collection system.roles --out myRoles.json
However, when trying mongoimport
mongoimport -p 26017 -u admin --password please -d admin --collection "system.roles" --file myRoles.json
the output displays
error validating settings: invalid collection name: collection name 'system.roles' is not allowed to begin with 'system.'
Primer
Users are attached to databases. Ideally, you have your database specific users stored in the respective database. All “global” users should go into admin. The good part: replica sets take care of syncing those users to each member of the replica set.
Solution
That being said, it seems to be quite obvious on how to deal with this.
For a worst case scenario, it is much easier to have a .js ready which simply recreates the 3-4 global roles instead
of fiddling with system.* collections in the admin database. This has the advantage that you can also do other setup stuff automatically, like sharding setup if TSHTF and you need to rebuild your cluster from scratch.
use admin;
db.createRole([...])
db.createRole([...])
// do other stuff, like sharding setup
Run it against the primary of your replica set or a mongos instance (if you have a sharded cluster) using
mongo daHost:27017/admin myjsfile.js
after you set up your machines but before you enable authentication.
Another option would be to use Ansible for user creation.
As for dump and restore, you might want to leave out the collection name.

How to reset root password in Mongodb?

I have a mongodb sharded cluster, with mongos machines, mongo nodes in replicate sets and config servers. MongoDB version is 3.02
The guy that set this up left the company a while ago and now I cant do simple things like show dbs or show collections
I have OS root in all these Debian machines, so I want to know how to reset mongo's root password so I can admin the database.
The apps that access this db seem to be working fine, using a user that has low privileges. I know the password for this particular user.
This is a production setup, so I can't afford to keep it down for more than a few seconds, tops minutes.
It depends on the types of users. For example, if you are using SCRAM, the basic steps to reset password would be:
Stop the mongod nodes
Disable authorization in mongod.conf
Restart the Replica set nodes
Connect to the replica set primary node using the mongo shell
Reset the your password by db.changePassword
I think this may work:
Stop your MongoDB instance
Remove the --auth and/or --keyfile options from your MongoDB config to disable authentication
Start the instance without authentication
Edit the users as needed
Restart the instance with authentication enabled
https://dba.stackexchange.com/questions/62976/how-can-i-enter-mongo-as-a-superuser-or-reset-users
This may not be the perfect answer, because I cannot test it. The base problem is of course that, that you cannot put your system into maintenance mode, where you can change admin password... But there is config file parameter security.transitionToAuth what you can add with rolling matter to your config file(s).
A mongod or mongos running with security.transitionToAuth does not enforce user access controls. Users may connect to your deployment without any access control checks and perform read, write, and administrative operations.
There are two options here
If you plan to upgrade to 3.4 this can be done without downtime:
MongoDB 3.4 allows Enforce Keyfile Access Control in a Replica Set without Downtime
You need to start all your members with --transitionToAuth(This will allow both authenticated and non-authenticated traffic for some duration)
Login to mongo shell on primary and create a userAdmin
Logout and login again using userAdmin
Create rootAdmin
Store the password in password manager
Disable transitionToAuth (Allow only authenticated traffic to replica set)
If you need to do this with existing MongoDB without upgrade:
Stop a secondaries in the replica set in a rolling manner. Disable authentication using keyFile options
Stepdown a primary and update its configuration to disable authentication.
Update you're the application to remove username and password from application config
Restart application
Create useradmin and rootAdmin in admin DB
Save passwords in the password manager
Enable authentication in the replica set
Start your application with the old config that includes username and password
Steps
Connect to the machine hosting your MongoDB instance
Open the MongoDB configuration file found in /etc/ folder using: sudo nano mongod.conf
Comment out the following code like so:
# security:
# authorization: enabled
Stop the MongoDB service: sudo service mongod stop
Start the MongoDB service: sudo service mongod start
Connect to the database using Robo3T or equivalent. With a connection to the admin collection, create a new admin superuser:
db.createUser({ user:"admin", pwd:"password", roles:[{role:"root", db:"admin"}] });
Go back and uncomment the lines from step 3. Then repeat steps 4 and 5.
You should now be able to authenticate with the new user you created in step 6 and have full access to the database.
Troubleshooting
If for whatever reason, after trying to restart your mongo service, you cannot connect to it, you can make sure the service properly started with: systemctl --type=service --state=active. If it has started, it will be in the list as mongod.service.
Mongo logs can also be found at /var/log/mongodb/mongodb.log but this is less likely to be helpful in this situation.

Locked outside mongodb replica set

I have a mongodb replica-set of 3 members (version 2.4) in which the administrator user for the 'admin' db does not have the 'userAdminAnyDatabase' role.
This role is required for managing the users on all databases.
The roles I currently have are: [ "readWriteAnyDatabase", "dbAdminAnyDatabase", "clusterAdmin" ]
I tried updating roles for myself or creating a new user, however I have no permission to access db.system.users in the admin db.
I tried setting noauth=true but that did not help. When removing the keyFile as well, the db was not able to sync with the other members (obviously) and got stuck in RECOVERY state.
I found a similar question that refers to a stand alone db (no replica set) so it doesn't really help in this case.
What would be the best way to add this role while having minimal system downtime?
I would use mongodump and mongorestore to backup the data then rebuild node with right permissions and restore the data.
However this approach should work:
If you have locked yourself out then you need to do the following:
Stop your MongoDB instance
Remove the --auth and/or --keyfile options from your MongoDB config
to disable authentication
Start the instance without authentication
Edit the users as needed
Restart the instance with authentication enabled
As you are using mongo 2.4, that means you have MMAP as a storage engine.
my proposal will be:
create similar replica set on each host but different port, and set database directory on same media as current one.
configure all auth stuff same as running ones
stop old replica set members
MOVE database files to new directory excluding local
change port on new replica set
start it
As moving files to other directory is just a pointer change this will take some seconds.
Please test before implementation.
Any comments welcome!

User field missing in system.profile collection when connecting with Mongos

We have a MongoDB cluster and clients connecting to it through a Mongos instance. The individual mongo(s) in the cluster are all running with --auth, and the Mongo use a --keyfile when communicating with them. We are profiling slow queries but are not getting the user names on queries that go through Mongo.
To make it clearer:
If I connect directly to one of the Mongo, authenticate, and run a query, then I can look in the system.profile collection afterwards, and the user field will be populated with my username.
If I connect through mongos, authenticate, and run a query, then the system.profile collection contains profiling info about the query, but the user field is blank.
The authentication is required, I can't run a query through Mongo without authenticating first, but the user name just doesn't seem to be included in the profiling info, and we'd really like to be able to see it.
Any ideas? Any alterations I can make to our configuration?
Just to actually add an answer:
As Ren stated in his comment, he filed a ticket, as this is related to a bug.