“文档” 菜单
文档首页
/
MongoDB Manual
/ / /

将分片集群更新为密钥文件身份验证

在此页面上

  • 概述
  • 注意事项
  • 步骤
  • x.509 内部身份验证

分片集群上执行访问控制需要配置:

对于本教程,分片集群的每个节点必须 使用相同的内部身份验证机制和设置。这意味着,在集群中的每个 mongosmongod 上实施内部身份验证。

以下教程使用密钥文件启用内部身份验证。

实施内部身份验证还可实施用户访问控制。 要连接到副本集, mongosh等客户端需要使用用户帐户。 请参阅访问控制。

如果 Cloud Manager 或 Ops Manager 正在管理您的部署,则会自动执行身份验证。

要在托管部署上配置访问控制,请参阅: Cloud Manager手册MongoDB Ops Manager手册中的 Configure Access Control for MongoDB Deployments

重要

要避免因 IP 地址变更而更新配置,请使用 DNS 主机名而非 IP 地址。在配置副本集成员或分片集群成员时,使用 DNS 主机名而非 IP 地址尤为重要。

在水平分割网络配置下,请使用主机名而非 IP 地址来配置集群。从 MongoDB 5.0 开始,仅配置了 IP 地址的节点将无法通过启动验证,因而不会启动。

默认情况下,MongoDB 二进制文件 mongodmongos 绑定到 localhost

本教程主要介绍 mongod 流程。Windows 用户应改用 mongod.exe 程序。

密钥文件是最低限度的安全手段,也最适合测试或开发环境。对于生产环境,建议使用 x.509 证书

本教程介绍在 admin 数据库上创建最少数量的管理用户。在用户身份验证方面,本教程使用默认的 SCRAM 身份验证机制。质询响应安全机制最适合测试或开发环境。对于生产环境,建议使用 x.509 证书LDAP 代理身份验证(仅用于 MongoDB Enterprise)或 Kerberos 身份验证(仅用于 MongoDB Enterprise)。

如需详细了解为特定认证机制创建用户,请参阅特定认证机制页面。

请参阅➤ 配置基于角色的访问控制,了解用户创建和管理的最佳实践。

通常,要为分片集群创建用户,请连接到 mongos 并添加分片集群用户。

不过,某些维护操作要求直接连接到分片集群中的特定分片。要执行这些操作,您必须直接连接到分片,并以分片本地管理用户身份进行身份验证。

分片本地用户仅存在于特定分片中,并且只能用于特定于分片的维护和配置。您无法通过分片本地用户连接到 mongos

有关更多信息,请参阅用户安全文档。

升级分片集群以实施访问控制需要停机。

1

在使用密钥文件身份验证时,分片集群中的每个 mongodmongos 实例将密钥文件内容作为共享密码,以对部署中的其他节点进行身份验证。仅具有正确密钥文件的 mongodmongos 实例可以加入分片集群。

注意

用于内部成员身份验证的密钥文件使用 YAML 格式,允许在密钥文件中包含多个密钥。YAML 格式接受以下任一形式:

  • 单个密钥字符串(与早期版本相同)

  • 键字符串序列

YAML 格式与使用文本文件格式的现有单密钥文件兼容。

密钥长度必须在 6 到 1,024 个字符之间,并且只能包含 base64 集合中的字符。分片集群的所有节点必须共享至少一个通用的密钥。

注意

在 UNIX 系统上,密钥文件不得具有群组或全局权限。在 Windows 系统中,不检查密钥文件权限。

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

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

有关使用密钥文件的更多详细信息和要求,请参阅密钥文件。

2

托管分片集群的mongodmongos组件的每台服务器都必须包含密钥文件的副本。

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

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

3

mongosh连接到mongos

sh.stopBalancer()

如果正在进行迁移,负载均衡器可能不会立即停止。 sh.stopBalancer()方法会阻止 Shell,直到负载均衡器停止。

从 MongoDB 6.0.3 开始,不再执行自动数据块分割。这是因为均衡策略的改进。自动分割命令仍然存在,但不执行操作。

在 6.0.3 之前的 MongoDB 版本中,sh.stopBalancer() 还会禁用分片集群的自动拆分。

使用sh.getBalancerState()验证负载均衡器是否已停止。

sh.getBalancerState()

重要

在负载均衡器停止运行之前,请勿继续。

有关配置托管集群负载均衡器行为的教程,请参阅托管集群负载均衡器

4

mongosh连接到每个mongos并将其关闭。

admin数据库上使用db.shutdownServer()方法安全关闭mongos

db.getSiblingDB("admin").shutdownServer()

重复此操作,直到集群中的所有mongos实例都离线。

完成此步骤后,集群中的所有mongos实例都应处于离线状态。

5

mongosh连接到配置服务器部署中的每个mongod ,然后将其关闭。

对于副本集配置服务器部署,最后关闭主节点成员。

admin数据库上使用db.shutdownServer()方法安全关闭mongod

db.getSiblingDB("admin").shutdownServer()

重复此操作,直到所有配置服务器都离线。

6

对于每个分片副本集,将mongosh连接到副本集中的每个mongod成员并将其关闭。 最后关闭节点。

admin数据库上使用db.shutdownServer()方法安全关闭mongod

db.getSiblingDB("admin").shutdownServer()

对每个分片副本集重复此步骤,直到所有分片副本集中的所有mongod实例都离线。

完成此步骤后,整个分片集群应处于离线状态。

7

启动配置服务器副本集中的每个 mongod。包括 keyFile 设置。通过 keyFile 设置可以执行内部/节点身份验证基于角色的访问控制

您可以通过配置文件或命令行指定 mongod 设置。

配置文件

如果使用配置文件,对于配置服务器副本集,请将security.keyFile设置为密钥文件的路径,将sharding.clusterRole设置为configsvr ,并将replication.replSetName设置为配置服务器副本集的名称。

security:
keyFile: <path-to-keyfile>
sharding:
clusterRole: configsvr
replication:
replSetName: <setname>
storage:
dbpath: <path>

根据配置要求包括其他选项。例如,如果您希望远程客户端连接到部署,或者部署节点运行在不同的主机上,请指定 net.bindIp 设置。

启动 mongod,同时指定 --config 选项和配置文件的路径。

mongod --config <path-to-config>

命令行

如果使用命令行参数,对于配置服务器副本集,请使用-keyFile--configsvr--replSet参数启动mongod

mongod --keyFile <path-to-keyfile> --configsvr --replSet <setname> --dbpath <path>

根据配置要求包括其他选项。例如,如果希望远程客户端连接到您的部署,或是您的部署成员运行在不同主机上,请指定 --bind_ip

有关命令行选项的更多信息,请参阅mongod参考页面。

确保在重新启动每个成员时使用原始副本集设置名称。您无法更改副本集的名称。

8

运行带有 keyFile 参数的 mongod 会强制执行内部/成员身份验证角色访问控制

使用配置文件或命令行启动副本集中的每个 mongod

配置文件

如果使用配置文件,请将security.keyFile选项设置为密钥文件的路径,并将replication.replSetName选项设置为副本集的原始名称。

security:
keyFile: <path-to-keyfile>
replication:
replSetName: <setname>
storage:
dbPath: <path>

根据配置要求包括其他选项。例如,如果您希望远程客户端连接到部署,或者部署节点运行在不同的主机上,请指定 net.bindIp 设置。

启动 mongod,同时指定 --config 选项和配置文件的路径。

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

命令行

如果使用命令行参数,请启动mongod并指定--keyFile--replSet参数。

mongod --keyfile <path-to-keyfile> --replSet <setname> --dbpath <path>

根据配置要求包括其他选项。例如,如果希望远程客户端连接到您的部署,或是您的部署成员运行在不同主机上,请指定 --bind_ip

有关初创企业参数的更多信息,请参阅 mongod 参考页面。

确保在重新启动每个成员时使用原始副本集设置名称。您无法更改副本集的名称。

重复此步骤,直到集群中的所有分片都在线。

9

重要

本地主机异常允许通过本地主机接口连接的客户端在执行访问控制的mongod上创建用户。 创建第一个用户后,本地主机异常将关闭。

第一个用户必须拥有创建其他用户的特权,如具备 userAdminAnyDatabase 的用户。这样可以确保在本地主机异常关闭后,您可以创建更多用户。

如果至少一个用户没有创建用户的权限,一旦本地主机异常关闭,您可能无法创建或修改具有新权限的用户,因此无法访问某些功能或操作。

对于集群中的每个分片副本集,通过 本地主机接口mongosh 将 连接到 节点。您必须在与目标 相同的计算机上运行mongosh mongod,才能使用本地主机接口。

admin数据库上创建具有userAdminAnyDatabase角色的用户。 该用户可以根据需要为分片副本集创建其他用户。 创建此用户还会关闭本地主机异常。

以下示例在admin数据库上创建分片本地用户fred

重要

密码应随机、长且复杂,以确保系统安全并防止或延迟恶意访问。

提示

您可以将 passwordPrompt() 方法与各种用户身份验证/管理方法/命令结合使用,以提示输入密码,而不是直接在方法/命令调用中指定密码。不过,您仍然可以像使用早期版本的 mongo shell 一样直接指定密码。

admin = db.getSiblingDB("admin")
admin.createUser(
{
user: "fred",
pwd: passwordPrompt(), // or cleartext password
roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
}
)
10

运行带有 keyFile 参数的 mongod 会强制执行内部/成员身份验证角色访问控制

使用配置文件或命令行启动副本集中的每个 mongos

配置文件

如果使用文件,请将security.keyFile设置为密钥文件的路径,将sharding.configDB设置为副本集名称,并采用<replSetName>/<host:port>格式设置至少一个副本集节点。

security:
keyFile: <path-to-keyfile>
sharding:
configDB: <configReplSetName>/cfg1.example.net:27019,cfg2.example.net:27019,...

根据配置要求包括其他选项。例如,如果您希望远程客户端连接到部署,或者部署节点运行在不同的主机上,请指定 net.bindIp 设置。

启动 mongos,同时指定 --config 选项和配置文件的路径。

mongos --config <path-to-config-file>

命令行

如果使用命令行参数,则启动 mongos,并指定 --keyFile--configdb 参数。

mongos --keyFile <path-to-keyfile> --configdb <configReplSetName>/cfg1.example.net:27019,cfg2.example.net:27019,...

根据配置要求包括其他选项。例如,如果希望远程客户端连接到您的部署,或是您的部署成员运行在不同主机上,请指定 --bind_ip

此时,整个分片集群已重新联机,并且可以使用指定的密钥文件进行内部通信。 但是, mongosh等外部程序需要使用正确配置的用户才能读取或写入集群。

11

通过本地主机接口mongosh 连接到一个 mongos 实例。您必须在与 mongos 实例相同的物理机器上运行 mongosh

只有当尚未为部署创建任何用户,本地主机接口才可用。本地主机接口会在创建第一个用户后关闭。

12

重要

创建第一个用户后,本地主机异常就不再可用。

第一个用户必须拥有创建其他用户的特权,如具备 userAdminAnyDatabase 的用户。这样可以确保在本地主机异常关闭后,您可以创建更多用户。

如果至少一个用户没有创建用户的权限,则一旦 Localhost Exception 关闭,您将无法创建或修改用户,因此可能无法执行必要的操作。

使用 db.createUser() 方法添加用户。该用户应在 admin 数据库中至少拥有 userAdminAnyDatabase 角色。

重要

密码应随机、长且复杂,以确保系统安全并防止或延迟恶意访问。

以下示例在 admin 数据库上创建 fred 用户:

提示

您可以将 passwordPrompt() 方法与各种用户身份验证/管理方法/命令结合使用,以提示输入密码,而不是直接在方法/命令调用中指定密码。不过,您仍然可以像使用早期版本的 mongo shell 一样直接指定密码。

admin = db.getSiblingDB("admin")
admin.createUser(
{
user: "fred",
pwd: passwordPrompt(), // or cleartext password
roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
}
)

有关内置角色和与数据库管理操作相关的角色的完整列表,请参阅数据库用户角色

13

使用 db.auth() 以用户管理员身份进行身份验证,才能创建其他用户:

提示

您可以将 passwordPrompt() 方法与各种用户身份验证/管理方法/命令结合使用,以提示输入密码,而不是直接在方法/命令调用中指定密码。不过,您仍然可以像使用早期版本的 mongo shell 一样直接指定密码。

db.getSiblingDB("admin").auth("fred", passwordPrompt()) // or cleartext password

根据提示输入密码。

或者使用 -u <username>-p <password>--authenticationDatabase "admin" 参数,将新的 mongosh 会话连接到目标副本集节点。您必须使用 Localhost Exception 连接到 mongos

mongosh -u "fred" -p --authenticationDatabase "admin"

如果您没有为 -p 命令行选项指定密码,mongosh 会提示输入密码。

14

集群管理员用户具有分片集群的clusterAdmin角色,而不是分片本地集群管理员。

以下示例在admin数据库上创建用户ravi

重要

密码应随机、长且复杂,以确保系统安全并防止或延迟恶意访问。

提示

您可以将 passwordPrompt() 方法与各种用户身份验证/管理方法/命令结合使用,以提示输入密码,而不是直接在方法/命令调用中指定密码。不过,您仍然可以像使用早期版本的 mongo shell 一样直接指定密码。

db.getSiblingDB("admin").createUser(
{
"user" : "ravi",
"pwd" : passwordPrompt(), // or cleartext password
roles: [ { "role" : "clusterAdmin", "db" : "admin" } ]
}
)

请参阅集群管理角色,获取与副本集和分片集群操作相关的内置角色的完整清单。

15

要执行分片操作,请使用clusterAdmin db.auth()方法或带有mongosh username、 和 参数的新password 会话以authenticationDatabase 用户身份进行身份验证。

注意

这是分片集群的集群管理员,而不是 分片本地集群管理员。

16

启动负载均衡器。

sh.startBalancer()

从 MongoDB 6.0.3 开始,不再执行自动数据块分割。这是因为均衡策略的改进。自动分割命令仍然存在,但不执行操作。

在 6.0.3 之前的 MongoDB 版本中,sh.startBalancer() 还支持分片集群的自动拆分。

使用sh.getBalancerState()验证负载均衡器已启动。

有关分片集群负载均衡器的教程,请参阅管理分片集群负载均衡器。

17

创建用户,以允许客户端连接并访问分片集群。有关可用的内置角色,例如 readreadWrite ,请参阅数据库用户角色。您可能还需要其他管理用户。有关用户的更多信息,请参阅用户

要创建其他用户,必须以具有 userAdminAnyDatabaseuserAdmin 角色的用户身份进行身份验证。

有关使用 x.509 进行内部身份验证的详情,请参阅使用 x.509 证书进行成员身份验证

要将密钥文件内部身份验证升级到 x.509 内部身份验证,请参阅从密钥文件身份验证升级到 x.509 身份验证

← 使用密钥文件身份验证部署分片集群