遇到的问题:
今天运行Redis时发生错误,错误信息如下:
(error) MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled. Please check Redis logs for details about the error.
Redis被配置为保存数据库快照,但它目前不能持久化到硬盘。用来修改集合数据的命令不能用。请查看Redis日志的详细错误信息。
原因:
强制关闭Redis快照导致不能持久化。
解决方案:
运行config set stop-writes-on-bgsave-error no 命令后,关闭配置项stop-writes-on-bgsave-error解决该问题。
root@ubuntu:/usr/local/redis/bin# ./redis-cli
127.0.0.1:6379> config set stop-writes-on-bgsave-error no
OK
redis-cli -h 123.123.123.123 keys "123*" | xargs redis-cli del 批量删除
附录:
redis 处理数据命令:
Redis 列表命令
下表列出了列表相关的基本命令:
序号 | 命令及描述 |
---|---|
1 | BLPOP key1 [key2 ] timeout 移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。 |
2 | BRPOP key1 [key2 ] timeout 移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。 |
3 | BRPOPLPUSH source destination timeout 从列表中弹出一个值,将弹出的元素插入到另外一个列表中并返回它; 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。 |
4 | LINDEX key index 通过索引获取列表中的元素 |
5 | LINSERT key BEFORE|AFTER pivot value 在列表的元素前或者后插入元素 |
6 | LLEN key 获取列表长度 |
7 | LPOP key 移出并获取列表的第一个元素 |
8 | LPUSH key value1 [value2] 将一个或多个值插入到列表头部 |
9 | LPUSHX key value 将一个值插入到已存在的列表头部 |
10 | LRANGE key start stop 获取列表指定范围内的元素 |
11 | LREM key count value 移除列表元素 |
12 | LSET key index value 通过索引设置列表元素的值 |
13 | LTRIM key start stop 对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。 |
14 | RPOP key 移除列表的最后一个元素,返回值为移除的元素。 |
15 | RPOPLPUSH source destination 移除列表的最后一个元素,并将该元素添加到另一个列表并返回 |
16 | RPUSH key value1 [value2] 在列表中添加一个或多个值 |
17 | RPUSHX key value 为已存在的列表添加值 |
下表列出了 redis hash 基本的相关命令:
序号 | 命令及描述 |
---|---|
1 | HDEL key field1 [field2] 删除一个或多个哈希表字段 |
2 | HEXISTS key field 查看哈希表 key 中,指定的字段是否存在。 |
3 | HGET key field 获取存储在哈希表中指定字段的值。 |
4 | HGETALL key 获取在哈希表中指定 key 的所有字段和值 |
5 | HINCRBY key field increment 为哈希表 key 中的指定字段的整数值加上增量 increment 。 |
6 | HINCRBYFLOAT key field increment 为哈希表 key 中的指定字段的浮点数值加上增量 increment 。 |
7 | HKEYS key 获取所有哈希表中的字段 |
8 | HLEN key 获取哈希表中字段的数量 |
9 | HMGET key field1 [field2] 获取所有给定字段的值 |
10 | HMSET key field1 value1 [field2 value2 ] 同时将多个 field-value (域-值)对设置到哈希表 key 中。 |
11 | HSET key field value 将哈希表 key 中的字段 field 的值设为 value 。 |
12 | HSETNX key field value 只有在字段 field 不存在时,设置哈希表字段的值。 |
13 | HVALS key 获取哈希表中所有值 |
14 | HSCAN key cursor [MATCH pattern] [COUNT count] 迭代哈希表中的键值对。 |
下表列出了 redis 有序集合的基本命令:
下表列出了 redis 发布订阅常用命令:
序号 | 命令及描述 |
---|---|
1 | PSUBSCRIBE pattern [pattern ...] 订阅一个或多个符合给定模式的频道。 |
2 | PUBSUB subcommand [argument [argument ...]] 查看订阅与发布系统状态。 |
3 | PUBLISH channel message 将信息发送到指定的频道。 |
4 | PUNSUBSCRIBE [pattern [pattern ...]] 退订所有给定模式的频道。 |
5 | SUBSCRIBE channel [channel ...] 订阅给定的一个或多个频道的信息。 |
6 | UNSUBSCRIBE [channel [channel ...]] 指退订给定的频道。 |
Redis 事务可以一次执行多个命令, 并且带有以下三个重要的保证:
- 批量操作在发送 EXEC 命令前被放入队列缓存。
- 收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行。
- 在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中。
下表列出了 redis 事务的相关命令:
序号 | 命令及描述 |
---|---|
1 | DISCARD 取消事务,放弃执行事务块内的所有命令。 |
2 | EXEC 执行所有事务块内的命令。 |
3 | MULTI 标记一个事务块的开始。 |
4 | UNWATCH 取消 WATCH 命令对所有 key 的监视。 |
5 | WATCH key [key ...] 监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。 |
附录2:
redis加固:
Redis 因配置不当存在未授权访问漏洞,可以被攻击者恶意利用。
在特定条件下,如果 Redis 以 root 身份运行,黑客可以给 root 账号写入 SSH 公钥文件,直接通过 SSH 登录受害服务器,从而获取服务器权限和数据。一旦入侵成功,攻击者可直接添加账号用于 SSH 远程登录控制服务器,给用户的 Redis 运行环境以及 Linux 主机带来安全风险,如删除、泄露或加密重要数据,引发勒索事件等。
在 Redis 客户端,尝试无账号登录 Redis:
root@kali:~# redis-cli -h 10.16.10.2
redis 10.16.10.2:6379> keys *
1) "1"`
从登录结果可以看出,该 Redis 服务对公网开放,且未启用认证。
二.修复方案
-
指定 Redis 服务使用的网卡
默认情况下,Redis 监听
127.0.0.1
。如果仅仅是本地通信,请确保监听在本地。这种方式可以在一定程度上缓解 Redis 未授权访问的风险(例外情况下,如果 Redis 以 root 用户运行,攻击者借助已有的 webshell,就可以利用该 Redis 来反弹 shell 以实现提权)。
在
redis.conf
文件中找到# bind 127.0.0.1
,将前面的#
去掉,然后保存。注意:
- 该操作需要重启 Redis 才能生效。
- 修改后只有本机才能访问 Redis,也可以指定访问源 IP 来访问 Redis。
bind 192.168.1.100 10.0.0.1
-
2.设置防火墙策略
如果正常业务中 Redis 服务需要被其他服务器来访问,可以通过 iptables 策略,仅允许指定的 IP 来访问 Redis 服务。
iptables -A INPUT -s x.x.x.x -p tcp --dport 6379 -j ACCEPT
-
设置访问密码
在
redis.conf
中找到requirepass
字段,去掉其注释,并在后面填上需要的密码。Redis 客户端也需要使用此密码来访问 Redis 服务。打开
/etc/redis/redis.conf
配置文件:requirepass !QE%^E3323BDWEwwwe1839
确保密码的复杂度,配置完毕后重启服务即可生效。
-
修改 Redis 服务运行账号
请以较低权限账号运行 Redis 服务,并禁用该账号的登录权限。以下操作创建了一个无 home 目录权限,且无法登录的普通账号:
useradd -M -s /sbin/nologin [username]
注意:该操作需要重启 Redis 才能生效。
-
隐藏重要命令
Redis 无权限分离,其管理员账号和普通账号无明显区分。攻击者登录后可执行任意操作,因此需要隐藏以下重要命令:
FLUSHDB, FLUSHALL, KEYS,PEXPIRE, DEL, CONFIG, SHUTDOWN, BGREWRITEAOF, BGSAVE, SAVE, SPOP, SREM, RENAME,DEBUG, EVAL
。另外,在 Redis 2.8.1 及 Redis 3.x (低于 3.0.2) 版本下存在 EVAL 沙箱逃逸漏洞,攻击者可通过该漏洞执行任意 Lua 代码。
下述配置将
config/flushdb/flushall
设置为空,即禁用该命令;也可设置为一些复杂的、难以猜测的名字。rename-command CONFIG ""
rename-command flushall ""
rename-command flushdb ""
rename-command shutdown shotdown_test
保存后,执行
/etc/init.d/redis-server restart
重启生效。
定期关注最新软件版本,并及时升级 Redis 到最新版,防止新漏洞被恶意利用。
批量删除
redis-cli -h 10.10.5.6 keys "123*" | xargs redis-cli del 批量删除