一.背景描述

1.漏洞描述
Redis 因配置不当存在未授权访问漏洞,可以被攻击者恶意利用。

在特定条件下,如果 Redis 以 root 身份运行,黑客可以给 root 账号写入 SSH 公钥文件(就是免密钥登陆),直接通过 SSH 登录受害服务器,从而获取服务器权限和数据。一旦入侵成功,攻击者可直接添加账号用于 SSH 远程登录控制服务器,给用户的 Redis 运行环境以及 Linux 主机带来安全风险,如删除、泄露或加密重要数据,引发勒索事件等。

2.受影响范围
在 Redis 客户端,尝试无账号登录 Redis:

root@kali:~# redis-cli -h 10.16.10.2
redis 10.16.10.2:6379> keys *
1) "1"`

从登录结果可以看出,该 Redis 服务对公网开放,且未启用认证。

二.修复方案

1.网络层加固

  • 指定 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 127.0.0.1

2.设置防火墙策略

如果正常业务中 Redis 服务需要被其他服务器来访问,可以通过 iptables 策略,仅允许指定的 IP 来访问 Redis 服务。

iptables -A INPUT -s x.x.x.x -p tcp --dport 6379 -j ACCEPT

3.账号与认证
设置访问密码

在 redis.conf 中找到 requirepass 字段,去掉其注释,并在后面填上需要的密码。Redis 客户端也需要使用此密码来访问 Redis 服务。

打开 /etc/redis/redis.conf 配置文件:

requirepass !QE%^E3323BDWEwwwe1839

确保密码的复杂度(12位及以上数字、大小字母、殊符号加标点符号),配置完毕后重启服务即可生效。

4.服务运行权限最小化

  • 修改 Redis 服务运行账号
    请以较低权限账号运行 Redis 服务,并禁用该账号的登录权限。以下操作创建了一个无 home 目录权限,且无法登录的普通账号:
useradd -M -s /sbin/nologin [username]            #无法远程登陆,只能在本地登录,仅仅作为运行redis的的用户

注意:该操作需要重启 Redis 才能生效。

5.服务精细化授权

  • 隐藏重要命令
    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 重启生效。

6.安全补丁
定期关注最新软件版本,并及时升级 Redis 到最新版,防止新漏洞被恶意利用。

保护Redis

1、指令安全

Redis的危险命令主要有:

redis强制提升为主 redis加固_Redis


禁用的具体做法是,修改服务器的配置文件redis.conf,在SECURITY这一项中,来禁用远程修改 DB 文件地址

我们新增以下命令:

rename-command FLUSHALL ""
rename-command FLUSHDB  ""
rename-command CONFIG   ""
rename-command KEYS     ""

而如果想要保留命令,但是不能轻易使用,可以重命名命令来设定:

rename-command FLUSHALL abcFLUSHALLabc
rename-command FLUSHDB  abcFLUSHDBabc
rename-command CONFIG   abcCONFIGabc
rename-command KEYS     abcKEYSabc

2、端口安全

  • 监听地址
    较新版本redis默认监听环回地址(loopback),无需修改;
    bind 127.0.0.1 ::1
  • 修改端口
    port 6380
  • 添加密码

配置文件中添加

requirepass yourpassword

命令行执行

redis 127.0.0.1:6379> config set requirepass test123
 redis 127.0.0.1:6379> config get requirepass
redis-cli -p 6379 -a test123

主从复制时从库需要设置

masterauth yourpassword

3、Lua脚本安全

Redis从2.6版本开始引入对Lua脚本的支持,通过在服务器中嵌入Lua环境,Redis客户端可以使用Lua脚本,直接在服务端原子的执行多个Redis命令。

使用脚本的好处如下:
1.减少网络开销:本来5次网络请求的操作,可以用一个请求完成,原先5次请求的逻辑放在redis服务器上完成。使用脚本,减少了网络往返时延。
2.原子操作:Redis会将整个脚本作为一个整体执行,中间不会被其他命令插入。
3.复用:客户端发送的脚本会永久存储在Redis中,意味着其他客户端可以复用这一脚本而不需要使用代码完成同样的逻辑。

正是因为Lua有强大的功能,我们更应给禁止Lua脚本由用户输入的内容(UGC)生成。

4、SSL代理

  • SSL代理
  • spiped

Redis安全防护

1.禁止使用root用户启动

使用root权限去运行网络服务是比较有风险的(nginx和apache都是有独立的work用户,而redis没有)。redis crackit 漏洞就是利用root用户的权限来替换或者增加authorized_keys,来获取root登录权限的
加固建议

useradd -s /sbin/nolog -M redis 
sudo -u redis /<redis-server-path>/redis-server /<configpath>/redis.conf

2.限制redis 配置文件访问权限

因为redis密码明文存储在配置文件中,禁止不相关的用户访问改配置文件是必要的,设置redis配置文件权限为600

#su redis       #切换到redis用户 去授权
chmod 600 /<filepath>/redis.conf

3.禁用或者重命名危险命令

Redis中线上使用keys *命令,也是非常危险的。因此线上的Redis必须考虑禁用一些危险的命令,或者尽量避免谁都可以使用这些命令,Redis没有完整的管理系统,但是也提供了一些方案。

修改 redis.conf 文件,添加

rename-command FLUSHALL ""
rename-command FLUSHDB  ""
rename-command CONFIG   ""
rename-command KEYS     ""
rename-command SHUTDOWN ""
rename-command DEL ""
rename-command EVAL ""

4.禁止监听在公网

Redis监听在0.0.0.0,可能导致服务对外或内网横向移动渗透风险,极易被黑客利用入侵。

在redis的配置文件redis.conf中配置如下: bind 127.0.0.1或者内网IP,然后重启redis

5.修改默认6379端口

编辑文件redis的配置文件redis.conf,找到包含port的行,将默认的6379修改为自定义的端口号,然后重启redis

6.打开保护模式

redis默认开启保护模式。要是配置里没有指定bind和密码,开启该参数后,redis只能本地访问,拒绝外部访问

redis.conf安全设置: # 打开保护模式 protected-mode yes

7.开启redis密码认证,并设置高复杂度密码

redis在redis.conf配置文件中,设置配置项requirepass, 开户密码认证。 redis因查询效率高,auth这种命令每秒能处理9w次以上,简单的redis的密码极容易为攻击者暴破。

打开redis.conf,找到requirepass所在的地方,修改为指定的密码,密码应符合复杂性要求:

1、长度8位以上
2、包含以下四类字符中的三类字符:
英文大写字母(A 到 Z)
英文小写字母(a 到 z)
10 个基本数字(0 到 9)
非字母字符(例如 !、$、%、@、^、&等,#除外)
3、避免使用已公开的弱密码,如:abcd.1234 、admin@123等

参考链接 :
保护Redis : https://www.jianshu.com/p/fbdfe587f5bc

Redis安全防护 : https://www.jianshu.com/p/238abacb9cdd