来源: 《etcd实战课》(极客时间) ---唐聪
目前etcd实现了两种认证机制,分别是密码认证和证书认证。
认证通过后,为了提高密码认证性能,会分配一个Token给client,client后续其他请求会携带此Token,server就可以快速完成client的身份校验。目前支持SimpleToken和JWT这两种。
通过认证后,在访问 MVCC 模块之前,还需要通过授权流程。授权的目的是检查 client 是否有权限操作你请求的数据路径,etcd 实现了 RBAC 机制,支持为每个用户分配一个角色,为每个角色授予最小化的权限。
认证
密码认证
密码存储
融合了高安全的hash函数,随机的加盐salt,可自定义的hash值计算迭代次数。
方法
在开启鉴权之前,etcd会首先要求你创建一个root账号,它拥有集群的最高读写权限。
# 添加root账号
$ etcdctl user add root:pw
User root created
$ etcdctl auth enable
Authentication Enabled
# 添加普通账号
$ etcdctl user add alice:alice_pw --user root:pw
User alice created
Token
Simple Token
核心原理是当一个用户身份验证通过后,生成一个随机的字符串值 Token 返回给 client,并在内存中使用 map 存储用户和 Token 映射关系。当收到用户的请求时, etcd 会从请求中获取 Token 值,转换成对应的用户名信息,返回给下层模块使用。
etcd 生成的每个 Token,都有一个过期时间 TTL 属性,Token 过期后 client 需再次验证身份,因此可显著缩小数据泄露的时间窗口,在性能上、安全性上实现平衡。
不过需要注意的是,Simple Token 字符串本身并未含任何有价值信息,因此 client 无法及时、准确获取到 Token 过期时间。所以 client 不容易提前去规避因 Token 失效导致的请求报错。
JWT Token
JWT 是 Json Web Token 缩写, 它是一个基于 JSON 的开放标准(RFC 7519)定义的一种紧凑、独立的格式,可用于在身份提供者和服务提供者间,传递被认证的用户身份信息。它由 Header、Payload、Signature 三个对象组成, 每个对象都是一个 JSON 结构体。
JWT Token 自带用户名、版本号、过期时间等描述信息,etcd server 不需要保存它,client 可方便、高效的获取到 Token 的过期时间、用户名等信息。它解决了 Simple Token 的若干不足之处,安全性更高,etcd 社区建议大家在生产环境若使用了密码认证,应使用 JWT Token( --auth-token 'jwt'),而不是默认的 Simple Token。
证书认证
授权
etcd基于RBAC(Role-based access control)实现权限控制
RBAC主要由三个对象组成:User、Role、Permission。User 表示用户,如 alice。Role 表示角色,它是权限的赋予对象。Permission 表示具体权限明细,比如赋予 Role 对 key 范围在[key,KeyEnd]数据拥有什么权限。目前支持三种权限,分别是 READ、WRITE、READWRITE。
比如希望给alice用户赋予[hello, helly]之间的读写权限:
# 创建admin role
$ etcdctl role add admin --user root:pw
Role admin created
# 给admin分配[hello, helly]之间的可读写权限
$ etcdctl role grant-permission admin readwrite hello helly --user root:pw
Role admin updated
# 将admin权限赋予user
$ etcdctl user grant-role alice admin --user root:pw
Role admin is granted to user alice
其实这里的role就是给某个具体的权限取的名字
因为有可能一个用户拥有成百上千个权限列表,etcd 为了提升权限检查的性能,引入了区间树,检查用户操作的 key 是否在已授权的区间,时间复杂度仅为 O(logN)。