Overview
MongoDB 分片集群可以强制执行用户身份验证及其组件的内部身份验证,以防止未经授权的访问。
以下教程介绍了使用security.transitionToAuth将现有分片集群转换为强制身份验证而不会导致停机的过程。
在尝试本教程之前,请先熟悉本文档的内容。
Considerations
Cloud Manager 或 Ops Manager
If you are using Cloud Manager or Ops Manager to manage your deployment, refer to Configure Access Control for MongoDB Deployments in the Cloud Manager manual or Ops Manager manual to enforce authentication.
IP 绑定
内部和客户端身份验证机制
本教程使用SCRAM配置身份验证进行客户端身份验证,使用密钥文件进行内部身份验证。
有关可用客户端和内部身份验证机制的完整列表,请参阅自管理部署上的身份验证文档。
架构
本教程假设每个分片副本集以及配置服务器副本集都可以在降级其现有主节点后选择新的主节点。
仅当以下两个条件为 true 时,副本集才能选举主节点:
mongos实例的最小数量
确保您的分片集群有至少两个可用的 mongos 实例。 本教程需要重新启动集群中的每个mongos 。 如果您的分片集群只有一个mongos实例,则会在mongos离线期间导致停机。
在现有分片集群上实施密钥文件访问控制
创建和分发密钥文件
在使用密钥文件身份验证时,分片集群中的每个 mongod 或 mongos 实例将密钥文件内容作为共享密码,以对部署中的其他节点进行身份验证。仅具有正确密钥文件的 mongod 或 mongos 实例可以加入分片集群。
注意
用于内部成员身份验证的密钥文件使用 YAML 格式,允许在密钥文件中包含多个密钥。YAML 格式接受以下任一形式:
单个密钥字符串(与早期版本相同)
键字符串序列
YAML 格式与使用文本文件格式的现有单密钥文件兼容。
密钥长度必须在 6 到 1,024 个字符之间,并且只能包含 base64 集合中的字符。分片集群的所有节点必须共享至少一个通用的密钥。
注意
在 UNIX 系统上,密钥文件不得具有群组或全局权限。在 Windows 系统中,不检查密钥文件权限。
您可以选择任何方法生成密钥文件。例如,以下操作使用 openssl 生成复杂的伪随机 1024 字符串以用作共享密码。然后,它使用 chmod 更改文件权限,仅为文件所有者提供读取权限:
openssl rand -base64 755 > <path-to-keyfile> chmod 400 <path-to-keyfile>
将密钥文件复制到每台托管分片集群成员的服务器上。确保运行 mongod 或 mongos 实例的用户是文件的所有者并且可以访问密钥文件。
避免将密钥文件存储在可以轻松与托管 mongod 或 mongos 实例的硬件断开连接的存储介质上,例如 USB 驱动器或联网存储设备。
有关使用密钥文件进行内部身份验证的更多信息,请参阅密钥文件。
配置分片集群管理员用户和客户端用户
您必须连接到mongos才能完成本节中的步骤。 在这些步骤中创建的用户是集群级别用户,不能用于访问单个分片副本集。
创建管理员用户。
使用db.createUser()方法创建管理员用户并为其分配以下角色:
clusterAdminadmin数据库上的数据库上的
userAdmin角色admin
在完成本教程后,对分片集群执行维护操作或用户管理操作的客户端必须以此用户身份进行身份验证。 立即创建此用户,确保您在实施身份验证后可以访问集群。
admin = db.getSiblingDB("admin"); admin.createUser( { user: "admin", pwd: "<password>", roles: [ { role: "clusterAdmin", db: "admin" }, { role: "userAdmin", db: "admin" } ] } );
重要
密码应随机、长且复杂,以防止或阻止恶意访问。
可选:为客户端应用程序创建其他用户。
除管理员用户外,您还可以在执行身份验证之前创建其他用户。 这样可以确保在您完全实施身份验证后可以访问分片集群。
例子
以下操作在marketing数据库上创建用户joe ,并为该用户分配marketing数据库上的readWrite角色。
db.getSiblingDB("marketing").createUser( { "user": "joe", "pwd": "<password>", "roles": [ { "role" : "readWrite", "db" : "marketing" } ] } )
身份验证为"joe"的客户端可以对marketing数据库执行读取和写入操作。
有关 MongoDB 提供的角色,请参阅数据库用户角色。
可选:更新客户端应用程序以指定身份验证档案。
虽然分片集群当前不强制执行身份验证,但您仍可更新客户端应用程序,以在连接到分片集群时指定身份验证档案。 这可以防止在完成本教程时失去连接。
例子
The following operation connects to the sharded cluster using mongosh, authenticating as the user joe on the marketing database.
mongosh --username "joe" --password "<password>" \ --authenticationDatabase "marketing" --host mongos1.example.net:27017
If your application uses a MongoDB driver, see the associated driver documentation for instructions on creating an authenticated connection.
转换每个mongos 实例以强制执行身份验证
创建新的mongos 配置文件。
对于每个mongos :
在新配置文件中,添加以下设置:
security.transitionToAuth设置为truesecurity.keyFile设置为密钥文件路径。如果使用不同的内部身份验证机制,请指定适合该机制的设置。
security: transitionToAuth: true keyFile: <path-to-keyfile> 新的配置文件应包含
mongos之前使用的所有配置设置以及新的安全设置。
mongos使用新的配置文件,一次重启一个 。
按照以下步骤重新启动mongos实例,一次启动一个mongos :
连接到
mongos以关闭。对
admin数据库使用db.shutdownServer()方法,安全关闭mongos。db.getSiblingDB("admin").shutdownServer()
在本部分结束时,分片集群中的所有mongos实例都使用security.transitionToAuth和security.keyFile内部身份验证来运行。
过渡配置服务器副本集成员以强制执行身份验证
创建新的mongod 配置文件。
对于配置服务器副本集中的每个mongod ,
在新配置文件中,添加以下设置:
security.transitionToAuth设置为truesecurity.keyFile设置为密钥文件路径。如果使用不同的内部身份验证机制,请指定适合该机制的设置。
security: transitionToAuth: true keyFile: <path-to-keyfile>
mongod使用新的配置文件,一次重启一个 。
从副本集开始,一次重启一个副本集。
所有从节点重新启动并启动后,重新启动主节点:
连接到
mongod。一旦您降级主节点并选举了新的主节点,请对
admin数据库使用db.shutdownServer()方法关闭旧的主节点。db.getSiblingDB("admin").shutdownServer()
在本部分结束时,所有mongod在副本集的配置服务器中都使用security.transitionToAuth和security.keyFile内部身份验证来运行。
转换每个分片副本集成员以强制执行身份验证
创建分片本地管理员
在强制执行身份验证的分片集群中,每个分片副本集都应有自己的分片本地管理员。 您不能使用一个分片的分片本地管理员来访问另一个分片或分片集群。
连接到每个分片副本集的主节点,并使用db.createUser()方法创建一个用户,为其分配以下角色:
clusterAdminadmin数据库上的数据库上的
userAdmin角色admin
提示
您可以将 passwordPrompt() 方法与各种用户身份验证/管理方法/命令结合使用,以提示输入密码,而不是直接在方法/命令调用中指定密码。不过,您仍然可以像使用早期版本的 mongo shell 一样直接指定密码。
admin = db.getSiblingDB("admin") admin.createUser( { user: "admin", pwd: passwordPrompt(), // or cleartext password roles: [ { role: "clusterAdmin", db: "admin" }, { role: "userAdmin", db: "admin" } ] } )
完成本教程后,如果要连接到分片以执行需要直接连接到分片的维护操作,则必须以分片本地管理员身份进行身份验证。
注意
与分片的直接连接只能用于特定于分片的维护和配置。 通常,客户端应通过mongos连接到分片集群。
步骤
一次过渡一个分片副本集,对分片集群中的每个分片副本集重复这些步骤。
创建新的mongod 配置文件。
对于分片副本集中的每个mongod ,
在新配置文件中,添加以下设置:
security.transitionToAuth设置为truesecurity.keyFile设置为密钥文件路径。如果使用不同的内部身份验证机制,请指定适合该机制的设置。
security: transitionToAuth: true keyFile: <path-to-keyfile>
mongod使用新的配置文件,一次重启一个 。
从副本集开始,一次重启一个副本集。
所有从节点重新启动并启动后,重新启动主节点:
连接到
mongod。一旦您降级主节点并选举了新的主节点,请对
admin数据库使用db.shutdownServer()方法关闭旧的主节点。db.getSiblingDB("admin").shutdownServer()
此时,分片集群的每个组件都使用--transitionToAuth和security.keyFile内部身份验证运行。 分片集群至少有一个管理用户,每个分片副本集都有一个分片本地管理用户。
其余部分涉及使分片集群脱离过渡状态以全面实施身份验证。
在没有 的情况下重新启动每个mongos 实例transitionToAuth
重要
在本节最后,客户端必须指定身份验证档案才能连接到分片集群。 在完成本部分之前,更新客户端以指定身份验证档案,以避免连接丢失。
要在分片集群中完成向完全强制执行身份验证的过渡,您必须重新启动每个不带mongos 设置的security.transitionToAuth 实例。
从 配置文件中删除transitionToAuthmongos 。
从本教程中创建的security.transitionToAuth mongos配置文件中删除 键及其值。保留教程中添加的security.keyFile设置。
security: keyFile: <path-to-keyfile>
mongos使用更新的配置文件重新启动 。
按照以下步骤重新启动mongos实例,一次启动一个mongos :
连接到
mongos以关闭。对
admin数据库使用db.shutdownServer()方法,安全关闭mongos。db.getSiblingDB("admin").shutdownServer()
在本节的最后,所有mongos实例都强制执行客户端身份验证和security.keyFile内部身份验证。
重新启动每个配置服务器副本集成员,无需 transitionToAuth
重要
在此步骤结束时,客户端必须指定身份验证档案才能连接到配置服务器副本集。 在完成本部分之前,更新客户端以指定身份验证档案,以避免连接丢失。
要在分片集群中完成向完全强制执行身份验证的过渡,您必须重新启动每个不带mongod 设置的security.transitionToAuth 实例。
从 配置文件中删除transitionToAuthmongod 。
从本教程中创建的配置服务器配置文件中删除security.transitionToAuth键及其值。 保留教程中添加的security.keyFile设置。
security: keyFile: <path-to-keyfile>
使用更新的配置文件,一次重启一个 mongod。
从副本集开始,一次重启一个副本集。
要一次重启一个从节点,
连接到
mongod并对admin数据库使用db.shutdownServer()方法,安全关闭mongod。db.getSiblingDB("admin").shutdownServer()
该节点启动后,对下一个从节点重复上述步骤。
所有从节点重新启动并启动后,重新启动主节点:
连接到
mongod。一旦您降级主节点并选举了新的主节点,请对
admin数据库使用db.shutdownServer()方法关闭旧的主节点。db.getSiblingDB("admin").shutdownServer()
在本部分最后,配置服务器副本集中的所有mongod实例都会强制执行客户端身份验证和security.keyFile内部身份验证。
重新启动每个分片副本集中的每个成员,无需 transitionToAuth
重要
在此步骤结束时,客户端必须指定身份验证档案才能连接到分片副本集。 在完成本部分之前,更新客户端以指定身份验证档案,以避免连接丢失。
要在分片集群中完成向完全强制执行身份验证的过渡,您必须重新启动不带security.transitionToAuth设置的分片集群中每个分片副本集的每个成员。
一次过渡一个分片副本集,对分片集群中的每个分片副本集重复这些步骤。
从 配置文件中删除transitionToAuthmongod 。
从本教程中创建的配置服务器配置文件中删除security.transitionToAuth键及其值。 保留教程中添加的security.keyFile设置。
security: keyFile: <path-to-keyfile>
使用更新的配置文件,一次重启一个 mongod。
从副本集开始,一次重启一个副本集。
要一次重启一个从节点,
连接到
mongod并对admin数据库使用db.shutdownServer()方法,安全关闭mongod。db.getSiblingDB("admin").shutdownServer()
该节点启动后,对下一个从节点重复上述步骤。
所有从节点重新启动并启动后,重新启动主节点:
连接到
mongod。一旦您降级主节点并选举了新的主节点,请对
admin数据库使用db.shutdownServer()方法关闭旧的主节点。db.getSiblingDB("admin").shutdownServer()
在本节的最后,分片集群中的所有mongos和mongod实例都会强制执行客户端身份验证和security.keyFile内部身份验证。 客户端只能使用配置的客户端身份验证机制连接到分片集群。 其他组件只能通过指定正确的密钥文件来加入集群。
X.509 证书内部身份验证
MongoDB支持与安全 TLS/SSL 连接一起使用的 X.509 证书身份验证。分片集群成员和副本集成员可以使用 X.509 证书来验证其集群或副本集身份,而无需使用密钥文件。
有关使用 X.509 证书进行内部身份验证的详细信息,请参阅在自管理 MongoDB 上使用 X.509 验证集群成员资格。
从密钥文件身份验证升级到 X.509 身份验证描述如何将部署的内部身份验证机制从基于密钥文件的身份验证升级到基于 X.509 证书的身份验证。