在不停机的情况下在副本集中实施密钥文件访问控制

在本页面

Overview

为了防止未经授权的访问,请对您的部署实施authentication。副本集的身份验证由副本集成员中的internal authentication和连接到副本集的 Client 端的用户访问控制组成。

如果您的部署不强制执行身份验证,则 MongoDB 3.4 将提供--transitionToAuth选项来执行无停机升级以强制执行身份验证。

3.4 版中的新增功能:MongoDB 3.2 和更早版本不支持无停机升级来强制执行身份验证。有关在现有 MongoDB 3.2 副本集中实施身份验证的信息,请参见在副本集中实施密钥文件访问控制

本教程使用keyfile内部身份验证机制来实现内部安全,并使用基于SCRAM基于角色的访问控制来进行 Client 端连接。

Cloud Manager 和 Ops Manager

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

Architecture

本教程假定您的副本集在退出现有的主要副本集成员后可以选择一个新的primary。这要求:

Transition State

--transitionToAuth一起运行的mongod接受经过身份验证的连接和未经身份验证的连接。在此过渡状态期间连接到mongod的 Client 端可以在任何数据库上执行读取,写入和 Management 操作。

Client Access

在以下过程结束时,副本集将拒绝任何尝试构建未经身份验证的连接的 Client 端。该过程将创建users,供 Client 端应用程序在连接到副本集时使用。

有关用户创建和 Management 的最佳做法,请参见➤配置基于角色的访问控制

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 绑定兼容性更改

Passwords

Important

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

对现有副本集实施密钥文件访问控制

创建用户 Management 员。

连接到primary以创建具有userAdminAnyDatabase角色的用户。 userAdminAnyDatabase角色授予对部署中任何数据库上的用户创建的访问权限。

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

Important

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

admin = db.getSiblingDB("admin")
admin.createUser(
  {
    user: "fred",
    pwd: "changeme1",
    roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
  }
)

完成此过程后,任何 Management 副本集中用户的 Client 端都必须以该用户或具有类似权限的用户身份进行身份验证。

有关与数据库 Management 操作有关的内置角色的完整列表,请参见数据库用户角色

创建集群 Management 员。

连接到primary以创建具有clusterAdmin角色的用户。 clusterAdmin角色授予对复制操作的访问权限,例如配置副本集。

下面的示例在admin数据库上创建具有clusterAdmin角色的用户ravi

Important

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

db.getSiblingDB("admin").createUser(
  {
    "user" : "ravi",
    "pwd" : "changeme2",
    roles: [ { "role" : "clusterAdmin", "db" : "admin" } ]
  }
)

完成此过程后,任何 Management 或维护副本集的 Client 端都必须以该用户或具有类似权限的用户身份进行身份验证。

有关副本集操作的内置角色的完整列表,请参见集群 Management 角色

为 Client 端应用程序创建用户。

创建用户以允许 Client 端应用程序连接副本集并与副本集进行交互。完成本教程后,Client 端必须以配置用户身份进行身份验证才能连接到副本集。

有关在创建只读和读写用户中使用的基本内置角色,请参见数据库用户角色

以下内容将创建一个对foo数据库具有读写权限的用户。

Important

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

foo数据库中创建一个具有readWrite角色的用户。

db.getSiblingDB("foo").createUser(
  {
    "user" : "joe",
    "pwd" : "changeme2",
    roles: [ { "role" : "readWrite", "db" : "foo" } ]
  }
)

以此用户身份验证的 Client 端可以对foo数据库执行读取和写入操作。有关创建到副本集的身份验证连接的更多信息,请参见验证用户

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

更新 Client 端应用程序

在此过程的这一点上,副本集不强制执行身份验证。但是,Client 端应用程序仍可以指定身份验证凭据并连接到副本集。

更新 Client 端应用程序以使用配置的用户对副本集进行身份验证。经过身份验证的连接需要用户名,密码和身份验证数据库。参见验证用户

例如,以下连接到名为mongoRepl的副本集并以用户joe身份验证。

mongo  -u joe -password changeme2 -authenticationDatabase foo --host mongoRepl/mongo1.example.net:27017, mongo2.example.net:27017, mongo3.example.net:27017

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

完成本教程后,副本集将拒绝未经身份验证的 Client 端连接。现在执行此步骤可确保 Client 端可以在过渡前后连接到副本集。

创建密钥文件。

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

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

Note

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

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

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

有关使用密钥文件的其他详细信息和要求,请参见Keyfiles

将密钥文件复制到每个副本集成员。

将密钥文件复制到承载副本集成员的每个服务器上。确保运行mongod实例的用户是文件的所有者,并且可以访问密钥文件。

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

使用 transitionToAuth 重新启动副本集的每个辅助或仲裁成员。

重新启动副本集中(包括配置中)的每个secondaryarbiter成员:

您必须一次重新启动每个成员,以确保副本集中的大多数成员保持联机状态。

关闭次要或仲裁员。

从连接到辅助服务器或仲裁服务器的mongoShell 上,针对admin数据库发出db.shutdownServer()

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

通过 transitionToAuth 重新启动辅助或仲裁成员

configuration file中指定以下设置。

从 MongoDB 3.6 开始,默认情况下mongodmongos绑定到 localhost。如果部署的成员在不同的主机上运行,或者希望远程 Client 端连接到部署,则必须指定net.bindIp设置。有关更多信息,请参见Localhost 绑定兼容性更改

security:
  keyFile: <path-to-keyfile>
  transitionToAuth: true
replication:
  replSetName: <replicaSetName>

启动mongod时,请指定--config选项以及配置文件的路径。

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

有关配置文件的更多信息,请参见configuration options

另外,您可以在启动mongod时使用等效的mongod命令行选项(例如--transitionToAuth--keyFile)。有关选项的完整列表,请参见mongod参考页。

包括适合您的部署的其他设置。

在此步骤结束时,应在security.transitionToAuth设置为true的情况下启动所有次要和仲裁程序。

退出副本集的主要成员,然后使用--transitionToAuth 重新启动它。

退出副本集中的primary成员,然后重新启动该成员,包括其配置:

降级主副本集成员

使用mongo shell 连接到主要数据库,并使用rs.stepDown()方法降级主要数据库。

rs.stepDown()

关闭旧的小学

一旦主数据库降级并且副本集选择了新的主数据库,请关闭旧的主数据库mongod

从连接到旧主数据库的mongo shell 中,在 Management 数据库上发出db.shutdownServer()

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

使用 transitionToAuth 重新启动旧的主数据库

configuration file中指定以下设置。

包括配置所需的其他选项。例如,如果您希望远程 Client 端连接到您的部署,或者您的部署成员在不同的主机上运行,请指定net.bindIp设置。有关更多信息,请参见Localhost 绑定兼容性更改

security:
  keyFile: <path-to-keyfile>
  transitionToAuth: true
replication:
  replSetName: <replicaSetName>

使用配置文件启动mongod

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

有关配置文件的更多信息,请参见configuration options

另外,您可以在启动mongod时使用等效的mongod命令行选项(例如--transitionToAuth--keyFile)。有关选项的完整列表,请参见mongod参考页。

包括适合您的部署的其他设置。

在此步骤结束时,副本集的所有成员都应启动并运行,并且将security.transitionToAuth设置为true并将security.keyFile设置为密钥文件路径。

在没有--transitionToAuth 的情况下重新启动次要和仲裁程序

重新启动副本集中的每个secondaryarbiter成员,并在重新启动时删除security.transitionToAuth选项。您必须一次执行一次此操作,以确保副本集中的大多数成员保持联机状态。

如果大多数副本集成员同时处于脱机状态,则副本集可能会进入只读模式。

关闭次要或仲裁员

mongo shell 连接到辅助服务器或仲裁器,然后在数据库上发出db.shutdownServer()

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

重新启动次要成员或仲裁者成员,而无需 transitionToAuth

这次重新启动mongod,没有* security.transitionToAuth选项,但带有*内部认证机制,例如security.keyFile

configuration file中指定以下设置。

包括配置所需的其他选项。例如,如果您希望远程 Client 端连接到您的部署,或者您的部署成员在不同的主机上运行,请指定net.bindIp设置。有关更多信息,请参见Localhost 绑定兼容性更改

security:
  keyFile: <path-to-keyfile>
replication:
  replSetName: <replicaSetName>

使用配置文件启动mongod

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

有关配置文件的更多信息,请参见configuration options

启动mongod时,您也可以使用等效的mongod选项。有关完整的选项列表,请参见mongod参考页。

包括适合您的部署的其他设置。

在此步骤结束时,所有辅助副本和仲裁器都应在配置了内部身份验证的情况下启动并运行,但必须* without * security.transitionToAuth。Client 端只能使用配置的 Client 端身份验证机制连接到这些mongod实例。

退出并重新启动没有--transitionToAuth 的主副本集成员。

退出副本集中的primary成员,然后在没有security.transitionToAuth选项的情况下重新启动它。

Important

在此步骤结束时,未与 auth 连接的 Client 端无法连接到副本集。在完成此步骤之前,请*更新 Client 端以使用身份验证进行连接,以避免失去连接。

降级主副本集成员

使用mongo shell 连接到主要数据库,并使用rs.stepDown()方法降级主要数据库。

rs.stepDown()

关闭旧的小学

一旦主数据库降级并且副本集选择了新的主数据库,请关闭旧的主数据库mongod

从连接到旧主数据库的mongo shell 中,在 Management 数据库上发出db.shutdownServer()

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

重新启动旧的主数据库,无需 transitionToAuth

这次重新启动mongod,没有* security.transitionToAuth选项,但是内部认证机制,例如security.keyFile

configuration file中指定以下设置。

security:
  keyFile: <path-to-keyfile>
replication:
  replSetName: <replicaSetName>

使用配置文件启动mongod

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

有关配置文件的更多信息,请参见configuration options

您也可以在启动 mongod 时使用等效的mongod选项。有关选项的完整列表,请参见mongod参考页。

包括适合您的部署的其他设置。

在此步骤结束时,副本集的所有成员都应启动并运行并强制执行身份验证。Client 端只能使用配置的 Client 端身份验证机制连接到这些mongod实例。

x.509 内部身份验证

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

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