Update Replica Set to Keyfile Authentication (No Downtime)

Overview

To secure against unauthorized access, enforce authentication for your deployments. Authenticationfor replica sets consists of internal authenticationamong the replica set members, and user access controlfor clients connecting to the replica set.

If your deployment does not enforce authentication, MongoDB 3.4+ provides the—transitionToAuth option for performing a no-downtime upgrade toenforcing authentication.

New in version 3.4: MongoDB 3.2 and earlier do not support a no-downtime upgrade to enforceauthentication. SeeUpdate Replica Set to Keyfile Authentication forenforcing authentication in an existing MongoDB 3.2 replica set.

This tutorial uses the keyfile internalauthentication mechanism for internal security, andSCRAM-based role-based access controls for client connections.

Cloud Manager and Ops Manager

If you are using Cloud Manager or Ops Manager to manage your deployment,see the respective Cloud Manager manualor the Ops Manager manual to enforce authentication.

Architecture

This tutorial assumes that your replica set can elect a newprimary after stepping down the existing primary replica set member.This requires:

Transition State

A mongod running with —transitionToAuth accepts bothauthenticated and non-authenticated connections. Clients connected to themongod during this transition state can perform read, write, andadministrative operations on any database.

Client Access

At the end of the following procedure, the replica set rejects anyclient attempting to make a non-authenticated connection. The procedure createsusers for client applications to use when connecting to thereplica set.

See Configure Role-Based Access Control for user creation andmanagement best practices.

IP Binding

Changed in version 3.6.

Starting with MongoDB 3.6, MongoDB binaries, mongod andmongos, bind to localhost by default.From MongoDB versions 2.6 to 3.4, only the binaries from theofficial MongoDB RPM (Red Hat, CentOS, Fedora Linux, and derivatives)and DEB (Debian, Ubuntu, and derivatives) packages would bind tolocalhost by default. To learn more about this change, seeLocalhost Binding Compatibility Changes.

Passwords

Important

Passwords should be random, long, and complex to ensure systemsecurity and to prevent or delay malicious access.

Enforce Keyfile Access Control on Existing Replica Set

Tip

When possible, use a logical DNS hostname instead of an ip address,particularly when configuring replica set members or sharded clustermembers. The use of logical DNS hostnames avoids configurationchanges due to ip address changes.

Create the user administrator.

Connect to the primary to create a user withuserAdminAnyDatabase role. TheuserAdminAnyDatabase role grants access to user creationon any database in the deployment.

The following example creates the user fred with theuserAdminAnyDatabase role on the admin database.

Important

Passwords should be random, long, and complex to ensure systemsecurity and to prevent or delay malicious access.

Tip

Starting in version 4.2 of the mongo shell, you canuse the passwordPrompt() method in conjunction withvarious user authentication/management methods/commands to promptfor the password instead of specifying the password directly in themethod/command call. However, you can still specify the passworddirectly as you would with earlier versions of themongo shell.

  1. admin = db.getSiblingDB("admin")
  2. admin.createUser(
  3. {
  4. user: "fred",
  5. pwd: " passwordPrompt(), // or cleartext password
  6. roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
  7. }
  8. )

At the completion of this procedure, any client that administers users inthe replica set must authenticate as this user, or a user withsimilar permissions.

See Database User Roles for a full list of built-in roles andrelated to database administration operations.

Create the cluster administrator.

Connect to the primary to create a user withclusterAdmin role. The clusterAdmin rolegrants access to replication operations, such as configuring thereplica set.

The following example creates the user ravi with theclusterAdmin role on the admin database.

Important

Passwords should be random, long, and complex to ensure system securityand to prevent or delay malicious access.

Tip

Starting in version 4.2 of the mongo shell, you canuse the passwordPrompt() method in conjunction withvarious user authentication/management methods/commands to promptfor the password instead of specifying the password directly in themethod/command call. However, you can still specify the passworddirectly as you would with earlier versions of themongo shell.

  1. db.getSiblingDB("admin").createUser(
  2. {
  3. "user" : "ravi",
  4. "pwd" : passwordPrompt(), // or cleartext password
  5. roles: [ { "role" : "clusterAdmin", "db" : "admin" } ]
  6. }
  7. )

At the completion of this procedure, any client that administrates ormaintains the replica set must authenticate as this user, or a user withsimilar permissions.

See Cluster Administration Roles for a full list of built-in roles related toreplica set operations.

Create users for client applications.

Create users to allow client application to connect and interact with thereplica set. At the completion of this tutorial, clients must authenticate asa configured user to connect to the replica set.

See Database User Roles for basic built-in roles to usein creating read-only and read-write users.

The following creates a user with read and write permissionson the foo database.

Important

Passwords should be random, long, and complex to ensure system securityand to prevent or delay malicious access.

Create a user with thereadWrite role in the foo database.

Tip

Starting in version 4.2 of the mongo shell, you canuse the passwordPrompt() method in conjunction withvarious user authentication/management methods/commands to promptfor the password instead of specifying the password directly in themethod/command call. However, you can still specify the passworddirectly as you would with earlier versions of themongo shell.

  1. db.getSiblingDB("foo").createUser(
  2. {
  3. "user" : "joe",
  4. "pwd" : passwordPrompt(), // or cleartext password
  5. roles: [ { "role" : "readWrite", "db" : "foo" } ]
  6. }
  7. )

Clients authenticating as this user can perform read and write operationsagainst the foo database. See Authenticate a User formore on creating an authenticated connection to the replica set.

See the Add Users tutorial for more information onadding users. Consider security best practices when adding new users.

Update Client Applications

At this point in the procedure, the replica set does not enforceauthentication. However, client applications can still specify authcredentials and connect to the replica set.

Update client applications to authenticate to the replica set using aconfigured user. Authenticated connections require a username, password, andthe authentication database. See Authenticate a User.

For example, the following connects to a replica set named mongoRepland authenticates as the user joe.

  1. mongo -u joe -password -authenticationDatabase foo --host mongoRepl/mongo1.example.net:27017, mongo2.example.net:27017, mongo3.example.net:27017

If you do not specify the password to the -pcommand-line option, the mongo shell prompts for thepassword.

If your application uses a MongoDB driver, see the associateddriver documentation for instructions oncreating an authenticated connection.

At the completion of this tutorial, the replica set rejects non-authenticatedclient connections. Performing this step now ensures clients can connectto the replica set before and after the transition.

Create a keyfile.

With keyfile authentication, eachmongod instances in the replica set uses the contents of the keyfile as theshared password for authenticating other members in the deployment. Onlymongod instances with the correct keyfile can join the replica set.

Note

Starting in MongoDB 4.2, keyfiles for internal membershipauthentication use YAML format to allow formultiple keys in a keyfile. The YAML format accepts content of:

  • a single key string (same as in earlier versions),
  • multiple key strings (each string must be enclosed in quotes), or
  • sequence of key strings.

The YAML format is compatible with the existing single-keykeyfiles that use the text file format.

A key’s length must be between 6 and 1024 characters and may onlycontain characters in the base64 set. All members of thereplica set must share at least one common key.

Note

On UNIX systems, the keyfile must not have group or worldpermissions. On Windows systems, keyfile permissions are not checked.

You can generate a keyfile using any method you choose. For example,the following operation uses openssl to generate a complexpseudo-random 1024 character string to use as a shared password. It thenuses chmod to change file permissions to provide readpermissions for the file owner only:

  1. openssl rand -base64 756 > <path-to-keyfile>
  2. chmod 400 <path-to-keyfile>

See Keyfiles for additional details and requirementsfor using keyfiles.

Copy the keyfile to each replica set member.

Copy the keyfile to each server hosting the replica set members.Ensure that the user running the mongod instances is the owner of thefile and can access the keyfile.

Avoid storing the keyfile on storage mediums that can be easilydisconnected from the hardware hosting the mongod instances, such as aUSB drive or a network attached storage device.

Restart each secondary or arbiter member of the replica set with transitionToAuth.

Restart each secondary or arbiter member in thereplica set, including in the configuration:

You must restart each member one at a time to ensure a majority ofmembers in the replica set remain online.

Shut down the secondary or arbiter members.

From a mongo shell connected to the secondary or arbiter,issue the db.shutdownServer() against the admin database.

  1. admin = db.getSiblingDB("admin")
  2. admin.shutdownServer()

Restart the secondary or arbiter members with transitionToAuth

Specify the following settings in your configuration file.

Starting in MongoDB 3.6, mongod and mongosbind to localhost by default. If the members of your deployment arerun on different hosts or if you wish remote clients to connect toyour deployment, you must specify the net.bindIp setting.For more information, see Localhost Binding Compatibility Changes.

  1. security:
  2. keyFile: <path-to-keyfile>
  3. transitionToAuth: true
  4. replication:
  5. replSetName: <replicaSetName>

Specify the —config option with the path to the configurationfile when starting the mongod.

  1. mongod --config <path-to-config-file>

For more information on the configuration file, seeconfiguration options.

Alternatively, you can use the equivalent mongodcommand-line options (e.g. —transitionToAuth and—keyFile) when starting your mongod. See themongod reference page for a complete list of options.

Include additional settings as appropriate to your deployment.

At the end of this step, all secondaries and arbiters should be upand running with security.transitionToAuth set to true.

Step down the primary member of the replica set and restart it with —transitionToAuth.

Step down the primary member in the replica set and restartthe member, including in its configuration:

Step down the primary replica set member

Connect to the primary using a mongo shell and step down theprimary using the rs.stepDown() method.

  1. rs.stepDown()

Shut down the old primary

Once the primary steps down and the replica set elects a new primary,shut down the old primary mongod.

From a mongo shell connected to the old primary, issue thedb.shutdownServer() on the admin database.

  1. admin = db.getSiblingDB("admin")
  2. admin.shutdownServer()

Restart the old primary with transitionToAuth

Specify the following settings in your configuration file.

Include additional options as requiredfor your configuration. For instance, if you wish remote clients toconnect to your deployment or your deployment members are run ondifferent hosts, specify the net.bindIp setting. For moreinformation, see Localhost Binding Compatibility Changes.

  1. security:
  2. keyFile: <path-to-keyfile>
  3. transitionToAuth: true
  4. replication:
  5. replSetName: <replicaSetName>

Start the mongod using the configuration file.

  1. mongod --config <path-to-config-file>

For more information on the configuration file, seeconfiguration options.

Alternatively, you can use the equivalent mongodcommand-line options (e.g. —transitionToAuth and—keyFile) when starting your mongod. See themongod reference page for a complete list of options.

Include additional settings as appropriate to your deployment.

At the end of this step, all members of the replica set should be upand running with security.transitionToAuth set to trueand security.keyFile set to the keyfile path.

Restart secondaries and arbiters without —transitionToAuth

Restart each secondary or arbiter member in the replica set,removing the security.transitionToAuth option on restart. You must dothis one at a time to ensure a majority of members in the replica set remainonline.

If the majority of replica set members are offline at the same time, thereplica set may go into read-only mode.

Shut down the secondary or arbiter members

Connect to a mongo shell to the secondary or arbiter, andissue the db.shutdownServer() on the database.

  1. admin = db.getSiblingDB("admin")
  2. admin.shutdownServer()

Restart the secondary or arbiter members without transitionToAuth

Restart the mongod, this time without thesecurity.transitionToAuth option but with internal authenticationmechanism such as security.keyFile.

Specify the following settings in your configuration file.

Include additional options as requiredfor your configuration. For instance, if you wish remote clients toconnect to your deployment or your deployment members are run ondifferent hosts, specify the net.bindIp setting. For moreinformation, see Localhost Binding Compatibility Changes.

  1. security:
  2. keyFile: <path-to-keyfile>
  3. replication:
  4. replSetName: <replicaSetName>

Start the mongod using the configuration file:

  1. mongod --config <path-to-config-file>

For more information on the configuration file, seeconfiguration options.

You can also use the equivalent mongod options when starting yourmongod. See the mongod reference page for a complete list ofoptions.

Include additional settings as appropriate to your deployment.

At the end of this step, all secondaries and arbiters should be up andrunning with internal authentication configured, but withoutsecurity.transitionToAuth. Clients can only connect to thesemongod instances by using the configured client authenticationmechanism.

Step down and restart the primary replica set member without —transitionToAuth.

Step down the primary member in the replica set, then restart itwithout the security.transitionToAuth option.

Important

At the end of this step, clients not connecting with auth cannot connectto the replica set. Update clients to connect with authentication _before_completing this step to avoid loss of connectivity.

Step down the primary replica set member

Connect to the primary using a mongo shell and step down theprimary using the rs.stepDown() method.

  1. rs.stepDown()

Shut down the old primary

Once the primary steps down and the replica set elects a new primary,shut down the old primary mongod.

From a mongo shell connected to the old primary, issue thedb.shutdownServer() on the admin database.

  1. admin = db.getSiblingDB("admin")
  2. admin.shutdownServer()

Restart the old primary without transitionToAuth

Restart the mongod, this time without thesecurity.transitionToAuth option but with the internal authenticationmechanism such as security.keyFile.

Specify the following settings in your configuration file.

  1. security:
  2. keyFile: <path-to-keyfile>
  3. replication:
  4. replSetName: <replicaSetName>

Start the mongod using the configuration file:

  1. mongod --config <path-to-config-file>

For more information on the configuration file, seeconfiguration options.

You can also use the equivalent mongod options when starting yourmongod. See the mongod reference page for a complete list ofoptions.

Include additional settings as appropriate to your deployment.

At the end of this step, all members of the replica set should be up andrunning with authentication enforced. Clients can only connect to thesemongod instances by using the configured client authenticationmechanism.

x.509 Internal Authentication

For details on using x.509 for internal authentication, seeUse x.509 Certificate for Membership Authentication.

To upgrade from keyfile internal authentication to x.509 internalauthentication, seeUpgrade from Keyfile Authentication to x.509 Authentication.