MongoDB replica set authentication guide

MongoDB replica set authentication guide

Share Everywhere

Table of contents

1. Create replica set

Launch EC2 instance & install mongoDB

You have to launch at least 3 EC2 instances. Make sure those 3 instances can connect to each other (set up ssh key, ssh config and check security groups). Use ansibe playbook (role XX.mongodb) to install mongoDB

Create mongoDB replica set

  1. In the first instance:
mongo

When mongo shell appear, run:

rs.status()
rs.initiate()

MongoDB will make the current EC2 instance become PRIMARY

  1. Add members to the replica set:
rs.add( { host: "ip-172-31-37-61.ap-northeast-1.compute.internal:27017" } )
rs.add( { host: "ip-172-31-44-98.ap-northeast-1.compute.internal:27017" } )
  1. Try to connect to the replica set:
mongo --host mongo-002
mongo --host mongo-003

Note that mongo-002 and mongo-003 is the DNS of the 2 private-IP instances: 172.31.37.61 and 172.31.44.98 (you can set alias in /etc/hosts)

If success ⇒ OK!

You can log in to mongo shell and see the status of the replica set. Example of result of rs.status() command:

rsCMS:PRIMARY> rs.status()
{
        "set" : "rsCMS",
        "date" : ISODate("2021-07-19T10:35:35.903Z"),
        "myState" : 1,
        "term" : NumberLong(3),
        "syncingTo" : "",
        "syncSourceHost" : "",
        "syncSourceId" : -1,
        "heartbeatIntervalMillis" : NumberLong(2000),
        "optimes" : {
                "lastCommittedOpTime" : {
                        "ts" : Timestamp(1626690933, 1),
                        "t" : NumberLong(3)
                },
                "readConcernMajorityOpTime" : {
                        "ts" : Timestamp(1626690933, 1),
                        "t" : NumberLong(3)
                },
                "appliedOpTime" : {
                        "ts" : Timestamp(1626690933, 1),
                        "t" : NumberLong(3)
                },
                "durableOpTime" : {
                        "ts" : Timestamp(1626690933, 1),
                        "t" : NumberLong(3)
                }
        },
        "lastStableCheckpointTimestamp" : Timestamp(1626690893, 1),
        "electionCandidateMetrics" : {
                "lastElectionReason" : "electionTimeout",
                "lastElectionDate" : ISODate("2021-07-19T09:52:53.446Z"),
                "electionTerm" : NumberLong(3),
                "lastCommittedOpTimeAtElection" : {
                        "ts" : Timestamp(0, 0),
                        "t" : NumberLong(-1)
                },
                "lastSeenOpTimeAtElection" : {
                        "ts" : Timestamp(1626685293, 1),
                        "t" : NumberLong(2)
                },
                "numVotesNeeded" : 2,
                "priorityAtElection" : 1,
                "electionTimeoutMillis" : NumberLong(10000),
                "numCatchUpOps" : NumberLong(0),
                "newTermStartDate" : ISODate("2021-07-19T09:52:53.452Z"),
                "wMajorityWriteAvailabilityDate" : ISODate("2021-07-19T09:52:54.774Z")
        },
        "members" : [
                {
                        "_id" : 0,
                        "name" : "ip-172-31-43-145.ap-northeast-1.compute.internal:27017",
                        "health" : 1,
                        "state" : 1,
                        "stateStr" : "PRIMARY",
                        "uptime" : 2795,
                        "optime" : {
                                "ts" : Timestamp(1626690933, 1),
                                "t" : NumberLong(3)
                        },
                        "optimeDate" : ISODate("2021-07-19T10:35:33Z"),
                        "syncingTo" : "",
                        "syncSourceHost" : "",
                        "syncSourceId" : -1,
                        "infoMessage" : "",
                        "electionTime" : Timestamp(1626688373, 1),
                        "electionDate" : ISODate("2021-07-19T09:52:53Z"),
                        "configVersion" : 5,
                        "self" : true,
                        "lastHeartbeatMessage" : ""
                },
                {
                        "_id" : 1,
                        "name" : "ip-172-31-44-98.ap-northeast-1.compute.internal:27017",
                        "health" : 1,
                        "state" : 2,
                        "stateStr" : "SECONDARY",
                        "uptime" : 2416,
                        "optime" : {
                                "ts" : Timestamp(1626690933, 1),
                                "t" : NumberLong(3)
                        },
                        "optimeDurable" : {
                                "ts" : Timestamp(1626690933, 1),
                                "t" : NumberLong(3)
                        },
                        "optimeDate" : ISODate("2021-07-19T10:35:33Z"),
                        "optimeDurableDate" : ISODate("2021-07-19T10:35:33Z"),
                        "lastHeartbeat" : ISODate("2021-07-19T10:35:34.142Z"),
                        "lastHeartbeatRecv" : ISODate("2021-07-19T10:35:34.742Z"),
                        "pingMs" : NumberLong(0),
                        "lastHeartbeatMessage" : "",
                        "syncingTo" : "ip-172-31-37-61.ap-northeast-1.compute.internal:27017",
                        "syncSourceHost" : "ip-172-31-37-61.ap-northeast-1.compute.internal:27017",
                        "syncSourceId" : 2,
                        "infoMessage" : "",
                        "configVersion" : 5
                },
                {
                        "_id" : 2,
                        "name" : "ip-172-31-37-61.ap-northeast-1.compute.internal:27017",
                        "health" : 1,
                        "state" : 2,
                        "stateStr" : "SECONDARY",
                        "uptime" : 2570,
                        "optime" : {
                                "ts" : Timestamp(1626690933, 1),
                                "t" : NumberLong(3)
                        },
                        "optimeDurable" : {
                                "ts" : Timestamp(1626690933, 1),
                                "t" : NumberLong(3)
                        },
                        "optimeDate" : ISODate("2021-07-19T10:35:33Z"),
                        "optimeDurableDate" : ISODate("2021-07-19T10:35:33Z"),
                        "lastHeartbeat" : ISODate("2021-07-19T10:35:34.142Z"),
                        "lastHeartbeatRecv" : ISODate("2021-07-19T10:35:35.483Z"),
                        "pingMs" : NumberLong(0),
                        "lastHeartbeatMessage" : "",
                        "syncingTo" : "ip-172-31-43-145.ap-northeast-1.compute.internal:27017",
                        "syncSourceHost" : "ip-172-31-43-145.ap-northeast-1.compute.internal:27017",
                        "syncSourceId" : 0,
                        "infoMessage" : "",
                        "configVersion" : 5
                }
        ],
        "ok" : 1,
        "operationTime" : Timestamp(1626690933, 1),
        "$clusterTime" : {
                "clusterTime" : Timestamp(1626690933, 1),
                "signature" : {
                        "hash" : BinData(0,"hzd0+nqjoPVXbOcLPn1wM0sZiJM="),
                        "keyId" : NumberLong("6986536417509769219")
                }
        }
}
rsCMS:PRIMARY>

  1. Insert some sample data:
db.products.insert( { item: "card", qty: 15 } )

2. Create replica set authentication

1. Create keyfile:

cd /srv/
sudo mkdir mongodb
openssl rand -base64 756 > /srv/mongodb/keyfile
chmod 400 /srv/mongodb/keyfile
sudo chown mongod /srv/mongodb/keyfile

Note: You have to copy the keyfile that you have generated to each replica set member (also have to chmod 400 and chown mongod on member servers)

  1. Run ansible copy toi /nfs/

2. Create superuser:

Note: You have to stand on the Primary server to do this!

You have to create user root before you enable access control for the replica set. To create other users, you have to log into user root!

Log in to the mongo shell

mongo

and run:

admin = db.getSiblingDB("admin")
admin.createUser(
  {
    user: "root",
    pwd: "root",
    roles: [ { role: 'root', db: 'admin' } ]
  }
)

3. Shutdown all the members of the replica set:

  • SSH to the MongoDB servers
  • Run: sudo systemctl stop mongod

4. Modify the /etc/mongod.conf file:

You have to add security.keyFile option to the replica set:

# mongod.conf

# for documentation of all options, see:
#   <http://docs.mongodb.org/manual/reference/configuration-options/>

# where to write logging data.
systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/mongod.log

# Where and how to store data.
storage:
  dbPath: /var/lib/mongo
  journal:
    enabled: true
#  engine:
#  mmapv1:
#  wiredTiger:

# how the process runs
processManagement:
  fork: true  # fork and run in background
  pidFilePath: /var/run/mongodb/mongod.pid  # location of pidfile
  timeZoneInfo: /usr/share/zoneinfo

# network interfaces
net:
  port: 27017
#  bindIp: 127.0.0.1  # Enter 0.0.0.0,:: to bind to all IPv4 and IPv6 addresses or, alternatively, use the net.bindIpAll setting.
  bindIp: 0.0.0.0

#security:
security:
   authorization: enabled
   keyFile: /srv/mongodb/keyfile

#operationProfiling:

replication:
  replSetName: "rsCMS"

#sharding:

## Enterprise-Only Options

#auditLog:

#snmp:

5. Start mongod again:

SSH to your mongodb servers and run:

sudo systemctl start mongod

6. Log into the mongo shell with root user:

You now can log into mongoDB using root user:

mongo -u "root" -p  --authenticationDatabase "admin"

Note: With users that authenticationDatabase is admin, –authenticationDatabase “admin” is optional

3. Create users:

1. Create user same as root but can not access to config and local:

admin = db.getSiblingDB("admin")
admin.createUser(
  {
    user: "adminrw",
    pwd: "adminrw",
    roles: [ { role: "readWriteAnyDatabase", db: "admin" } ]
  }
)

2. Create DB read only user (but can not read config and local db):

admin = db.getSiblingDB("admin")
admin.createUser(
  {
    user: "read",
    pwd: "read",
    roles: [ { role: "readAnyDatabase", db: "admin" } ]
  }
)

3. Create Database – level access control user:

use testDB1
db.createUser(
  {
    user: "admin1",
    pwd: "admin1",
    roles: [ { role: "readWrite", db: "testDB1" } ]
  }
)

When log in:

mongo -u "admin1" -p  --authenticationDatabase "testDB1"

Note: –authenticationDatabase “testDB1” is neccessary. If you do not specify ⇒ can not authenticate.

4. Create collection – level access control user:

  1. Create user – defined role:
use admin
db.createRole(
   {
     role: "manageOpRole", 
     privileges: [
       { resource: { db: "test", collection: "products" }, actions: [ "find", "update", "insert" ] },
	   { resource: { db: "testDB1", collection: "user" }, actions: [ "find", "update" ] },
	   { resource: { db: "testDB2", collection: "" }, actions: [ "listCollections" ] }
     ],
     roles: []
   }
)
  1. Create user and attach role:
admin = db.getSiblingDB("admin")
admin.createUser(
  {
    user: "cadmin2",
    pwd: "cadmin2",
    roles: [ { role: "manageOpRole", db: "admin" } ]
  }
)

4. Testing

Note: In our case, mongo-003 is primary and 001, 002 are secondaries.

Case 1: Log in to mongo shell and do not provide any authentication data ⇒ Can not find db information

MongoDB replica set authentication guide
MongoDB replica set authentication guide

Even in the case that you know that there are dbs that exist:

MongoDB replica set authentication guide
MongoDB replica set authentication guide

You can not interact with dbs

Case 2: Log into mongo shell, provide wrong authentication data:

  • Wrong password:
MongoDB replica set authentication guide
  • Wrong username:
MongoDB replica set authentication guide

Case 3: Log into mongo shell with correct authentication data:

MongoDB replica set authentication guide

Log into mongo shell with correct authentication data on secondaries:

MongoDB replica set authentication guideMongoDB replica set authentication guide

Case 4: Read Write any database but not config and local:

  • When log into by root user:
Create collection – level access control:
  • Log in by root user in secondaries:
Create collection – level access control:Log into by adminrw user:
  • Log into by adminrw user:
Create collection – level access control:

Case 5: Read only but can not read local and config DB: (log in to by read user)

Create collection – level access control:

Case 6: Access control for only one DB only: (Log into by admin1 user)

  • If connect to wrong DB:
Create collection – level access control:
  • Connect to right DB:
Create collection – level access control:

Case 7: Create collection – level access control:

Create collection – level access control:

 

Bạn thấy bài viết này như thế nào?
0 reactions

Add new comment

Restricted HTML

  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.
Image CAPTCHA
Enter the characters shown in the image.

Bài viết liên quan

Cùng mình đập hộp xem bên trong có gì nhé.

Câu chuyện học AWS nên học từ đâu và trở thành AWS Community Builder

Sau 2 tháng đăng ký làm thành viên của AWS Community Builder thì hôm nay mình đã nhận được quà của AWS từ Singapore.
Ngoài ra còn có rất nhiều câu chuyện và chia sẻ kỹ thuật hữu ích nữa

Ngoài ra còn có rất nhiều câu chuyện và chia sẻ kỹ thuật hữu ích nữa

Năm nay mình có dịp trở lại với Singapore, một đất nước rất xanh, sạch, và đẹp, ở đâu cũng thấy mọi người tập thể dục ngoài trời
Democratize analytics and machine learning with no-code AWS services

Democratize analytics and machine learning with no-code AWS services

Access to all data for fast analytics at scale is key for 360-degree projects involving data engineers
Train ML models quickly and cost-effectively with Amazon SageMaker

Train ML models quickly and cost-effectively with Amazon SageMaker

Training machine learning models at scale often requires significant investments
Go beyond insights to predictive analytics with Amazon Redshift ML and Amazon SageMaker Canvas

Go beyond insights to predictive analytics with Amazon Redshift ML and Amazon SageMaker Canvas

Organizations are managing more data than ever before, and data use is only continuing to expand.