「etcd」- Password Authentication

密码认证:etcd 支持为每个用户分配一个账号名称、密码。

创建用户

通过如下命令开启鉴权:

// 注意 etcd 会先要求创建一个 root 账号,它拥有集群的最高读写权限。

$ etcdctl user add root:root
User root created

$ etcdctl auth enable
Authentication Enabled

通过鉴权模块的 user 命令,给 etcd 增加 alice 账号。我们一起来看看 etcd 鉴权模块是如何基于我上面介绍的技术方案,来安全存储 alice 账号信息。

$ etcdctl user add alice:alice --user root:root
User alice created

etcd 的用户密码存储使用高安全性 hash 函数、随机 Salt 参数、可自定义的 hash 值计算迭代次数 cost;

鉴权模块收到此命令后,它会使用 bcrpt 库的 blowfish 算法,基于明文密码、随机分配的 salt、自定义的 cost、迭代多次计算得到一个 hash 值,并将加密算法版本、salt 值、cost、hash 值组成一个字符串,作为加密后的密码。

最后,鉴权模块将用户名 alice 作为 key,用户名、加密后的密码作为 value,存储到 boltdb 的 authUsers bucket 里面,完成一个账号创建。

用户认证

当启用鉴权后,执行如下命令,etcd server 会返回 user name is empty 错误,以达到防止匿名用户访问 etcd 数据目的:

$ etcdctl put hello world
Error: etcdserver: user name is empty

etcd server 收到 put hello 请求的时候,在提交到 Raft 模块前,它会从你请求的上下文中获取你的用户身份信息。如果 Client 未通过认证,那么在状态机应用 put 命令的时候,检查身份权限的时候发现是空,就会返回此错误给 client。

当你使用 alice 账号访问 etcd 的时候,你需要先调用鉴权模块的 Authenticate 接口,它会验证你的身份合法性。

鉴权模块首先会根据你请求的用户名 alice,从 boltdb 获取加密后的密码,因此 hash 值包含了算法版本、salt、cost 等信息,因此可以根据你请求中的明文密码,计算出最终的 hash 值,若计算结果与存储一致,那么身份校验通过。

当认证通过后,为了提高密码认证性能,会分配一个 Token(类似我们生活中的门票、通信证)给 Client,后续 Client 其他请求将携带此 Token,server 就可快速完成 client 的身份校验工作;

实现分配 Token 的服务也有多种,这是 TokenProvider 所负责的,目前支持 SimpleToken 和 JWT 两种;