Starting MongoDB as a service with auth - mongodb

I created a mongodb replicaset (using 3.2) and on each server, I set up MongoDB as a service
"C:\Program Files\MongoDB\Server\3.2\bin\mongod.exe" --config "C:\program files\mongodb\server\3.2\mongod.cfg" --service
So far so good. I recently set up users and need to set up MongoDB so that a user has to be supplied. From what I've read, I would start mongodb with the --auth parameter. However, since the service is already created, is there an equivalent in the config file? Based on the Configuration File Options Documentions, I have tried security.authorization set to enable
security:
authorization: enabled
But when I restarted the service on both servers, it appears that neither could talk to each other. I also tried
setParameter:
auth
but MongoDB wouldn't start up with that configuration.
What's the right way to do this?

Since you are using a replica set, merely setting security.authorization is not sufficient as you need to allow for cluster members to authenticate which is referred to as "Internal Authentication" in the docs.
The easiest way to do this is using a keyfile which is essentially a shared secret/password among the cluster members. After you've created your keyfile and copied it to all of the replica set members, you'll need to specify it's location in your config via the security.keyFile setting or using --keyFile.
For reference, you may also want to read Enforce Keyfile Access Control on Existing Replica Set for more detail on these steps.

Related

MongoDB error not master and slaveOk=false

I am using MongoDB with Loopback in my application with a loopback connector to the MongoDB. My application was working fine but now it throws an error
not master and slaveOk=false.
try running rs.slaveOk() in a mongoDB shell
You are attempting to connect to secondary replica whilst previously your app (connection) was set to connect likely to the primary, hence the error. If you use rs.secondaryOk() (slaveOk is deprecated now) you will possibly solve the connection problem but it might not be what you want.
To make sure you are doing the right thing, think if you want to connect to the secondary replica instead of primary. Usually, it's not what you want.
If you have permissions to amend the replica configuration
I suggest to connect using MongoDB Compass and execute rs.status() first to see the existing state and configuration for the cluster. Then, verify which replica is primary.
If necessary, adjust priorities in the replicaset configuration to assign primary status to the right replica. The highest priority number sets the replica as primary. This article shows how to do it right.
If you aren't able to change the replica configuration
Try a few things:
make sure your hostname points to the primary replica
if it is a local environment issue - make sure you added your local replica hostnames to the /etc/hosts pointing to 127.0.0.1
experiment with directConnection=true
experiment with multiple replica hosts and ?replicaSet=<name> - read this article (switch tabs to replica)
The best bet is that your database configuration has changed and your connection string no longer reflects it correctly. Usually, slight adjustments in the connection string are needed or just checking to what instance you want to connect.

What is the correct MONGO_URL setting for replica sets on Meteor 1.4.1.1

This morning I went to deploy my updated Meteor project onto Heroku.
I was upgrading from 1.1.0.3 to 1.4.1.1.
Using the Meteor Buildpack Horse everything installed correctly, but the application was erroring out with the error;
MongoError: seed list contains no mongos proxies, replicaset connections requires the parameter replicaSet to be supplied in the URI or options object, mongodb://server:port/db?replicaSet=name
My MONGO_URL was mongodb://u:p#url1:port,url2:port/db so I changed it to;
mongodb://u:p#url1:port,url2:port/db?replicaSet=set-name
If I made a mistake with the replicaSet param I would get this error;
MongoError: no primary found in replicaset
Which seems sensible, since the replicaset didn't exist, but when I put the correct value in I get that original error again saying the seed list contains no proxies.
My replica set has a dash in the name, I don't know if that is relevant.
What I've tried
I've tried using the URL that throws this error in a Mongo client and it allows me to connect to the instance fine, so I know all the details are correct.
I've also tried escaping the replicaSet, so ?replicaSet=set\-name this gave me the MongoError: no primary found in replicaset error.
I have an open ticket with my MongoDB provider, but I suspect this is a Meteor/me issue!
Meteor v1.4 uses a new version of the MongoDB driver.
While the MONGO_URL environment variable was in the correct form, the error was caused by MONGO_OPLOG_URL, which should be modified to include a replicaSet argument.
See this GitHub issue for more details and the following notes (regarding Compose.io).
From the oplog driver documentation:
Oplog tailing is automatically enabled in development mode with meteor run, and can be enabled in production with the MONGO_OPLOG_URL environment variable.
(...)
To use oplog tailing in your production Meteor app, your MongoDB servers must be configured as a replica set; a single-mongod database has no oplog. Your cluster may not use Mongo sharding.
And the migration guide:
As of 1.4, you must ensure your MONGO_OPLOG_URL contains a replicaSet argument (see the changelog and the oplog documentation).
NOTE: Some MongoDB hosting providers may have a deployment setup that doesn't require you to use a replicaSet argument. For example, Compose.io has two types of deployments, MongoDB Classic and MongoDB+. The new MongoDB+ offering is a sharded setup and not a true replica set (despite the shard being implemented as a replica set) so it does not require the replicaSet parameter and Meteor will throw an error if you add it to your connection strings.

deploying mongodb on google cloud platform?

Hello all actually for my startup i am using google cloud platform, now i am using app engine with node.js this part is working fine but now for database, as i am mongoDB i saw this for mongoDB https://console.cloud.google.com/launcher/details/click-to-deploy-images/mongodb?q=mongo now when i launched it on my server now it created three instances in my compute engine but now i don't know which is primary instance and which is secondary, also one more thing as i read that primary instance should be used for writing data and secondary for reading, now when i will query my database should i provide secondary instance url and for updating/inserting data in my mongodb database should i provide primary instance url otherwise which url should i use for CRUD operations on my mongodb database ?? also after launcing this do i have to make any changes in any conf file or in any file manually or they already done that for me ?? Also do i have to make instance groups of all three instances or not ??
Please if any one of you think i have not done any research on this or its not a valid stackoverflow question then i am so sorry google cloud platform is very much new that's why there is not much documentation on it also this is my first time here in deploying my code on servers that's why i am completely noob in this field Thanks Anyways please help me ut of here guys.
but now i don't know which is primary instance and which is secondary,
Generally the Cloud Launcher will name the primary with suffix -1 (dash one). For example by default it would create mongodb-1-server-1 instance as the primary.
Although you can also discover which one is the primary by running rs.status() on any of the instances via the mongo shell. As an example:
mongo --host <External instance IP> --port <Port Number>
You can get the list of external IPs of the instances using gcloud. For example:
gcloud compute instances list
By default you won't be able to connect straight away, you need to create a firewall rule for the compute engines to open port(s). For example:
gcloud compute firewall-rules create default-allow-mongo --allow tcp:<PORT NUMBER> --source-ranges 0.0.0.0/0 --target-tags mongodb --description "Allow mongodb access to all IPs"
Insert a sensible port number, please avoid using the default value. You may also want to limit the source IP ranges. i.e. your office IP. See also Cloud Platform: Networking
i read that primary instance should be used for writing data and secondary for reading,
Generally replication is to provide redundancy and high availability. Where the primary instance is being used to read and write, and secondaries act as replicas to provide a level of fault tolerance. i.e. the loss of primary server.
See also:
MongoDB Replication.
Replication Read Preference.
MongoDB Sharding.
now when i will query my database should i provide secondary instance url and for updating/inserting data in my mongodb database should i provide primary instance url otherwise which url should i use for CRUD operations on my mongodb database
You can provide both in MongoDB URI and the driver will figure out where to read/write. For example in your Node.js you could have:
mongodb://<instance 1>:<port 1>,<instance 2>:<port 2>/<database name>?replicaSet=<replica set name>
The default replica set name set by Cloud Launcher is rs0. Also see:
Node Driver: URI.
Node Driver: Read Preference.
also after launcing this do i have to make any changes in any conf file or in any file manually or they already done that for me ?? Also do i have to make instance groups of all three instances or not ??
This depends on your application use case, but if you are launching through click and deploy the MongoDB config should all be taken care of.
For a complete guide please follow tutorial : Deploy MongoDB with Node.js. I would also recommend to check out MongoDB security checklist.
Hope that helps.

mongodb keyfile and -auth

I'm trying to learn mongoDB Replica set. Now I have three servers: one to be primary, one to be secondary, and the last one to be the arbiter. I was told to build a keyfile and use it for mongod startup command. So, what does this keyfile really do? I do not understand the role a keyfile is playing. And, when I use this keyfile, does it automatically turn -auth on? Do I have to create a new user and auth him? If I have to do this operation, on which machine should I take this action?
A key file contains the key, or password if you like, that the cluster members use to communicate.
The key file should reside on all cluster members.
Specifying a key file should imply authorization enabled.
If I'm not mistaken, you should create the user on the primary, this will apply to all three servers.

How to add new server in replica set in production

I am new to mongodb replica set.
According to Replic Set Ref this should be connection string in my application to connect to mongodb
mongodb://db1.example.net,db2.example.net,db3.example.net:2500/?replicaSet=test
Suppose this is production replica set (i.e. I cannot change application code or stop all the mongo servers) And, I want to add another mongo db instance db4.example.net in test replica set. How will I do that?
How my application will know about the new db4.example.net
If you are looking for real-world scenario:
In situation when any of existing server is down due to hardware failure etc, it is natural to add another db server to the replica set to preserve the redundancy. But, how to do that.
The list of replica set hosts in your connection string is a "seed list", and does not have to include all of the members of your replica set.
The MongoDB client driver used by your application will iterate through the seed list until it can successfully connect to a host, and use that host to request the current replica set configuration which will list all current members of the replica set. Per the documentation, it is recommended to include at least two hosts in the connect string so that your driver can still connect in the event the first host happens to be down.
Any changes in replica set configuration (i.e. adding/removing members or election of a new primary) are automatically discovered by your client driver so you should not have to make any changes in the application configuration to add a new member to your replica set.
A change in replica set configuration may trigger an election for a new primary, so your application code should expect to handle transient errors for a few seconds during reconfiguration.
Some helpful mongo shell commands:
rs.conf() - display the current replication configuration
db.isMaster().primary - display the current primary
You should notice a version number in the configuration document returned by rs.conf(). This version is incremented on every configuration change so drivers and replica set nodes can check if they have a stale version of the config.
How my application will know about the new db4.example.net
Just rs.add("db4.example.net") and your application should discover this host automatically.
In your scenario, if you are replacing an entirely dead host you would likely also want to rs.remove() the original host (after adding the replacement) to maintain the voting majority for your replica set.
Alternatively, rather than adding a host with a new name you could replace the dead host with a new server using the same hostname as previously configured. For example, if db3.example.net died, you could replace it with a new db3.example.net and follow the steps to Resync a replica set member.
A way to provide abstraction to your database is to set up a sharded cluster. In that case, the access point between your application and the database are the mongodb routers. What happens behind them is outside of the visibility of the application. You can add shards, remove shards, turn shards into replica-sets and change those replica-sets all you want. The application keeps talking with the routers, and the routers know which servers they need to forward them. You can change the cluster configuration at runtime by connecting to the routers with the mongo shell.
When you have questions about how to set up and administrate MongoDB clusters, please ask on http://dba.stackexchange.com.
But note that in the scenario you described, that wouldn't even be necessary. When one of your database servers has a hardware failure and your system administrators want to replace it without application downtime, they can just assign the same IP and hostname to the new server so the application doesn't even notice that it's a replacement.
When you want to know details about how to do this, you will find help on http://serverfault.com