在不停机的情况下在现有分片群集中实施身份验证

在本页面

Overview

Important

以下过程适用于使用 MongoDB 3.4 或更高版本的分片群集。

MongoDB 的早期版本不支持无停机升级。有关使用早期版本的 MongoDB 的分片群集,请参阅在分片群集中实施密钥文件访问控制

MongoDB 分片群集可以强制执行其组件的user authenticationinternal authentication,以防止未经授权的访问。

以下教程介绍了使用security.transitionToAuth转换现有分片群集以强制执行身份验证而不会造成停机的过程。

在尝试本教程之前,请熟悉本文档的内容。

Considerations

Cloud Manager 和 Ops Manager

如果您使用 Cloud Manager 或 Ops ManagerManagement 部署,请参考Cloud Manager 手册Ops Manager 手册中的为 MongoDB 部署配置访问控制以强制执行身份验证。

IP Binding

在版本 3.6 中更改。

从 MongoDB 3.6 开始,MongoDB 二进制文件mongodmongos默认绑定到localhost。从 MongoDB 版本 2.6 到 3.4,默认情况下,只有来自正式 MongoDB RPM(Red Hat,CentOS,Fedora Linux 和衍生产品)和 DEB(Debian,Ubuntu 和衍生产品)软件包的二进制文件会绑定到localhost。要了解有关此更改的更多信息,请参见Localhost 绑定兼容性更改

内部和 Client 端身份验证机制

本教程使用SCRAM进行 Client 端认证,使用keyfile进行内部认证配置认证。

有关可用的 Client 端和内部身份验证机制的完整列表,请参阅Authentication文档。

Architecture

本教程假定每个分片副本集以及配置服务器副本集在退出其现有主副本后都可以选择一个新的primary

只有同时满足以下两个条件,副本集才能选择主副本:

mongos 实例的最小数量

确保分片集群至少有两个可用的 mongos 实例。本教程要求重新启动集群中的每个mongos。如果分片群集只有一个mongos实例,则在mongos脱机期间将导致停机。

在现有分片群集上强制执行密钥文件访问控制

创建和分发密钥文件

通过keyfile身份验证,分片群集中的每个mongodmongos实例都将密钥文件的内容用作共享密码,以对部署中的其他成员进行身份验证。具有正确密钥文件的mongodmongos实例只能加入分片群集。

密钥文件的内容长度必须在 6 到 1024 个字符之间,并且对于分片群集的所有成员都必须相同。

Note

在 UNIX 系统上,密钥文件不得具有组或世界权限。在 Windows 系统上,不检查密钥文件权限。

您可以使用任何选择的方法来生成密钥文件。例如,以下操作使用openssl生成用于密钥文件的复杂伪随机 1024 字符串。然后,它使用chmod更改文件权限,以仅为文件所有者提供读取权限:

openssl rand -base64 755 > <path-to-keyfile>
chmod 400 <path-to-keyfile>

将密钥文件复制到托管分片集群成员的每个服务器。确保运行mongodmongos实例的用户是文件的所有者,并且可以访问密钥文件。

避免将密钥文件存储在易于与托管mongodmongos实例的硬件断开连接的存储介质上,例如 USB 驱动器或网络连接的存储设备。

有关使用密钥文件进行内部认证的更多信息,请参考Keyfiles

配置分片群集 Management 员用户和 Client 端用户

您必须连接到mongos才能完成本节中的步骤。在这些步骤中创建的用户是群集级用户,不能用于访问各个分片副本集。

创建 Management 员用户。

使用db.createUser()方法创建 Management 员用户并为其分配以下角色:

在分片群集上执行维护操作或用户 Management 操作的 Client 端必须在本教程完成时以该用户身份进行身份验证。立即创建此用户,以确保在执行身份验证后您可以访问集群。

admin = db.getSiblingDB("admin");
admin.createUser(
  {
    user: "admin",
    pwd: "<password>",
    roles: [
      { role: "clusterAdmin", db: "admin" },
      { role: "userAdmin", db: "admin" }
    ]
  }
);

Important

密码应随机,长且复杂,以防止或阻止恶意访问。

可选:为 Client 端应用程序创建其他用户。

除了 Management 员用户外,您还可以在强制执行身份验证之前创建其他用户。这可以确保在完全强制执行身份验证后访问分片群集。

Example

以下操作在marketing数据库上创建用户joe,并向该用户分配marketing数据库上的readWrite角色。

db.getSiblingDB("marketing").createUser(
{
"user": "joe",
"pwd": "<password>",
"roles": [ { "role" : "readWrite", "db" : "marketing" } ]
}
)

认证为"joe"的 Client 端可以在marketing数据库上执行读取和写入操作。

有关 MongoDB 提供的角色,请参见数据库用户角色

有关添加用户的更多信息,请参见Add Users教程。添加新用户时,请考虑安全最佳实践

可选:更新 Client 端应用程序以指定身份验证凭据。

尽管分片群集当前不强制执行身份验证,但是在连接到分片群集时,您仍然可以更新 Client 端应用程序以指定身份验证凭据。这可以防止在本教程完成时失去连接。

Example

以下操作使用mongo shell 连接到分片群集,并以marketing数据库上的用户joe身份进行身份验证。

mongo  --username "joe" --password "<password>" \
--authenticationDatabase "marketing" --host mongos1.example.net:27017

如果您的应用程序使用 MongoDB 驱动程序,请参阅相关的driver文档,以获取有关创建经过身份验证的连接的说明。

转换每个 mongos 实例以强制执行身份验证

创建一个新的 mongos 配置文件。

对于每个mongos

  • 复制现有的mongos配置文件,并为其指定一个不同的名称,例如<filename>-secure.conf(如果使用 Windows,则为.cfg)。您将使用此新的配置文件转换mongos以在分片群集中强制执行身份验证。保留原始配置文件以用于备份。

  • 在新的配置文件中,添加以下设置:

  • security.transitionToAuth设为true

  • security.keyFile设置为密钥文件路径。

如果使用其他内部认证机制,请指定适合该机制的设置。

security:
   transitionToAuth: true
   keyFile: <path-to-keyfile>

新的配置文件应包含mongos以前使用的所有配置设置以及新的安全设置。

一次,使用新的配置文件重新启动 mongos。

Note

如果您的群集只有一个mongos,则此步骤将导致mongos脱机时的停机时间。

请按照以下步骤重新启动mongos实例,一次一次mongos

db.getSiblingDB("admin").shutdownServer()
  • 使用新的配置文件重新启动mongos,并使用--config指定配置文件的路径。例如,如果新的配置文件名为mongos-secure.conf
mongos --config <path>/mongos-secure.conf

其中<path>代表包含新配置文件的文件夹的系统路径。

对下一个mongos实例重复重新启动过程,直到分片群集中的所有mongos实例都已重新启动。

在本节末尾,分片群集中的所有mongos实例都使用security.transitionToAuthsecurity.keyFile内部身份验证运行。

Transition Config Server 副本集成员强制执行身份验证

创建一个新的 mongod 配置文件。

对于配置服务器副本集中的每个mongod

  • 复制现有的mongod配置文件,并为其指定一个不同的名称,例如<filename>-secure.conf(如果使用 Windows,则为.cfg)。您将使用此新的配置文件转换mongod以在分片群集中强制执行身份验证。保留原始配置文件以用于备份。

  • 在新的配置文件中,添加以下设置:

  • security.transitionToAuth设为true

  • security.keyFile设置为密钥文件路径。

如果使用其他内部认证机制,请指定适合该机制的设置。

security:
   transitionToAuth: true
   keyFile: <path-to-keyfile>

一次,使用新的配置文件重新启动 mongod。

secondary成员开始,一次重新启动一个副本集。

db.getSiblingDB("admin").shutdownServer()
  • 用新的配置文件重新启动mongod,并使用--config指定配置文件的路径。例如,如果新的配置文件名为mongod-secure.conf
mongod --config <path>/mongod-secure.conf

其中<path>代表包含新配置文件的文件夹的系统路径。

此成员构建后,请为下一个secondary成员重复。

  • 全部 辅助成员重新启动并启动后,重新启动主要成员:

  • 连接到mongod

    • 使用rs.stepDown()方法可以降低主要级别并触发选举。
rs.stepDown()

您可以使用rs.status()方法来确保副本集选择了新的主数据库。

  • 降级主要数据库并选定新的主要数据库后,请对admin数据库使用db.shutdownServer()方法关闭旧的主要数据库。
db.getSiblingDB("admin").shutdownServer()
  • 用新的配置文件重新启动mongod,并使用--config指定配置文件的路径。例如,如果新的配置文件名为mongod-secure.conf
mongod --config <path>/mongod-secure.conf

其中<path>代表包含新配置文件的文件夹的系统路径。

在本节末尾,配置服务器副本集中的所有mongod实例都使用security.transitionToAuthsecurity.keyFile内部身份验证运行。

过渡每个分片副本集成员以强制执行身份验证

创建分片本地 Management 员

在实施身份验证的分片群集中,每个分片副本集应具有自己的shard-local administrator。您不能对一个分片使用分片本地 Management 员来访问另一个分片或分片的集群。

连接到每个分片副本集的primary成员,并使用db.createUser()方法创建用户,并为其分配以下角色:

admin = db.getSiblingDB("admin")
admin.createUser(
  {
    user: "admin",
    pwd: "<password>",
    roles: [
      { role: "clusterAdmin", db: "admin" },
      { role: "userAdmin", db: "admin" }
    ]
  }
)

在完成本教程后,如果要连接到分片以执行需要直接连接到分片的维护操作,则必须以本地分片 Management 员身份进行身份验证。

Note

与分片的直接连接仅应用于分片特定的维护和配置。通常,Client 端应通过mongos连接到分片群集。

Procedure

一次转换一个分片副本集,对分片群集中的每个分片副本集重复这些步骤。

创建一个新的 mongod 配置文件。

对于分片副本集中的每个mongod

  • 复制现有的mongod配置文件,并为其指定一个不同的名称,例如<filename>-secure.conf(如果使用 Windows,则为.cfg)。您将使用此新的配置文件转换mongod以在分片群集中强制执行身份验证。保留原始配置文件以用于备份。

  • 在新的配置文件中,添加以下设置:

  • security.transitionToAuth设为true

  • security.keyFile设置为密钥文件路径。

如果使用其他内部认证机制,请指定适合该机制的设置。

security:
   transitionToAuth: true
   keyFile: <path-to-keyfile>
一次,使用新的配置文件重新启动 mongod。

secondary成员开始,一次重新启动一个副本集。

db.getSiblingDB("admin").shutdownServer()
  • 用新的配置文件重新启动mongod,并使用--config指定配置文件的路径。例如,如果新的配置文件名为mongod-secure.conf
mongod --config <path>/mongod-secure.conf

其中<path>代表包含新配置文件的文件夹的系统路径。

一旦此成员启动,请对副本集的下一个secondary成员重复,直到所有辅助副本都已更新。

  • 全部 辅助成员重新启动并启动后,重新启动主要成员:

  • 连接到mongod

    • 使用rs.stepDown()方法可以降低主要级别并触发选举。
rs.stepDown()

您可以使用rs.status()方法来确保副本集选择了新的主数据库。

  • 降级主要数据库并选定新的主要数据库后,请对admin数据库使用db.shutdownServer()方法关闭旧的主要数据库。
db.getSiblingDB("admin").shutdownServer()
  • 用新的配置文件重新启动mongod,并使用--config指定配置文件的路径。例如,如果新的配置文件名为mongod-secure.conf
mongod --config <path>/mongod-secure.conf

其中<path>代表包含新配置文件的文件夹的系统路径。

在本教程的这一点上,分片群集的每个组件都使用--transitionToAuthsecurity.keyFile内部身份验证运行。分片群集至少有一个 Management 用户,并且每个分片副本集都有一个分片本地 Management 用户。

其余部分涉及将分片群集从过渡状态中移出以完全实施身份验证。

重新启动每个 mongos 实例,而不进行 transitionToAuth

Important

在本节末尾,Client 端必须指定身份验证凭据才能连接到分片群集。在完成本节之前,请在更新 Client 端之前指定身份验证凭据,以避免失去连接。

要完成到分片群集中完全强制身份验证的过渡,必须重新启动每个mongos实例,而无需设置security.transitionToAuth

从 mongos 配置文件中删除 transitionToAuth。

从本教程创建的mongos配置文件中删除security.transitionToAuth键及其值。保留本教程中添加的security.keyFile设置。

security:
   keyFile: <path-to-keyfile>

使用更新的配置文件重新启动 mongos。

Note

如果您的群集只有一个mongos,则此步骤将导致mongos脱机时的停机时间。

按照以下步骤重新启动mongos实例,一次mongos

db.getSiblingDB("admin").shutdownServer()
  • 使用更新的配置文件重新启动mongos,并使用--config指定配置文件的路径。例如,如果更新后的配置文件名为mongos-secure.conf
mongos --config <path>/mongos-secure.conf

在本节末尾,所有mongos实例都强制执行 Client 端身份验证和security.keyFile内部身份验证。

重新启动每个 Config Server 副本集成员,而无需 transitionToAuth

Important

在此步骤结束时,Client 端必须指定身份验证凭据才能连接到配置服务器副本集。在完成本节之前,请在更新 Client 端之前指定身份验证凭据,以避免失去连接。

要完成到分片群集中完全强制身份验证的过渡,必须重新启动每个mongod实例,而无需设置security.transitionToAuth

从 mongod 配置文件中删除 transitionToAuth。

从本教程创建的配置服务器配置文件中删除security.transitionToAuth键及其值。保留本教程中添加的security.keyFile设置。

security:
   keyFile: <path-to-keyfile>

一次,使用更新的配置文件重新启动 mongod。

secondary成员开始,一次重新启动一个副本集。

db.getSiblingDB("admin").shutdownServer()
  • 用更新的配置文件重新启动mongod,并使用--config指定配置文件的路径。例如,如果新的配置文件名为mongod-secure.conf
mongod --config <path>/mongod-secure.conf

其中<path>代表包含更新的配置文件的文件夹的系统路径。

此成员构建后,请为下一个secondary成员重复。

  • 全部 辅助成员重新启动并启动后,重新启动主要成员:

  • 连接到mongod

    • 使用rs.stepDown()方法可以降低主要级别并触发选举。
rs.stepDown()

您可以使用rs.status()方法来确保副本集选择了新的主数据库。

  • 降级主要数据库并选定新的主要数据库后,请对admin数据库使用db.shutdownServer()方法关闭旧的主要数据库。
db.getSiblingDB("admin").shutdownServer()
  • 用更新的配置文件重新启动mongod,并使用--config指定配置文件的路径。例如,如果新的配置文件名为mongod-secure.conf
mongod --config <path>/mongod-secure.conf

其中<path>代表包含更新的配置文件的文件夹的系统路径。

在本节末尾,配置服务器副本集中的所有mongod实例都将强制执行 Client 端身份验证和security.keyFile内部身份验证。

重新启动每个分片副本集中的每个成员,而无需 transitionToAuth

Important

在此步骤结束时,Client 端必须指定身份验证凭据才能连接到分片副本集。在完成本节之前,请在更新 Client 端之前指定身份验证凭据,以避免失去连接。

要完成到分片群集中完全强制身份验证的过渡,必须重新启动分片群集中每个分片副本集的每个成员,而无需设置security.transitionToAuth

一次转换一个分片副本集,对分片群集中的每个分片副本集重复这些步骤。

从 mongod 配置文件中删除 transitionToAuth。

从本教程创建的配置服务器配置文件中删除security.transitionToAuth键及其值。保留本教程中添加的security.keyFile设置。

security:
   keyFile: <path-to-keyfile>

一次,使用更新的配置文件重新启动 mongod。

secondary成员开始,一次重新启动一个副本集。

db.getSiblingDB("admin").shutdownServer()
  • 用更新的配置文件重新启动mongod,并使用--config指定配置文件的路径。例如,如果新的配置文件名为mongod-secure.conf
mongod --config <path>/mongod-secure.conf

其中<path>代表包含更新的配置文件的文件夹的系统路径。

此成员构建后,请为下一个secondary成员重复。

  • 全部 辅助成员重新启动并启动后,重新启动主要成员:

  • 连接到mongod

    • 使用rs.stepDown()方法可以降低主要级别并触发选举。
rs.stepDown()

您可以使用rs.status()方法来确保副本集选择了新的主数据库。

  • 降级主要数据库并选定新的主要数据库后,请对admin数据库使用db.shutdownServer()方法关闭旧的主要数据库。
db.getSiblingDB("admin").shutdownServer()
  • 用更新的配置文件重新启动mongod,并使用--config指定配置文件的路径。例如,如果新的配置文件名为mongod-secure.conf
mongod --config <path>/mongod-secure.conf

其中<path>代表包含更新的配置文件的文件夹的系统路径。

在本节的最后,分片群集中的所有mongosmongod实例都强制执行 Client 端身份验证和security.keyFile内部身份验证。Client 端只能使用配置的 Client 端身份验证机制连接到分片群集。其他组件只能通过指定正确的密钥文件来加入集群。

x.509 证书内部身份验证

MongoDB 支持用于安全 TLS/SSL 连接的 x.509 证书身份验证。分片的群集成员和副本集成员可以使用 x.509 证书来验证其对群集或副本集的成员身份,而不是使用Keyfiles

有关使用 x.509 证书进行内部身份验证的详细信息,请参阅使用 x.509 证书进行会员身份验证

从密钥文件身份验证升级到 x.509 身份验证描述了如何将部署的内部身份验证机制从基于密钥文件的身份验证升级到基于 x.509 证书的身份验证。