How to create MongoDB Replica Set with Authentication Ubuntu 16.04
How to make a MongoDB replica set
A three member mongodb replica set on three separate hosts with authentication. Also see official docs.
In this tutorial we're putting MongoDB on three different hosts. We generate and use keyfile. The keyfile gets used as part of a Salted Challenge Response Authentication Mechanism (SCRAM) Mechanism.
If the members of your deployment are run on different hosts or if you wish remote clients to connect to your deployment, you must specify --bind_ip or net.bindIp.
First see:
- Getting started with MongoDB
- Install MongoDB on Ubuntu 16.04
- Note that each member of the replica set uses the same internal authentication mechanism and settings.
- You will need to create three instances / vps / servers to be members of your replica set.
Here's a referral link to create three VPS instances on Vultr which is cheaper than Digital Ocean (select Miami location). Annoyingly, you'll have to create two $2.50 instances by selecting Miami location and one $5 instance because Vultr doesn't allow the account to spin up 3 $2.50 instances...and imho Vultr should make this clearer in their on-boarding.
Enter each instances ip address here and the tutorial will be easier:
1. Create a keyfile
On one of your instances, create a key file.
openssl rand -base64 756 > /var/lib/mongodb/keyfile &&
chmod 400 /var/lib/mongodb/keyfile &&
chown mongodb:mongodb /var/lib/mongodb/keyfile
The chmod is needed because "the keyfile must not have group or world permissions".
2. Copy keyfile to each replica set member
rsync -av /var/lib/mongodb/keyfile root@ip-of-your-second-instance:/var/lib/mongodb
..and on the third instance
rsync -av /var/lib/mongodb/keyfile root@ip-of-your-third-instance:/var/lib/mongodb
Note that we're using rsync
which allows us to preserve the ownership permissions of the file. You have rsync installed by default on Ubuntu 16.04, woopie!
3. Restart each member of the replica set with access control enabled
By default your MongoDB instances are only binding (listening) on localhost (127.0.0.1) and listening on all interfaces 0.0.0.0
without authentication would be dangerous (you'd be hacked within a day, if not less).
Running mongod with the --keyFile command-line option or the security.keyFile configuration file setting enforces both Internal Authentication and Role-Based Access Control.
Create a mongod config file
Do this on each of your instances.
Stop mongod
sudo service mongod stop
Update a config file
sudo vim /lib/systemd/system/mongod.conf
Enter the following:
Un-comment out the security section, and enter:
security:
keyFile: /var/lib/mongodb/keyfile
Un-comment-out the replication section, and enter:
replication:
replSetName: replicaSetOne
Edit the net
section by removing bindIp
line and update it to:
net:
bindIpAll: true
Leave the port default to 27017
.
Warning: Do not set
bindIpAll: true
without setting a keyFile. Doing so would leave your replica set open on all interfaces without authentication!
Start mongod with authentication
sudo mongod --config /var/lib/mongodb/config&
Because we're passing in the config file, and we've specified the path of a keyFile, mongod will not enforce both Internal Authentication and Role-Based Access Control which is doesn't do by default.
Complete the above steps for each instance.
4. Connect to a member of the replica set over the localhost interface.
Connect to your first mongo instance via ssh. We're going to create a user on the initial instance.
$ mongo <Press ENTER>
This will give you the mongo shell.
The localhost interface is only available since no users have been created for the deployment. The localhost interface closes after the creation of the first user.
5. Initiate the replica set.
Finally!
Only run this on one mondod instance!
rs.initiate(
{
_id : 'replicaSetOne',
members: [
{ _id : 0, host : "ip-of-instance-1:27017" },
{ _id : 1, host : "ip-of-instance-2:27017" },
{ _id : 2, host : "ip-of-instance-3:27017" }
]
}
)
MongoDB will then try and:
- Communicate to all members of the replica set
- Attempt a dry run an election
- Run an election to select a primary node out of the three instances. Cool!
Run rs.status()
from the mongo shell if you want to find out which of your nodes was selected as primary.
6. Create the user administrator
IMPORTANT
After you create the first user, the localhost exception is no longer available.
The first user must have privileges to create other users, such as a user with the userAdminAnyDatabase. This ensures that you can create additional users after the Localhost Exception closes.
If at least one user does not have privileges to create users, once the localhost exception closes you may be unable to create or modify users with new privileges, and therefore unable to access necessary operations!
You **must**
be connected to the primary to create users. Remember, run rs.status()
from the mongo shell to find out which instance is the primary.
Choose a username and strong password. Then, from the mongo shell on your primary run:
admin = db.getSiblingDB("admin")
admin.createUser(
{
user: "admin",
pwd: "changeme1",
roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
}
)
You should see "Successfully added user
" as the response.
Verify your admin user
Exit out of the mongo sell (Ctrl+c
).
Log into your mongo instance:
$ mongo
Try and show all databases:
show dbs
This should fail.
Authenticate:
db.getSiblingDB("admin", "password");
show dbs
The above should succeed showing you three default databases:
admin 0.000GB
config 0.000GB
local 0.000GB
Optional
You may want to now