文章目录
ACL安全策略与消息队列
ACL安全策略
1.ACL简介
在 Redis6 之前的版本,我们只能使用 requirepass 参数给 default 用户配置登录密码,同一个 redis 集群的所 有开发都共享 default 用户,难免会出现误操作把别人的 key 删掉或者数据泄露的情况。
因此 Redis6 版本推出了 ACL(Access Controller List)访问控制权限的功能,基于此功能,我们可以设置多个用 户,并且给每个用户单独设置命令权限和数据权限。为了保证向下兼容,Redis6 保留了 default 用户和使用 requirepass 的方式给 default 用户设置密码,默认情况下 default 用户拥有 Redis 最大权限,我们使用 redis-cli 连接 时如果没有指定用户名,用户也是默认 default。
在 redis.conf 和 aclfile 模式中配置 DSL 官方更推荐使用 aclfile,因为如果在 redis,conf 中配置了权限之后需要重启 redis 服务才能将配置的权限加载至 redis 服务中来;
但如果使用 aclfile 模式,可以调用 acl load 命令将 aclfile 中配置的 ACL 权限热加载进环境中,类似于 Mysql 中的 flush privileges。但同时我们也可以使用命令:config rewrite 将 acl 权限初始化到 redis.conf 中,同时执行 acl save 可以将 acl 配置持久化到 aclfile 中。
开启 aclfile 之后不再推荐在 redis.conf 文件中通过 requirepass 配置 default 的密码,因为它不再生效,同时开 启 aclfile 之后也不能使用 redis-cli -a xxx 登陆,必须使用 redis-cli --user xxx --pass yyy 来登陆。在没设置密码的时 候也可以无密码登录
2.配置 ACL
两种配置方式:
1.在 config 文件中直接配置
2.另一种是在外部 aclfile 中配置
配置的命令是一 样的,但是两种方式只能选择其中一种,我们之前使用 requirepass 给 default 用户设置密码 默认就是使用 config 的方式,执行 config rewrite 重写配置后会自动在 config 文件最下面新增一行记录配置 default 的密码和权限。
3.Redis 设置密码
1)通过修改配置文件
- 在 Redis 6.0 之前,Redis 只有一个 default 用户,也是 Redis 中的超管用户,设置密码的方式如下
# 通过修改配置文件将密码设置为123456
[root@k8s-master1 ~]# vim /usr/local/redis/bin/redis.conf
requirepass 123456
# 修改之后再次进入Redis时,发现已经没有权限操作了,因为只有一个default用户
[root@k8s-master1 ~]# redis-cli --raw
127.0.0.1:6379> set a b
NOAUTH Authentication required.
# 这个时候我们需要使用密码的方式进入
[root@k8s-master1 ~]# redis-cli -a 123456 --raw
Warning: Using a password with '-a' or '-u' option on the command line interface may
not be safe.
127.0.0.1:6379> set a b
OK
2)通过使用外部 ACL
- 可以使用原default用户acl这行DSL命令设置用户权限
- 也可以配置外部aclfile权限(配置前需将配置文件中的DSL注释或删除,因为redis不允许两种方式同时使用)
[root@k8s-master1 ~]# vim /usr/local/redis/bin/redis.conf
1.注释所有已授权的 ACL 命令,如:
#user default on #8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92~* +@all
2.注释 default 用户的密码(因为开启 aclfile 之后,requirepass 的密码就失效了)
#requirepass 123456
3.配置 aclfile 的路径,然后创建该文件,否则重启 redis 服务会报错找不到该文件
# aclfile /etc/redis/users.acl
aclfile /usr/local/redis/conf/users.acl
4.通过命令行来创建此空文件即可
mkdir /usr/local/redis/etc
touch /usr/local/redis/etc/users.aclfile
5.重启redis
systemctl restart redis
6.加载权限生效
127.0.0.1:6379> aclfile load
4.创建激活用户
on # 激活状态
off # 未激活状态
# 创建用户
127.0.0.1:6379> acl setuser Peng
OK
127.0.0.1:6379> acl list
1) "user Peng off -@all"
2) "user default on nopass ~* +@all"
# 激活用户
127.0.0.1:6379> acl setuser Peng on
OK
127.0.0.1:6379> acl list
1) "user Peng on -@all"
2) "user default on nopass ~* +@all"
5.将acl配置写入配置文件
127.0.0.1:6379> config rewrite
OK
# 查看,提交成功(末行)
[root@k8s-master1 ~]# cat /usr/local/redis/bin/redis.conf
···
"user default on nopass ~* +@all"
6.给用户增加密码
127.0.0.1:6379> acl setuser Peng >123
OK
127.0.0.1:6379> acl list
1) "user Peng off #a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3 -@all"
2) "user default on nopass ~* +@all"
7.认证
127.0.0.1:6379> auth default 123
OK
127.0.0.1:6379> acl whoami
"default"
8.将用户设置权限
命令 | 解释 |
---|---|
+[ command ] | 将命令添加到用户可以调用的命令列表中 |
-[ command ] | 将命令从用户可以调用的命令列表中移除 |
+@[ category ] | 有效类别为@admin,@set, @sortedset 等,可通过调用 ACL CAT 命令查看完整列表 |
-@[ category ] | 禁止用户调用[ category ]类别中的所有命令 |
+[ command ]|subcommand | 允许使用已禁用命令的特定子命令 |
allcommands | +@all 的别名。包括当前存在的命令以及将来通过模块加载的所有命令。 |
1)按条件创建用户
- 创建用户egon,增加:密码为123、设置访问、以 name 开头的 key、set 权限
acl setuser [username] # 若用户不存在,则按默认规则创建用户、若用户存在则该命令不做任何操作
# 创建用户
127.0.0.1:6379> acl setuser egon on >123 ~name* +set
OK
127.0.0.1:6379> acl list
1) "user egon on #a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3 ~name* -@all +set"
# 切换到egon用户
127.0.0.1:6379> auth egon 123
OK
# 查看列表无权限
127.0.0.1:6379> acl list
(error) NOPERM this user has no permissions to run the 'acl' command or its subcommand
127.0.0.1:6379>
2)提权
# 先切换到高权限用户
127.0.0.1:6379> auth Peng 123
# 提权(提权方式追加:+@list、+@ALL等,acl cat查看可加权限)
127.0.0.1:6379> acl setuser egon +@all
OK
# 切回
127.0.0.1:6379> auth egon 123
OK
# 此时已有权限查看列表
127.0.0.1:6379> acl list
1) "user Peng on #a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3 ~name* +@all"
2) "user default on nopass ~* +@all"
3) "user egon on #a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3 ~name* +@all"
9.ACL常用命令
# 展示所有的用户
127.0.0.1:6379> acl list
1) "user Peng on #a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3 ~name* +@all"
2) "user default on nopass ~* +@all"
3) "user egon on #a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3 ~name* +@all"
# 展示所有的用户
127.0.0.1:6379> acl users
1) "Peng"
2) "default"
3) "egon"
# 展示当前用户
127.0.0.1:6379> acl whoami
"Peng"
# 展示当前可授权限
127.0.0.1:6379> acl cat
1) "keyspace"
2) "read"
3) "write"
4) "set"
···
21) "scripting"
# 创建用户
127.0.0.1:6379> acl setuser Peng on >123 ~name* +set
OK
# 查看一个用户所有的key
127.0.0.1:6379> acl getuser Peng
1) "flags"
2) 1) "on"
2) "allcommands"
3) "passwords"
4) 1) "a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3"
5) "commands"
6) "+@all"
7) "keys"
8) 1) "name*"
# 删除一个用户
127.0.0.1:6379> acl deluser egon
(integer) 1
# 保存用户信息
127.0.0.1:6379> acl save
OK
# 加载用户信息
127.0.0.1:6379> acl load
OK
# 将从节点加入主节点(主从)
127.0.0.1:6381> slaveof 127.0.0.1
OK
# 查看主从状态
127.0.0.1:6381> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:6
master_sync_in_progress:0
slave_repl_offset:1334
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:56085d806ab8d1219f1434e9854683758af4d145
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1334
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:1334
127.0.0.1:6381>
消息队列
发布与订阅:相当于微信订阅号,订阅号的消息大家都能收到,表示大家都订阅了
Redis 通过 publish(发布)、subscribe(订阅) 等命令实现了订阅与发布模式,此功能提供良两种验证机制:
订阅/发布到频道
订阅/发布到模式
发布者发布信息 --> 通过频道分发给用户 <-- 用户通过频道获取订阅的内容
订阅发布到频道
publish(发布端):发布到多个频道
127.0.0.1:6379> publish test1 "aaa"
(integer) 1
127.0.0.1:6379> publish test2 "bbb"
(integer) 1
127.0.0.1:6379> publish test3 "bbb"
subscribe(订阅端1):订阅多个频道
127.0.0.1:6379> subscribe test1 test2
Reading messages... (press Ctrl-C to quit)
1) "message"
2) "test1"
3) "aaa"
1) "message"
2) "test2"
3) "bbb"
subscribe(订阅端2):订阅单个频道
Reading messages... (press Ctrl-C to quit)
1) "message"
2) "test3"
3) "bbb"