主要是基于用户及密码的认证流程,包含用户、角色、认证相关的详细步骤,代码实现时也可与该步骤保持一致,否则很容易报错。
下文基于docker启动的etcd进行详述,如你的操作不是基于docker 的,则去掉指令前面的docker exec 容器名 直接使用etcdctl操作即可。
先查看是否开启了认证,刚开始都是默认关闭,false表示关闭:
[root@ myetcd]# docker exec my_etcd etcdctl auth status
Authentication Status: false
AuthRevision: 1
查看角色列表和用户列表,什么都没有:
[root@ myetcd]# docker exec my_etcd etcdctl role list
[root@ myetcd]# docker exec my_etcd etcdctl user list
添加root角色
[root@ myetcd]# docker exec my_etcd etcdctl role add root
Role root created
添加root用户(也可以直接user add root,不带冒号即表示使用交互式命令完成密码录入):
[root@ myetcd]# docker exec my_etcd etcdctl user add root:123
User root created
再次查看角色和用户列表:
[root@ myetcd]# docker exec my_etcd etcdctl role list
root
[root@ myetcd]# docker exec my_etcd etcdctl user list
root
给root用户赋予root角色
[root@ myetcd]# docker exec my_etcd etcdctl user grant-role root root
Role root is granted to user root
好了,开启认证看看:
[root@ myetcd]# docker exec my_etcd etcdctl auth enable
Authentication Enabled
至此,认证开启流程已完成,下文为验证其读/写用户、角色、权限等问题的详细流程。
添加一个名为rw_role1用于读写的角色
[root@ myetcd]# docker exec my_etcd etcdctl role add rw_role1
Role rw_role1 created
添加一个名为rw_user1用于读写的用户
[root@ myetcd]# docker exec my_etcd etcdctl user add rw_user1:123
User rw_user1 created
给rw_user1用户绑定rw_role1角色
[root@ myetcd]# docker exec my_etcd etcdctl user grant-role rw_user1 rw_role1
Role rw_role1 is granted to user rw_user1
给rw_role1角色赋予以 / 开头的key的 读写权限,--prefix=true是使用前缀的标识,也可不带
[root@ myetcd]# docker exec my_etcd etcdctl role grant-permission --prefix=true rw_role1 readwrite /
Role rw_role1 updated
这时候随便执行个命令:
[root@ myetcd]# docker exec my_etcd etcdctl role list?
{"level":"warn","ts":"2022-04-25T09:13:30.560Z","logger":"etcd-client","caller":"v3/retry_interceptor.go:62","msg":"retrying of unary invoker failed","target":"etcd-endpoints://0xc000420a80/127.0.0.1:2379","attempt":0,"error":"rpc error: code = InvalidArgument desc = etcdserver: user name is empty"}
Error: etcdserver: user name is empty
这是因为开启了认证后执行指令就必须带指定用户,那好,带一个用户看看:
[root@ myetcd]# docker exec my_etcd etcdctl role list --user=rw_user1:123
{"level":"warn","ts":"2022-04-25T09:13:48.835Z","logger":"etcd-client","caller":"v3/retry_interceptor.go:62","msg":"retrying of unary invoker failed","target":"etcd-endpoints://0xc000314a80/127.0.0.1:2379","attempt":0,"error":"rpc error: code = PermissionDenied desc = etcdserver: permission denied"}
Error: etcdserver: permission denied
怎么权限不够?哈哈别急,因为rw_user1的权限只针对以/为前缀的key ,其它的都没有权限,这时候使用root操作:
[root@ myetcd]# docker exec my_etcd etcdctl role list --user=root:123
root
rw_role1
[root@ myetcd]# docker exec my_etcd etcdctl user list --user=root:123
root
rw_user1
查看认证状态也一样,必须带上有权限操作该指令的用户:
[root@ myetcd]# docker exec my_etcd etcdctl auth status
{"level":"warn","ts":"2022-04-25T09:17:55.673Z","logger":"etcd-client","caller":"v3/retry_interceptor.go:62","msg":"retrying of unary invoker failed","target":"etcd-endpoints://0xc00043e700/127.0.0.1:2379","attempt":0,"error":"rpc error: code = InvalidArgument desc = etcdserver: user name is empty"}
Error: etcdserver: user name is empty
[root@ myetcd]# docker exec my_etcd etcdctl auth status --user=root:123
Authentication Status: true
AuthRevision: 8
好,现在我们用刚刚创建的读写用户写一个值:
[root@ myetcd]# docker exec my_etcd etcdctl --user=rw_user1:123 put /abc 1
OK
查看一下:
[root@ myetcd]# docker exec my_etcd etcdctl --user=rw_user1:123 get /abc
/abc
1
创建一个读角色试试
[root@ myetcd]# docker exec my_etcd etcdctl role add r_role1 --user=root:123
Role r_role1 created
给角色赋予前缀为/abc/de的key的读权限(etcd中分为三类大的权限:读、写、读写)
[root@ myetcd]# docker exec my_etcd etcdctl role grant-permission --prefix=true r_role1 read /abc/de ?--user=root:123
Role r_role1 updated
创建读用户
[root@ myetcd]# docker exec my_etcd etcdctl --user=root:123 user add r_user1:123
User r_user1 created
给r_user1用户绑定r_role1角色
[root@ myetcd]# docker exec my_etcd etcdctl user grant-role --user=root:123 r_user1 r_role1
Role r_role1 is granted to user r_user1
使用读用户读取刚创建的/abc肯定提示无权限:
[root@ myetcd]# docker exec my_etcd etcdctl --user=r_user1:123 get /abc
{"level":"warn","ts":"2022-04-25T09:22:55.510Z","logger":"etcd-client","caller":"v3/retry_interceptor.go:62","msg":"retrying of unary invoker failed","target":"etcd-endpoints://0xc000430380/127.0.0.1:2379","attempt":0,"error":"rpc error: code = PermissionDenied desc = etcdserver: permission denied"}
Error: etcdserver: permission denied
这时再创建一个key为/abc/def,value为2
[root@ myetcd]# docker exec my_etcd etcdctl --user=rw_user1:123 put /abc/def 2
OK
用r_user1读一下成功了:
[root@ myetcd]# docker exec my_etcd etcdctl --user=r_user1:123 get /abc/def
/abc/def
2
此时在它的权限范围内,因此读取成功。感觉不过瘾?再来个试试,用读写用户创建/abc/df1:
[root@ myetcd]# docker exec my_etcd etcdctl --user=rw_user1:123 put /abc/df1 3
OK
/abc/df1不在r_user1的权限范围,没权限,因此读取失败:
[root@ myetcd]# docker exec my_etcd etcdctl --user=r_user1:123 get /abc/df1
{"level":"warn","ts":"2022-04-25T09:30:19.992Z","logger":"etcd-client","caller":"v3/retry_interceptor.go:62","msg":"retrying of unary invoker failed","target":"etcd-endpoints://0xc0000de700/127.0.0.1:2379","attempt":0,"error":"rpc error: code = PermissionDenied desc = etcdserver: permission denied"}
Error: etcdserver: permission denied
可以看看指定角色的权限:
[root@ myetcd]# docker exec my_etcd etcdctl --user=root:123 role get rw_role1
Role rw_role1
KV Read:
? ? ? ? [/, 0) (prefix /)
KV Write:
? ? ? ? [/, 0) (prefix /)
读用户的:
[root@ myetcd]# docker exec my_etcd etcdctl --user=root:123 role get r_role1
Role r_role1
KV Read:
? ? ? ? [/abc/de, /abc/df) (prefix /abc/de)
KV Write:
可以看到是前闭后开区间。
想不想看看最高权限root长啥样?
[root@ myetcd]# docker exec my_etcd etcdctl --user=root:123 role get root?
Role root
KV Read:
KV Write:
答曰:nil