文档版本 v3.7-DRAFT 处于 草稿 状态。如需获取最新的稳定版文档,请参阅 v3.6。
基于角色的访问控制
概述
身份验证功能在 etcd 2.1 中添加。etcd v3 API 对身份验证功能的 API 和用户界面进行了轻微修改,以更好地适应新的数据模型。本指南旨在帮助用户在 etcd v3 中设置基本的身份验证和基于角色的访问控制。
特殊用户和角色
有一个特殊的用户 root 和一个特殊的角色 root。
用户 root
root 用户拥有对 etcd 的完全访问权限,在激活身份验证之前必须创建该用户。root 用户的目的是用于管理角色和普通用户。root 用户必须具有 root 角色,并且可以更改 etcd 内部的任何内容。
角色 root
除了 root 用户外,root 角色也可以授予任何其他用户。具有 root 角色的用户具有全局读写访问权限,并且可以更新集群的身份验证配置。此外,root 角色还授予一般的集群维护权限,包括修改集群成员、碎片整理和快照。
用户管理
etcdctl 的 user 子命令处理所有与用户账户相关的事宜。
可以通过以下命令列出用户:
$ etcdctl user list
创建用户非常简单,只需运行:
$ etcdctl user add myusername
创建新用户时会提示输入新密码。如果提供了选项 --interactive=false,可以从标准输入提供密码。也可以使用 --new-user-password 提供密码。
还可以创建一个不能用密码进行身份验证的用户,如下所示:
$ etcdctl user add myusername --no-password
这样的用户只能通过TLS 通用名称进行身份验证。
可以使用以下命令为用户授予权限或撤销权限:
$ etcdctl user grant-role myusername foo
$ etcdctl user revoke-role myusername bar
可以使用以下命令检查用户的设置:
$ etcdctl user get myusername
可以使用以下命令更改用户的密码:
$ etcdctl user passwd myusername
更改密码时会再次提示输入新密码。如果提供了选项 --interactive=false,可以从标准输入提供密码。
使用以下命令删除账户:
$ etcdctl user delete myusername
角色管理
etcdctl 的 role 子命令处理与特定角色相关的所有访问控制事宜,这些角色被授予个别用户。
使用以下命令列出角色:
$ etcdctl role list
使用以下命令创建新角色:
$ etcdctl role add myrolename
角色没有密码;它只是定义了一组新的访问权限。
角色被授予对单个键或一系列键的访问权限。
范围可以指定为区间 [start-key, end-key),其中 start-key 应该在字母顺序上小于 end-key。
访问权限可以被授予读、写或两者,如下例所示:
# Give read access to a key /foo
$ etcdctl role grant-permission myrolename read /foo
# Give read access to keys with a prefix /foo/. The prefix is equal to the range [/foo/, /foo0)
$ etcdctl role grant-permission myrolename --prefix=true read /foo/
# Give write-only access to the key at /foo/bar
$ etcdctl role grant-permission myrolename write /foo/bar
# Give full access to keys in a range of [key1, key5)
$ etcdctl role grant-permission myrolename readwrite key1 key5
# Give full access to keys with a prefix /pub/
$ etcdctl role grant-permission myrolename --prefix=true readwrite /pub/
要查看已授予的权限,我们可以随时查看角色:
$ etcdctl role get myrolename
撤销权限也是以同样的逻辑方式进行:
$ etcdctl role revoke-permission myrolename /foo/bar
完全移除一个角色也是如此:
$ etcdctl role delete myrolename
启用身份验证
启用身份验证的最小步骤如下。管理员可以在启用身份验证之前或之后设置用户和角色,这取决于个人偏好。
确保创建了根用户:
$ etcdctl user add root
Password of root:
启用身份验证:
$ etcdctl auth enable
此后,etcd 将在启用了身份验证的情况下运行。出于任何原因需要禁用它时,请使用相应的命令:
$ etcdctl --user root:rootpw auth disable
使用 etcdctl 进行身份验证
etcdctl 支持与 curl 类似的身份验证标志。
$ etcdctl --user user:password get foo
密码可以从提示符中获取:
$ etcdctl --user user get foo
密码也可以从命令行标志 --password 中获取:
$ etcdctl --user user --password password get foo
否则,所有 etcdctl 命令保持不变。仍然可以创建和修改用户和角色,但需要具有根角色的用户进行身份验证。
使用 TLS 通用名称
从 v3.2 版本开始,如果 etcd 服务器启动时带有选项 --client-cert-auth=true,客户端 TLS 证书中的通用名称 (CN) 字段将用作 etcd 用户。在这种情况下,通用名称用于认证用户,客户端不需要密码。请注意,如果同时满足以下条件:1. --client-cert-auth=true 被传递且客户端提供了 CN;2. 客户端提供了用户名和密码,则基于用户名和密码的身份验证优先。请注意,此功能不能与 gRPC-proxy 和 gRPC-gateway 一起使用。这是因为 gRPC-proxy 终止了来自其客户端的 TLS,因此所有客户端共享代理的证书。gRPC-gateway 在内部使用 TLS 连接将 HTTP 请求转换为 gRPC 请求,因此也存在相同的限制。因此,客户端无法正确地向服务器提供其 CN。如果给定的证书具有非空的 CN,gRPC-proxy 将导致错误并停止。gRPC-proxy 返回一个错误,指示客户端的证书中具有非空的 CN。
关于密码强度的注意事项
etcdctl 和 etcd API 在用户创建或更新用户密码操作时不强制特定的密码长度。管理员有责任执行这些要求。为了避免与密码强度相关的安全风险,可以使用基于 TLS 通用名称的身份验证和使用 --no-password 选项创建的用户。