前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >云原生etcd基于用户角色控制权限

云原生etcd基于用户角色控制权限

原创
作者头像
聂伟星
发布2023-06-23 15:24:38
7271
发布2023-06-23 15:24:38
举报

腾讯云云原生 etcd(Cloud Service for etcd)是基于 开源 etcd 针对云原生服务场景进行优化的 etcd 托管解决方案。具体介绍说明可以参考文档/document/product/457/58176

云原生etcd默认提供2种访问,http和https的方式,https双向认证及鉴权,启用 HTTPS 的情况下,支持开启客户端证书认证。http没有鉴权,可以直接访问。

etcd还有一种访问方式,就是用户身份认证功能,但是云原生etcd没有提供这种配置方式,因为https默认就有证书认证了,不需要再额外配置认证了,所以我们这里基于http方式云原生etcd配置下身份认证,来给云原生etcd增加认证。

前提条件:

  • 腾讯云http方式访问的etcd实例
  • 配置了etcdctl的客户端机器

1. 创建root用户和角色

root用户拥有etcd的所有权限,且必须在激活身份认证之前就创建好. root用户的设计主要是出于管理的目的: 管理角色和普通用户. root用户必须具有root角色, 并且可以在etcd中进行任何修改。

代码语言:javascript
复制
# 添加root用户
# etcdctl --endpoints="http://172.16.10.41:2379" user add root
Password of root:
Type password of root again for confirmation:
User root created

# 添加root角色
# etcdctl --endpoints="http://172.16.10.41:2379" role add root
Role root created

# root角色绑定到root用户
# etcdctl --endpoints="http://172.16.10.41:2379" user grant-role root root
Role root is granted to user root

# 开启auth
# etcdctl --endpoints="http://172.16.10.41:2379" auth enable
Authentication Enabled

没有开启认证前,直接设置key是正常的

开启auth后,这里访问etcd默认就需要加认证了,不然会报错

代码语言:javascript
复制
# etcdctl --endpoints="http://172.16.10.41:2379" put c d
{"level":"warn","ts":"2023-06-23T14:31:21.660+0800","caller":"clientv3/retry_interceptor.go:62","msg":"retrying of unary invoker failed","target":"endpoint://client-11049eed-9e44-417b-bfa8-0fdf8ff23e3d/172.16.10.41:2379","attempt":0,"error":"rpc error: code = InvalidArgument desc = etcdserver: user name is empty"}
Error: etcdserver: user name is empty

访问etcd的数据,需要加上--user来认证

2. 创建用户

这里我们创建一个子用户,用来测试,创建用户时需要提供一个密码,如果使用 --interactive=false选项,支持从标准输入提供,也可以使用 --new-user-password 选项提供。

代码语言:javascript
复制
# etcdctl --endpoints="http://172.16.10.41:2379" --user root:123456  user add nwx --new-user-password 123456
User nwx created

如果用户不需要了,删除用户可以用如下命令删除。

代码语言:javascript
复制
# etcdctl --endpoints="http://172.16.10.41:2379" --user root:123456 user delete 用户名

3. 创建角色

接下来我们创建下角色,这里我们创建了3个角色,这里etcd角色可以被赋予3种权限,分别是read(读)、write(写)、readwrite(读和写)权限,这里3个角色分别对应不同的权限。

代码语言:javascript
复制
# etcdctl --endpoints="http://172.16.10.41:2379" --user root:123456  role add etcd-ro
Role etcd-ro created
# etcdctl --endpoints="http://172.16.10.41:2379" --user root:123456  role add etcd-wo
Role etcd-wo created
# etcdctl --endpoints="http://172.16.10.41:2379" --user root:123456  role add etcd-wr
Role etcd-wr created

如果角色不需要了,删除角色可以用如下命令删除。

代码语言:javascript
复制
# etcdctl --endpoints="http://172.16.10.41:2379" --user root:123456 role delete 角色名

4. 给角色授权

角色创建好之后,给角色授权下

  • etcd-ro授予读权限
  • etcd-wo授予写权限
  • etcd-wr授予读写权限

角色授权是基于具体的key的,首先我们创建2个key,分别是test1和test2来用于测试

代码语言:javascript
复制
# etcdctl --endpoints="http://172.16.10.41:2379" --user root:123456 put /test1 hello1
OK
# etcdctl --endpoints="http://172.16.10.41:2379" --user root:123456 put /test2 hello2
OK

下面我们分别给角色分配test1这个key的权限

代码语言:javascript
复制
# etcdctl --endpoints="http://172.16.10.41:2379" --user root:123456  role  grant-permission etcd-ro read /test1
Role etcd-ro updated
# etcdctl --endpoints="http://172.16.10.41:2379" --user root:123456  role  grant-permission etcd-wo write /test1
Role etcd-wo updated
# etcdctl --endpoints="http://172.16.10.41:2379" --user root:123456  role  grant-permission etcd-wr readwrite /test1
Role etcd-wr updated

上面是设置单个key,如果要设置多个key,可以参考grant-permission的用法说明

代码语言:javascript
复制
# etcdctl role grant-permission --help
NAME:
        role grant-permission - Grants a key to a role
USAGE:
        etcdctl role grant-permission [options] <role name> <permission type> <key> [endkey] [flags]
OPTIONS:
      --from-key[=false]        grant a permission of keys that are greater than or equal to the given key using byte compare
  -h, --help[=false]            help for grant-permission
      --prefix[=false]          grant a prefix permission

# 给以/foo/开头的所有key赋予读权限. The prefix is equal to the range [/foo/, /foo0)
etcdctl role grant-permission 角色名 --prefix=true read /foo/

# 给[key1, key5) 范围内的所有key赋予所有权限 
etcdctl role grant-permission 角色名 readwrite key1 key5

# 赋予以/pub/可有的key所有权限
etcdctl role grant-permission 角色名 --prefix=true readwrite /pub/

如果需要给角色删除权限,可以用如下命令删除

代码语言:javascript
复制
# etcdctl --endpoints="http://172.16.10.41:2379" --user root:123456 role revoke-permission 角色名 key

5. 给用户绑定角色测试权限

用户和角色都创建好了,我们给第一步创建的用户nwx绑定具体的角色来测试下权限是否生效。

给用户绑定和解除角色的命令如下

代码语言:javascript
复制
为用户添加角色
etcdctl user grant-role 用户名 角色名

为用户删除角色
etcdctl user revoke-role 用户名 角色名

5.1 用户绑定读权限的角色

这里首先给nwx绑定下etcd-ro角色,因为etcd-ro默认是分配的读权限

代码语言:javascript
复制
# etcdctl --endpoints="http://172.16.10.41:2379" --user root:123456  user grant-role nwx etcd-ro
Role etcd-ro is granted to user nwx
# etcdctl --endpoints="http://172.16.10.41:2379" --user root:123456  user get nwx
User: nwx
Roles: etcd-ro

然后我们测试下访问test1和test2这2个key试试,正常只能读test1这个key,其他key权限都没有

代码语言:javascript
复制
# etcdctl --endpoints="http://172.16.10.41:2379" --user nwx:123456 get /test1
/test1
hello1
# etcdctl --endpoints="http://172.16.10.41:2379" --user nwx:123456 put /test1 hello1-1
{"level":"warn","ts":"2023-06-23T14:56:21.693+0800","caller":"clientv3/retry_interceptor.go:62","msg":"retrying of unary invoker failed","target":"endpoint://client-8d09a8b1-1a12-41f7-be25-aecc4909adba/172.16.10.41:2379","attempt":0,"error":"rpc error: code = PermissionDenied desc = etcdserver: permission denied"}
Error: etcdserver: permission denied
# etcdctl --endpoints="http://172.16.10.41:2379" --user nwx:123456 get /test2
{"level":"warn","ts":"2023-06-23T14:56:33.235+0800","caller":"clientv3/retry_interceptor.go:62","msg":"retrying of unary invoker failed","target":"endpoint://client-47eb949b-240d-4e9c-9179-b540c7e99732/172.16.10.41:2379","attempt":0,"error":"rpc error: code = PermissionDenied desc = etcdserver: permission denied"}
Error: etcdserver: permission denied
# etcdctl --endpoints="http://172.16.10.41:2379" --user nwx:123456 put /test2 hello2-1
{"level":"warn","ts":"2023-06-23T14:56:47.108+0800","caller":"clientv3/retry_interceptor.go:62","msg":"retrying of unary invoker failed","target":"endpoint://client-255ca16f-47bc-4ded-ba79-0f6ede414778/172.16.10.41:2379","attempt":0,"error":"rpc error: code = PermissionDenied desc = etcdserver: permission denied"}
Error: etcdserver: permission denied

从测试结果看是符合角色权限设置预期的,只能读test1这个key。

5.2 用户绑定写权限的角色

这里继续测试下写权限的角色,我么给nwx绑定下etcd-wo角色,因为etcd-wo默认是分配的写权限,需要将etcd-ro的角色解绑掉,避免影响测试结果。

代码语言:javascript
复制
# etcdctl --endpoints="http://172.16.10.41:2379" --user root:123456  user grant-role nwx etcd-wo
Role etcd-wo is granted to user nwx
# etcdctl --endpoints="http://172.16.10.41:2379" --user root:123456  user revoke-role nwx etcd-ro
Role etcd-ro is revoked from user nwx
# etcdctl --endpoints="http://172.16.10.41:2379" --user root:123456  user get nwx
User: nwx
Roles: etcd-wo

然后我们测试下访问test1和test2这2个key试试,正常只能写test1这个key,其他key权限都没有。

代码语言:javascript
复制
# etcdctl --endpoints="http://172.16.10.41:2379" --user nwx:123456 get /test1
{"level":"warn","ts":"2023-06-23T15:03:43.460+0800","caller":"clientv3/retry_interceptor.go:62","msg":"retrying of unary invoker failed","target":"endpoint://client-353c2a2e-7f00-4412-b373-17bb98968f41/172.16.10.41:2379","attempt":0,"error":"rpc error: code = PermissionDenied desc = etcdserver: permission denied"}
Error: etcdserver: permission denied
# etcdctl --endpoints="http://172.16.10.41:2379" --user nwx:123456 put /test1 hello1-1
OK
# etcdctl --endpoints="http://172.16.10.41:2379" --user nwx:123456 get /test2
{"level":"warn","ts":"2023-06-23T15:04:02.877+0800","caller":"clientv3/retry_interceptor.go:62","msg":"retrying of unary invoker failed","target":"endpoint://client-2044c10e-d752-4a3e-b40f-cffb29fe405d/172.16.10.41:2379","attempt":0,"error":"rpc error: code = PermissionDenied desc = etcdserver: permission denied"}
Error: etcdserver: permission denied
# etcdctl --endpoints="http://172.16.10.41:2379" --user nwx:123456 put /test2 hello2-1
{"level":"warn","ts":"2023-06-23T15:04:15.619+0800","caller":"clientv3/retry_interceptor.go:62","msg":"retrying of unary invoker failed","target":"endpoint://client-6a99f67d-b243-4d49-ac70-13b2dca8d0b5/172.16.10.41:2379","attempt":0,"error":"rpc error: code = PermissionDenied desc = etcdserver: permission denied"}
Error: etcdserver: permission denied

从测试结果看是符合角色权限设置预期的,只能写test1这个key。

5.3 用户绑定读写权限的角色

这里测试下读写权限的角色,我么给nwx绑定下etcd-wr角色,因为etcd-wr默认是分配的读写权限,需要将etcd-wo的角色解绑掉,避免影响测试结果。

代码语言:javascript
复制
# etcdctl --endpoints="http://172.16.10.41:2379" --user root:123456  user revoke-role nwx etcd-wo
Role etcd-wo is revoked from user nwx
# etcdctl --endpoints="http://172.16.10.41:2379" --user root:123456  user grant-role nwx etcd-wr
Role etcd-wr is granted to user nwx
# etcdctl --endpoints="http://172.16.10.41:2379" --user root:123456  user get nwx
User: nwx
Roles: etcd-wr

然后我们测试下访问test1和test2这2个key试试,正常只能读写test1这个key,其他key的权限都没有。

代码语言:javascript
复制
# etcdctl --endpoints="http://172.16.10.41:2379" --user nwx:123456 get /test1
/test1
hello1-1
# etcdctl --endpoints="http://172.16.10.41:2379" --user nwx:123456 put /test1 hello1
OK
# etcdctl --endpoints="http://172.16.10.41:2379" --user nwx:123456 get /test2
{"level":"warn","ts":"2023-06-23T15:08:54.681+0800","caller":"clientv3/retry_interceptor.go:62","msg":"retrying of unary invoker failed","target":"endpoint://client-9da01b24-df4e-4d5c-bebb-37de9d9571e7/172.16.10.41:2379","attempt":0,"error":"rpc error: code = PermissionDenied desc = etcdserver: permission denied"}
Error: etcdserver: permission denied
# etcdctl --endpoints="http://172.16.10.41:2379" --user nwx:123456 put /test2 hello2-1
{"level":"warn","ts":"2023-06-23T15:09:03.869+0800","caller":"clientv3/retry_interceptor.go:62","msg":"retrying of unary invoker failed","target":"endpoint://client-c2691c6e-39d6-4686-83f2-cf1b09d8e3b1/172.16.10.41:2379","attempt":0,"error":"rpc error: code = PermissionDenied desc = etcdserver: permission denied"}
Error: etcdserver: permission denied

从测试结果看是符合角色权限设置预期的,可以读写test1这个key,其他key的权限都没,并且这里查看test1的值是hello1-1,也验证了上一步的测试,给分配读权限是正常的。

上面就是如何通过用户和角色来控制权限,通过用户和角色可以更加灵活的来控制etcd里面的数据访问。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 创建root用户和角色
  • 2. 创建用户
  • 3. 创建角色
  • 4. 给角色授权
  • 5. 给用户绑定角色测试权限
    • 5.1 用户绑定读权限的角色
      • 5.2 用户绑定写权限的角色
        • 5.3 用户绑定读写权限的角色
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
        http://www.vxiaotou.com