Docs 菜单

Docs 主页开发应用程序MongoDB Manual

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

在此页面上

  • 概述
  • 考虑因素
  • 使用密钥文件访问控制来部署分片集群
  • 后续步骤
  • x.509 内部身份验证

分片集群上实施访问控制需要配置以下内容:

  • 使用内部身份验证确保集群各组件之间的安全。

  • 使用用户访问控制配置连接客户端和集群之间的安全性。

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

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

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

如果使用 Cloud Manager 或 Ops Manager 管理部署,请参阅相应的Cloud Manager 手册Ops Manager 手册以强制执行身份验证。

重要

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

使用主机名而不是 IP 地址在分割网络范围内配置集群。从 MongoDB 5开始。 0 ,仅配置了 IP 地址的节点未通过启动验证,因此不会启动。

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

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

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

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

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

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

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

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

本教程要求创建分片集群用户,但包括添加分片本地用户的可选步骤。

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

本教程使用 mongodmongos 程序。Windows 用户应改用 mongod.exemongos.exe 程序。

以下过程涉及如何创建一个新的分片集群,此集群由 mongos、配置服务器和两个分片组成。

重要

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

使用主机名而不是 IP 地址在分割网络范围内配置集群。从 MongoDB 5开始。 0 ,仅配置了 IP 地址的节点未通过启动验证,因此不会启动。

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

注意

从 MongoDB 4.2 开始,用于内部成员身份验证的密钥文件使用 YAML 格式,允许密钥文件中有多个密钥。YAML 格式接受:

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

  • 键字符串序列

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

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

注意

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

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

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

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

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

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

以下步骤部署配置服务器副本集。

请在生产部署中部署至少包含三个节点的配置服务器副本集。可创建单节点副本集进行测试。

1

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

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

配置文件

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

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

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

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

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

命令行

如果使用命令行参数,请使用 --keyFile--configsvr--replSet 参数启动 mongod

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

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

2

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

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

3

rs.initiate() 方法启动副本集,可以获取可选的副本集配置文档。 在副本集配置文档中,包括:

  • _id_id 必须 与传递给 mongod--replSet 参数匹配。

  • members字段。 members 字段是一个数组,每个副本集的成员都需要一个文档。

  • configsvr字段。 配置服务器副本集的 configsvr 字段必须设置为 true

有关副本集配置文档的更多信息,请参阅副本集配置

使用 rs.initiate() 方法和配置文档启动副本集:

rs.initiate(
{
_id: "myReplSet",
configsvr: true,
members: [
{ _id : 0, host : "cfg1.example.net:27019" },
{ _id : 1, host : "cfg2.example.net:27019" },
{ _id : 2, host : "cfg3.example.net:27019" }
]
}
)

注意

要在此过程中使用配置服务器副本集 (CSRS),必须首先等待其完成初始化。 如果 CSRS 尚未初始化,则会导致NotYetInitialized错误。

配置服务器副本集 (CSRS) 启动并运行后,继续创建分片副本集。

对于生产部署,请使用至少包含三个成员的副本集。出于测试目的,可创建单成员副本集。

这些步骤包括添加分片本地用户的可选过程。现在执行这些步骤可确保每个分片都有用户可以执行分片级别的维护。

1

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

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

配置文件

如果使用配置文件,请将 security.keyFile 选项设置为密钥文件的路径,将 replication.replSetName 选项设置为副本集的所需名称,将 sharding.clusterRole 选项设置为 shardsvr

security:
keyFile: <path-to-keyfile>
sharding:
clusterRole: shardsvr
replication:
replSetName: <replSetName>
storage:
dbPath: <path>

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

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

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

命令行

如果使用命令行选项,在启动组件时,请指定 --keyFilereplSet--shardsvr 参数,如以下示例所示:

mongod --keyFile <path-to-keyfile> --shardsvr --replSet <replSetName> --dbpath <path>

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

2

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

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

3

mongosh运行rs.initiate()方法。

rs.initiate() 可以接受一个可选的副本集配置文档。在复制集配置文档中,包括:

以下示例会启动一个三节点副本集。

rs.initiate(
{
_id : "myReplSet",
members: [
{ _id : 0, host : "s1-mongo1.example.net:27018" },
{ _id : 1, host : "s1-mongo2.example.net:27018" },
{ _id : 2, host : "s1-mongo3.example.net:27018" }
]
}
)

rs.initiate() 触发选举,并选出一名节点担任主节点

在继续之前连接到主节点。使用 rs.status() 查找主节点。

4

重要

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

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

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

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

您必须连接到主节点才能创建用户。

以下示例在 admin 数据库上创建具有 userAdminAnyDatabase 角色的用户 fred

重要

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

提示

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

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

根据提示输入密码。有关内置角色和与数据库管理操作相关的角色的完整列表,请参阅数据库用户角色

5

admin 数据库进行身份验证。

mongosh中,使用db.auth()进行身份验证。例如,以下身份验证为用户管理员fred

提示

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

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

或者,使用-u <username>-p <password>--authenticationDatabase参数将新的mongosh实例连接到主副本集成员。

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

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

6

分片本地集群管理员用户具有 clusterAdmin 角色,可提供允许访问复制操作的权限。

有关与副本集操作相关的角色的完整列表,请参阅集群管理角色

admin 数据库中创建集群管理员用户并分配 clusterAdmin 角色:

提示

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

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

根据提示输入密码。

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

1

使用配置文件或命令行参数启动 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>

命令行

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

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

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

2

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

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

3

重要

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

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

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

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

重要

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

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

提示

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

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

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

4

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

提示

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

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

根据提示输入密码。

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

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

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

5

集群管理员用户具有 clusterAdmin 角色,该角色可授予对复制和分片操作的访问权限。

admin 数据库中创建 clusterAdmin 用户。

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

重要

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

提示

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

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

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

6

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

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

要继续,您必须连接到 mongos,并以分片集群的集群管理员用户身份进行身份验证。

注意

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

若要将每个分片添加到集群,请使用 sh.addShard() 方法。如果分片是副本集,请指定副本集的名称,然后指定该副本集的节点。在生产部署中,所有分片都应是副本集。

以下操作将单个分片副本集添加到该集群中:

sh.addShard( "<replSetName>/s1-mongo1.example.net:27017")

以下操作是在集群中添加独立 mongod 分片的示例:

sh.addShard( "s1-mongo1.example.net:27017")

重复这些步骤,直到集群包含所有分片。此时,分片集群对集群以及每个分片集群组件之间的内部通信实施访问控制。

要继续,您必须连接到 mongos,并以分片集群的集群管理员用户身份进行身份验证。

注意

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

在数据库上启用分片后,就可以对数据库中的collection进行分片。使用sh.enableSharding()方法在目标数据库上启用分片。

sh.enableSharding("<database>")

要继续,您必须连接到 mongos,并以分片集群的集群管理员用户身份进行身份验证。

注意

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

要对集合进行分片,请使用sh.shardCollection()方法。您必须指定集合的完整命名空间和包含分片键的文档。

您选择的分片键会影响分片效率,以及您利用某些分片功能(例如区域)的能力。请参阅选择分片键中列出的选择注意事项。

如果集合已包含数据,则必须先使用 db.collection.createIndex() 方法在分片键上创建索引,然后再使用 shardCollection()

如果集合为空,MongoDB 会将索引创建为sh.shardCollection()的一部分。

以下是 sh.shardCollection() 方法的示例:

sh.shardCollection("<database>.<collection>", { <key> : <direction> } )

创建用户以允许客户端连接到分片集群,并与之交互。

有关用于创建只读和读写用户的基本内置角色,请参阅数据库用户角色

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

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

提示

另请参阅:

← 将副本集更新为密钥文件身份验证(无停机时间)