将自管理副本集更新为密钥文件身份验证(无停机时间)
Overview
为了防止未经授权的访问权限,请对您的部署实施身份验证。 副本集的身份验证包括副本副本集节点之间的内部身份验证,以及连接到副本集的客户端的用户访问权限控制。
如果您的部署当前不强制执行身份验证,则可以使用 --transitionToAuth
选项在不停机的情况下强制执行身份验证。
本教程使用密钥文件内部身份验证机制实现内部安全,并使用基于SCRAM和角色的访问控制实现客户端连接。
Cloud Manager 或 Ops Manager
如果您使用Cloud Manager或MongoDB Ops Manager来管理部署,请参阅相应的 Cloud Manager手册或MongoDB Ops Manager手册以强制执行身份验证。
架构
本教程假设您的副本集可以在现有主节点副本集成员退出后选举新的主节点。 这需要:
过渡状态
mongod
--transitionToAuth
使用 既接受经过身份验证的连接,也接受未经身份验证的连接。在此转换状态期间连接到mongod
的客户端可以对任何数据库执行读取、写入和管理操作。
客户端访问
在以下过程结束时,副本集会拒绝任何尝试进行未经身份验证的连接的客户端。 该过程为客户端应用程序创建用户,以便在连接到副本集时使用。
有关用户创建和管理的最佳实践,请参阅➤ 配置基于角色的访问控制。
IP 绑定
密码
重要
密码应随机、长且复杂,以确保系统安全并防止或延迟恶意访问。
对现有副本集执行密钥文件访问控制
重要
要避免因 IP 地址变更而更新配置,请使用 DNS 主机名而非 IP 地址。在配置副本集成员或分片集群成员时,使用 DNS 主机名而非 IP 地址尤为重要。
在水平分割网络配置下,请使用主机名而非 IP 地址来配置集群。从 MongoDB 5.0 开始,仅配置了 IP 地址的节点将无法通过启动验证,因而不会启动。
创建用户管理员。
连接到主节点以创建具有userAdminAnyDatabase
角色的用户。 userAdminAnyDatabase
角色授予在部署中的任何数据库上创建用户的访问权限。
以下示例在 admin
数据库上创建具有 userAdminAnyDatabase
角色的用户 fred
。
重要
密码应随机、长且复杂,以确保系统安全并防止或延迟恶意访问。
提示
您可以将 passwordPrompt()
方法与各种用户身份验证/管理方法/命令结合使用,以提示输入密码,而不是直接在方法/命令调用中指定密码。不过,您仍然可以像使用早期版本的 mongo
shell 一样直接指定密码。
admin = db.getSiblingDB("admin") admin.createUser( { user: "fred", pwd: " passwordPrompt(), // or cleartext password roles: [ { role: "userAdminAnyDatabase", db: "admin" } ] } )
完成此过程后,管理副本集中用户的任何客户端都必须以此用户或具有类似权限的用户身份进行身份验证。
有关内置角色和与数据库管理操作相关的角色的完整列表,请参阅数据库用户角色。
创建集群管理员。
连接到主节点以创建具有clusterAdmin
角色的用户。 clusterAdmin
角色授予对复制操作的访问权限,例如配置副本集。
以下示例在 admin
数据库上创建具有 clusterAdmin
角色的用户 ravi
。
重要
密码应随机、长且复杂,以确保系统安全并防止或延迟恶意访问。
提示
您可以将 passwordPrompt()
方法与各种用户身份验证/管理方法/命令结合使用,以提示输入密码,而不是直接在方法/命令调用中指定密码。不过,您仍然可以像使用早期版本的 mongo
shell 一样直接指定密码。
db.getSiblingDB("admin").createUser( { "user" : "ravi", "pwd" : passwordPrompt(), // or cleartext password roles: [ { "role" : "clusterAdmin", "db" : "admin" } ] } )
完成此过程后,任何管理或维护副本集的客户端都必须以此用户或具有类似权限的用户身份进行身份验证。
请参阅集群管理角色,获取与副本集操作相关的内置角色的完整清单。
为客户端应用程序创建用户。
创建用户以允许客户端应用程序与副本集连接并交互。 完成本教程后,客户端必须以已配置用户的身份进行身份验证,才能连接到副本集。
有关用于创建只读和读写用户的基本内置角色,请参阅数据库用户角色。
以下创建了一个对foo
数据库具有读写权限的用户。
重要
密码应随机、长且复杂,以确保系统安全并防止或延迟恶意访问。
在foo
数据库中创建具有readWrite
角色的用户。
提示
您可以将 passwordPrompt()
方法与各种用户身份验证/管理方法/命令结合使用,以提示输入密码,而不是直接在方法/命令调用中指定密码。不过,您仍然可以像使用早期版本的 mongo
shell 一样直接指定密码。
db.getSiblingDB("foo").createUser( { "user" : "joe", "pwd" : passwordPrompt(), // or cleartext password roles: [ { "role" : "readWrite", "db" : "foo" } ] } )
以该用户身份进行身份验证的客户端可以对foo
数据库执行读取和写入操作。 有关创建与副本集的经过身份验证的连接的更多信息,请参阅使用自管理部署对用户进行身份验证。
更新客户端应用程序
在此点中,副本集不强制执行身份验证。但是,客户端应用程序仍可指定身份验证档案并连接到副本集。
更新客户端应用程序以使用配置的用户对副本集进行身份验证。 经过身份验证的连接需要用户名、密码和身份验证数据库。 请参阅使用自管理部署对用户进行身份验证。
例如,以下连接到设置名称为mongoRepl
的副本集并以用户joe
进行身份验证。
mongosh -u joe -password -authenticationDatabase foo --host mongoRepl/mongo1.example.net:27017, mongo2.example.net:27017, mongo3.example.net:27017
如果您没有为 -p
命令行选项指定密码,mongosh
会提示输入密码。
如果您的应用程序使用 MongoDB 驱动程序,请参阅相关的驱动程序文档以浏览创建验证连接的说明。
完成本教程后,副本集会拒绝未经身份验证的客户端连接。现在执行此步骤可确保客户端可以在过渡前后连接到副本集。
创建密钥文件。
通过密钥文件身份验证,副本集中的每个 mongod
实例都使用密钥文件的内容作为共享密码,对部署中的其他节点进行身份验证。只有具有正确密钥文件的 mongod
实例才能加入副本集。
注意
用于内部成员身份验证的密钥文件使用 YAML 格式,允许在密钥文件中包含多个密钥。YAML 格式接受以下任一形式:
单个密钥字符串(与早期版本相同)
键字符串序列
YAML 格式与使用文本文件格式的现有单密钥文件兼容。
密钥的长度必须介于 6 到 1,024 个字符之间,且只能包含 base64 集合中的字符。复制集的所有成员均须至少共享一个公钥。
注意
在 UNIX 系统上,密钥文件不得具有群组或全局权限。在 Windows 系统中,不检查密钥文件权限。
您可以选择任何方法生成密钥文件。例如,以下操作使用 openssl
生成复杂的伪随机 1024 字符串以用作共享密码。然后,它使用 chmod
更改文件权限,仅为文件所有者提供读取权限:
openssl rand -base64 756 > <path-to-keyfile> chmod 400 <path-to-keyfile>
有关使用密钥文件的更多详细信息和要求,请参阅密钥文件。
使用 重新启动副本集的每个从从节点(secondary nodetransitionToAuth
from replica set)或仲裁节点。
重新启动副本集中的每个secondary或 仲裁节点 ,包括在配置 中 :
security.transitionToAuth
设置。 在 设置为 的情况下启动mongod
security.transitionToAuth
会使实例处于过渡状态,在该状态下,它可以接受和创建经过身份验证和未经身份验证的连接。true
内部身份验证机制,例如
security.keyFile
。
您必须一次重启一个成员,以确保副本集中的大多数成员保持在线。
关闭从节点或仲裁节点成员。
从连接到从节点或仲裁节点的mongosh
会话中,针对admin
数据库发出db.shutdownServer()
。
admin = db.getSiblingDB("admin") admin.shutdownServer()
重新启动从节点或仲裁节点成员 transitionToAuth
security.keyFile
,替换为密钥文件的路径。replication.replSetName
为原始副本集设置名称。将
security.transitionToAuth
更改为true
。
mongod
和mongos
默认绑定到本地主机。 如果部署的成员在不同主机上运行,或者希望远程客户端连接到部署,则必须指定net.bindIp
设置。
security: keyFile: <path-to-keyfile> transitionToAuth: true replication: replSetName: <replicaSetName>
启动 mongod
时,指定--config
选项以及配置文件的路径
mongod --config <path-to-config-file>
有关配置文件的更多信息,请参阅配置选项。
或者,您可以使用等效的mongod
命令行选项(例如 --transitionToAuth
和--keyFile
)启动mongod
时。 有关选项的完整列表,请参阅mongod
参考页面。
根据您的部署包含其他设置。
在此步骤结束时,所有从节点和仲裁节点都应启动并运行,并将security.transitionToAuth
设置为true
。
将副本集的主节点 (primary node in the replica set)节点降级,并使用--transitionToAuth
重新启动。
降级副本集中的主节点并重新启动该节点,包括在其配置中:
security.transitionToAuth
设置。 在 设置为 的情况下启动mongod
security.transitionToAuth
会使实例处于过渡状态,在该状态下,它可以接受和创建经过身份验证和未经身份验证的连接。true
内部身份验证机制,例如
security.keyFile
。
降级主节点副本集成员
使用mongosh
连接到主节点,并使用rs.stepDown()
方法降级主节点。
rs.stepDown()
关闭旧的主节点
一旦主节点降级并且副本集选出新的主节点,请关闭旧的主mongod
。
从连接到主节点 (primary node in the replica set)的mongosh
会话中,对admin
数据库发出db.shutdownServer()
。
admin = db.getSiblingDB("admin") admin.shutdownServer()
重新启动旧的主节点 transitionToAuth
security.keyFile
,替换为密钥文件的路径。replication.replSetName
为原始副本集设置名称。将
security.transitionToAuth
更改为true
。
根据配置要求包括其他选项。例如,如果您希望远程客户端连接到部署,或者部署节点运行在不同的主机上,请指定 net.bindIp
设置。
security: keyFile: <path-to-keyfile> transitionToAuth: true replication: replSetName: <replicaSetName>
使用配置文件启动mongod
。
mongod --config <path-to-config-file>
有关配置文件的更多信息,请参阅配置选项。
或者,您可以使用等效的mongod
命令行选项(例如 --transitionToAuth
和--keyFile
)启动mongod
时。 有关选项的完整列表,请参阅mongod
参考页面。
根据您的部署包含其他设置。
在此步骤结束时,副本集的所有成员都应启动并运行,并将security.transitionToAuth
设置为true
,并将security.keyFile
设置为密钥文件路径。
在没有 的情况下重新启动从节点和仲裁节点--transitionToAuth
重新启动副本集中的每个从节点或仲裁节点,在重新启动时删除security.transitionToAuth
选项。您必须逐个执行此操作,以确保副本集中的大多数成员保持在线。
如果大多数副本集成员同时离线,副本集可能会Go只读模式。
关闭从节点或仲裁节点成员
将mongosh
连接到从从节点(secondary node from replica set)或仲裁节点,并对admin
数据库发出db.shutdownServer()
。
admin = db.getSiblingDB("admin") admin.shutdownServer()
重新启动从节点或仲裁节点成员,无需 transitionToAuth
重新启动mongod
,这次不使用security.transitionToAuth
选项,但使用内部身份验证机制,例如security.keyFile
。
security.keyFile
,替换为密钥文件的路径。replication.replSetName
为原始副本集设置名称。
根据配置要求包括其他选项。例如,如果您希望远程客户端连接到部署,或者部署节点运行在不同的主机上,请指定 net.bindIp
设置。
security: keyFile: <path-to-keyfile> replication: replSetName: <replicaSetName>
使用配置文件启动 mongod
:
mongod --config <path-to-config-file>
有关配置文件的更多信息,请参阅配置选项。
您还可以在启动 时使用等效的mongod
mongod
选项。有关完整选项列表,请参阅mongod
参考页面。
根据您的部署包含其他设置。
在此步骤结束时,所有从节点和仲裁节点都应启动并运行,并配置内部身份验证,但没有security.transitionToAuth
。 客户端只能使用配置的客户端身份验证机制连接到这些mongod
实例。
降级并重启不带 的主节点 (primary node in the replica --transitionToAuth
set)副本集成员。
将副本集中的主节点降级,然后在不使用security.transitionToAuth
选项的情况下重新启动。
重要
在此步骤结束时,未使用身份验证连接的客户端无法连接到副本集。 在完成此步骤之前,更新客户端以通过身份验证进行连接,以避免连接丢失。
降级主节点副本集成员
使用mongosh
连接到主节点,并使用rs.stepDown()
方法降级主节点。
rs.stepDown()
关闭旧的主节点
一旦主节点降级并且副本集选出新的主节点,请关闭旧的主mongod
。
从连接到主节点 (primary node in the replica set)的mongosh
会话中,对admin
数据库发出db.shutdownServer()
。
admin = db.getSiblingDB("admin") admin.shutdownServer()
重新启动旧的主节点,无需 transitionToAuth
重新启动mongod
,这次不使用security.transitionToAuth
选项,但使用内部身份验证机制,例如security.keyFile
。
security.keyFile
,替换为密钥文件的路径。replication.replSetName
为原始副本集设置名称。
security: keyFile: <path-to-keyfile> replication: replSetName: <replicaSetName>
使用配置文件启动 mongod
:
mongod --config <path-to-config-file>
有关配置文件的更多信息,请参阅配置选项。
您还可以在启动 mongod 时使用等效的mongod
选项。 有关完整选项列表,请参阅mongod
参考页。
根据您的部署包含其他设置。
在此步骤结束时,副本集的所有成员均应启动并运行,并强制执行身份验证。 客户端只能使用配置的客户端身份验证机制连接到这些mongod
实例。
x.509 内部身份验证
有关使用 x.509 进行内部身份验证的详细信息,请参阅使用 x.509 证书对托理 MongoDB 进行成员身份验证。
要从密钥文件内部身份验证升级到 x. 509内部身份验证,请参阅将自管理MongoDB从密钥文件身份验证升级到 x。 509身份验证。