使用密钥文件访问控制部署分片群集
在本页面
Overview
在sharded cluster上执行访问控制需要配置:
-
使用Internal Authentication的群集组件之间的安全性。
-
使用用户访问控制连接 Client 端和群集之间的安全性。
对于本教程,分片群集的每个成员必须使用相同的内部身份验证机制和设置。这意味着对群集中的每个mongos和mongod强制执行内部身份验证。
以下教程使用keyfile启用内部身份验证。
强制执行内部身份验证也会强制执行用户访问控制。要连接到副本集,诸如mongo shell 之类的 Client 端需要使用user account。参见Access Control。
CloudManager 和 OpsManager
如果您使用 Cloud Manager 或 Ops ManagerManagement 部署,请参阅相应的Cloud Manager 手册或Ops Manager 手册以强制执行身份验证。
Considerations
IP Binding
在版本 3.6 中更改。
从 MongoDB 3.6 开始,MongoDB 二进制文件mongod和mongos默认绑定到localhost
。从 MongoDB 版本 2.6 到 3.4,默认情况下,只有来自正式 MongoDB RPM(Red Hat,CentOS,Fedora Linux 和衍生产品)和 DEB(Debian,Ubuntu 和衍生产品)软件包的二进制文件会绑定到localhost
。要了解有关此更改的更多信息,请参见Localhost 绑定兼容性更改。
Keyfile Security
密钥文件是最低限度的安全性形式,最适合于测试或开发环境。对于生产环境,我们建议使用x.509 certificates。
Access Control
本教程介绍了在admin
数据库* only *上创建最少数量的 Management 用户。对于用户身份验证,本教程使用默认的SCRAM身份验证机制。质询响应安全机制最适合测试或开发环境。对于生产环境,我们建议使用x.509 certificates或LDAP 代理验证(仅适用于 MongoDB Enterprise)或Kerberos Authentication(仅适用于 MongoDB Enterprise)。
有关为特定身份验证机制创建用户的详细信息,请参阅特定身份验证机制页面。
有关创建和 Management 用户的最佳做法,请参见➤配置基于角色的访问控制。
Users
通常,要为分片群集创建用户,请连接到mongos并添加分片群集用户。
但是,某些维护操作需要直接连接到分片群集中的特定分片。要执行这些操作,您必须直接连接到分片并以分片本地 Management 用户身份进行身份验证。
分片本地用户仅存在于特定分片中,并且仅应用于分片特定的维护和配置。您无法使用本地分片用户连接到mongos。
本教程要求创建分片集群用户,但包括添加分片本地用户的可选步骤。
有关更多信息,请参见Users安全文档。
Operating System
本教程使用mongod和mongos程序。 Windows 用户应改用mongod.exe和mongos.exe程序。
使用密钥文件访问控制部署分片群集
以下过程涉及创建一个新的分片群集,该群集由mongos,配置服务器和两个分片组成。
创建密钥文件
通过keyfile身份验证,分片群集中的每个mongod或mongos实例都将密钥文件的内容用作共享密码,以对部署中的其他成员进行身份验证。具有正确密钥文件的mongod或mongos实例只能加入分片群集。
密钥文件的内容长度必须在 6 到 1024 个字符之间,并且对于分片群集的所有成员都必须相同。
Note
在 UNIX 系统上,密钥文件不得具有组或世界权限。在 Windows 系统上,不检查密钥文件权限。
您可以使用任何选择的方法来生成密钥文件。例如,以下操作使用openssl
生成用于密钥文件的复杂伪随机 1024 字符串。然后,它使用chmod
更改文件权限,以仅为文件所有者提供读取权限:
openssl rand -base64 756 > <path-to-keyfile>
chmod 400 <path-to-keyfile>
有关使用密钥文件的其他详细信息和要求,请参见Keyfiles。
分发密钥文件
将密钥文件复制到托管分片集群成员的每个服务器。确保运行mongod或mongos实例的用户是文件的所有者,并且可以访问密钥文件。
避免将密钥文件存储在易于与托管mongod或mongos实例的硬件断开连接的存储介质上,例如 USB 驱动器或网络连接的存储设备。
创建配置服务器副本集
以下步骤将部署配置服务器副本集。
对于生产部署,请部署至少具有三个成员的配置服务器副本集。出于测试目的,您可以创建单成员副本集。
在配置服务器副本集中启动* each * mongod。包括keyFile
设置。 keyFile
设置同时强制Internal Authentication和基于角色的访问控制。
您可以通过配置文件或命令行指定mongod设置。
Configuration File
如果使用配置文件,请将security.keyFile设置为密钥文件的路径,将sharding.clusterRole设置为configsvr
,并将replication.replSetName设置为配置服务器副本集的所需名称。
security:
keyFile: <path-to-keyfile>
sharding:
clusterRole: configsvr
replication:
replSetName: <setname>
包括配置所需的其他选项。例如,如果您希望远程 Client 端连接到您的部署,或者您的部署成员在不同的主机上运行,请指定net.bindIp设置。有关更多信息,请参见Localhost 绑定兼容性更改。
启动mongod,指定--config
选项和配置文件的路径。
mongod --config <path-to-config-file>
Command Line
如果使用命令行参数,请使用--keyFile
,--configsvr
和--replSet
参数启动mongod。
mongod --keyFile <path-to-keyfile> --configsvr --replSet <setname> --dbpath <path>
包括配置所需的其他选项。例如,如果您希望远程 Client 端连接到您的部署,或者您的部署成员在不同的主机上运行,请指定--bind_ip
。有关更多信息,请参见Localhost 绑定兼容性更改。
通过 localhost 接口连接到副本集的成员。
将mongoShell 连接到localhost interface上的mongod实例之一。您必须在与mongod实例相同的物理计算机上运行mongo shell。
localhost interface仅由于没有为部署创建用户而可用。 localhost interface在创建第一个用户后关闭。
rs.initiate()方法启动副本集,并可以采用可选的副本集配置文档。在副本集配置文档中,包括:
有关副本集配置文档的更多信息,请参见副本集配置。
使用rs.initiate()方法和配置文档初始化副本集:
rs.initiate(
{
_id: "<replSetName>",
configsvr: true,
members: [
{ _id : 0, host : "cfg1.example.net:27017" },
{ _id : 1, host : "cfg2.example.net:27017" },
{ _id : 2, host : "cfg3.example.net:27017" }
]
}
)
启动并启动配置服务器副本集(CSRS)后,continue 创建分片副本集。
创建分片副本集
对于生产部署,请使用至少具有三个成员的副本集。出于测试目的,您可以创建单成员副本集。
这些步骤包括添加分片本地用户的可选过程。现在执行它们可以确保每个分片都有可用的用户来执行分片级维护。
在启用访问控制的情况下启动副本集的每个成员。
使用keyFile
参数运行mongod会同时强制Internal Authentication和基于角色的访问控制。
使用配置文件或命令行在副本集中启动每个 mongod。
Configuration File
如果使用配置文件,则将security.keyFile选项设置为密钥文件的路径,将replication.replSetName设置为所需的副本集名称,并将sharding.clusterRole选项设置为shardsvr
。
security:
keyFile: <path-to-keyfile>
sharding:
clusterRole: shardsvr
replication:
replSetName: <replSetName>
storage:
dbPath: <path>
包括配置所需的其他选项。例如,如果您希望远程 Client 端连接到您的部署,或者您的部署成员在不同的主机上运行,请指定net.bindIp设置。有关更多信息,请参见Localhost 绑定兼容性更改。
启动mongod,指定--config
选项和配置文件的路径。
mongod --config <path-to-config-file>
Command Line
如果使用命令行选项,则在启动组件时,请指定--keyFile
,replSet
和--shardsvr
参数,如以下示例所示:
mongod --keyFile <path-to-keyfile> --shardsvr --replSet <replSetName> --dbpath <path>
包括配置所需的其他选项。例如,如果您希望远程 Client 端连接到您的部署,或者您的部署成员在不同的主机上运行,请指定--bind_ip
。有关更多信息,请参见Localhost 绑定兼容性更改。
通过 localhost 接口连接到副本集的成员。
将mongoShell 连接到localhost interface上的mongod实例之一。您必须在与mongod实例相同的物理计算机上运行mongo shell。
localhost interface仅由于没有为部署创建用户而可用。 localhost interface在创建第一个用户后关闭。
启动副本集。
在mongo shell 中,运行rs.initiate()方法。
rs.initiate()可以选填副本集配置文档。在副本集配置文档中,包括:
-
_id字段设置为在replication.replSetName或
--replSet
选项中指定的副本集名称。 -
members数组,每个副本集中每个成员都有一个文档。
下面的示例初始化一个三成员副本集。
rs.initiate(
{
_id : <replicaSetName>,
members: [
{ _id : 0, host : "s1-mongo1.example.net:27017" },
{ _id : 1, host : "s1-mongo2.example.net:27017" },
{ _id : 2, host : "s1-mongo3.example.net:27017" }
]
}
)
rs.initiate()触发election并选举成员之一成为primary。
在 continue 之前,请连接到主服务器。使用rs.status()查找主要成员。
创建分片本地用户 Management 员(可选)。
Important
创建第一个用户后,localhost exception将不再可用。
第一个用户必须具有创建其他用户(例如具有userAdminAnyDatabase的用户)的特权。这样可以确保您可以在Localhost Exception关闭后创建其他用户。
如果至少一个用户没有创建用户的特权,则在 localhost 异常关闭后,您可能无法使用新特权创建或修改用户,因此无法访问必要的操作。
使用db.createUser()方法添加用户。用户在admin
数据库上至少应具有userAdminAnyDatabase角色。
您必须连接到primary才能创建用户。
下面的示例在admin
数据库上创建具有userAdminAnyDatabase角色的用户fred
。
Important
密码应随机,长且复杂,以确保系统安全并防止或延迟恶意访问。
admin = db.getSiblingDB("admin")
admin.createUser(
{
user: "fred",
pwd: "changeme1",
roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
}
)
有关与数据库 Management 操作有关的内置角色的完整列表,请参见数据库用户角色。
以本地用户身份验证(可选)。
验证到admin
数据库。
在mongo shell 中,使用db.auth()进行身份验证。例如,以下身份验证为用户 Management 员fred
:
db.getSiblingDB("admin").auth("fred", "changeme1" )
或者,使用-u <username>
,-p <password>
和--authenticationDatabase
参数将新的mongo shell 连接到主副本集成员。
mongo -u "fred" -p "changeme1" --authenticationDatabase "admin"
创建分片本地集群 Management 员(可选)。
本地分片群集 Management 员用户具有clusterAdmin角色,该角色提供允许访问复制操作的特权。
有关与副本集操作相关的角色的完整列表,请参见集群 Management 角色。
创建集群 Management 员用户,并在admin
数据库中分配clusterAdmin角色:
db.getSiblingDB("admin").createUser(
{
"user" : "ravi",
"pwd" : "changeme2",
roles: [ { "role" : "clusterAdmin", "db" : "admin" } ]
}
)
有关副本集和分片群集操作的内置角色的完整列表,请参见集群 Management 角色。
将 mongos 连接到分片集群
将 mongos 连接到集群
使用配置文件或命令行参数启动mongos以指定密钥文件。
Configuration File
如果使用configuration file,请将security.keyFile设置为密钥文件的路径,并将sharding.configDB设置为副本集的名称,并且副本集的至少一个成员应使用<replSetName>/<host:port>
格式。
security:
keyFile: <path-to-keyfile>
sharding:
configDB: <configReplSetName>/cfg1.example.net:27019,cfg2.example.net:27019,...
包括配置所需的其他选项。例如,如果您希望远程 Client 端连接到您的部署,或者您的部署成员在不同的主机上运行,请指定net.bindIp设置。有关更多信息,请参见Localhost 绑定兼容性更改。
启动mongos,指定--config
选项和配置文件的路径。
mongos --config <path-to-config>
Command Line
如果使用命令行参数,请启动mongos并指定--keyFile
和--configdb
参数。
mongos --keyFile <path-to-keyfile> --configdb <configReplSetName>/cfg1.example.net:27019,cfg2.example.net:27019,...
包括配置所需的其他选项。例如,如果您希望远程 Client 端连接到您的部署,或者您的部署成员在不同的主机上运行,请指定--bind_ip
。有关更多信息,请参见Localhost 绑定兼容性更改。
通过 localhost 接口连接到 mongos。
将mongoShell 连接到localhost interface上的mongos实例之一。您必须在与mongos实例相同的物理计算机上运行mongo shell。
localhost interface仅由于没有为部署创建用户而可用。 localhost interface在创建第一个用户后关闭。
创建用户 Management 员。
Important
创建第一个用户后,localhost exception将不再可用。
第一个用户必须具有创建其他用户(例如具有userAdminAnyDatabase的用户)的特权。这样可以确保您可以在Localhost Exception关闭后创建其他用户。
如果至少一个用户没有创建用户的特权,那么在 localhost 异常关闭后,您将无法创建或修改用户,因此可能无法执行必要的操作。
使用db.createUser()方法添加用户。用户在admin
数据库上至少应具有userAdminAnyDatabase角色。
Important
密码应随机,长且复杂,以确保系统安全并防止或延迟恶意访问。
下面的示例在admin
数据库上创建用户fred
:
admin = db.getSiblingDB("admin")
admin.createUser(
{
user: "fred",
pwd: "changeme1",
roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
}
)
有关与数据库 Management 操作有关的内置角色的完整列表,请参见数据库用户角色。
以用户 Management 员身份进行身份验证。
使用db.auth()验证用户 Management 员身份以创建其他用户:
db.getSiblingDB("admin").auth("fred", "changeme1" )
或者,使用-u <username>
,-p <password>
和--authenticationDatabase "admin"
参数将新的mongo shell 连接到目标副本集成员。您必须使用Localhost Exception连接到mongos。
mongo -u "fred" -p "changeme1" --authenticationDatabase "admin"
为群集 Management 创建 Management 用户
群集 Management 员用户具有clusterAdmin角色,该角色授予对复制和分片操作的访问权限。
在admin
数据库中创建一个clusterAdmin用户。
下面的示例在admin
数据库上创建用户ravi
。
Important
密码应随机,长且复杂,以确保系统安全并防止或延迟恶意访问。
db.getSiblingDB("admin").createUser(
{
"user" : "ravi",
"pwd" : "changeme2",
roles: [ { "role" : "clusterAdmin", "db" : "admin" } ]
}
)
有关副本集和分片群集操作的内置角色的完整列表,请参见集群 Management 角色。
创建其他用户(可选)。
创建用户以允许 Client 端连接和访问分片群集。请参阅数据库用户角色以获取可用的内置角色,例如read和readWrite。您可能还需要其他 Management 用户。有关用户的更多信息,请参见Users。
要创建其他用户,您必须认证为具有userAdminAnyDatabase或userAdmin角色的用户。
将碎片添加到群集
要 continue,您必须连接到mongos并以分片群集的群集 Management 员身份验证。
Note
这是分片群集的群集 Management 员,不是分片本地群集 Management 员。
要将每个分片添加到群集,请使用sh.addShard()方法。如果该分片是副本集,请指定副本集的名称并指定该集的成员。在生产部署中,所有分片应为副本集。
以下操作将单个分片副本集添加到集群:
sh.addShard( "<replSetName>/s1-mongo1.example.net:27017")
以下操作是向群集添加独立的mongod分片的示例:
sh.addShard( "s1-mongo1.example.net:27017")
重复这些步骤,直到群集包含所有分片。此时,分片群集对群集以及每个分片群集组件之间的内部通信实施访问控制。
启用数据库分片
要 continue,您必须连接到mongos并以分片群集的群集 Management 员身份验证。
Note
这是分片群集的群集 Management 员,不是分片本地群集 Management 员。
在数据库上启用分片可以在数据库中分片集合。使用sh.enableSharding()方法可以在目标数据库上启用分片。
sh.enableSharding("<database>")
分片集合
要 continue,您必须连接到mongos并以分片群集的群集 Management 员身份验证。
Note
这是分片群集的群集 Management 员,不是分片本地群集 Management 员。
要分片集合,请使用sh.shardCollection()方法。您必须指定集合的完整名称空间以及包含分片键的文档。
您对分片密钥的选择会影响分片的效率,以及您利用某些分片功能(例如zones)的能力。请参阅选择分片键中列出的选择注意事项。
如果集合已经包含数据,则必须在使用shardCollection()之前使用db.collection.createIndex()方法在shard key上创建索引。
如果集合为空,则 MongoDB 将创建索引作为sh.shardCollection()的一部分。
以下是sh.shardCollection()方法的示例:
sh.shardCollection("<database>.<collection>", { <key> : <direction> } )
Next Steps
创建用户以允许 Client 端连接到分片群集并与之交互。
有关在创建只读和读写用户中使用的基本内置角色,请参见数据库用户角色。
x.509 内部身份验证
有关使用 x.509 进行内部身份验证的详细信息,请参阅使用 x.509 证书进行会员身份验证。
要将密钥文件内部身份验证升级到 x.509 内部身份验证,请参阅从密钥文件身份验证升级到 x.509 身份验证。
See also