一、背景
Redis是一个高性能的数据库,Redis安全漏洞本质上是由于Redis自身缺乏安全防护机制,同时Redis的使用者又未曾遵循官方的安全规范所导致的。一些架构在设计之初并没有考虑到相关的安全问题,又或者设定了特定的应用环境。但大多数用户在部署及使用这些应用架构的过程中,似乎忽略了这些安全问题,那么随着使用量级的不断提升,安全风险也随之攀升。
二、基线目标
通过在系统生命周期不同阶段对目标系统展开各类安全检查,找出不符合基线定义的安全配置项并选择和实施安全措施来控制安全风险,并通过对历史数据的分析获得系统安全状态和变化趋势。
三、Redis常见漏洞特征
1、 Redis常见漏洞
Redis因配置不当可以导致未授权访问,被攻击者恶意利用。当前流行的针对Redis未授权访问的一种新型攻击方式,在特定条件下,如果Redis以root身份运行,黑客可以给root账户写入SSH公钥文件,直接通过SSH登录受害服务器,可导致服务器权限被获取和数据删除、泄露或加密勒索事件发生,严重危害业务正常服务。
一旦入侵成功,Redis数据会丢失,攻击者可直接添加账号用于ssh远程登录控制服务器,会给用户的 Redis 运行环境以及 Linux 主机造成安全风险,引发重要数据删除、泄露或加密勒索事件发生。
2、入侵特征
Redis 可能执行过 FLUSHALL命令,整个 Redis 数据库被清空;
在 Redis 数据库中新建了一个名为 crackit(网上流传的命令指令) 的键值对,内容为一个 SSH 公钥;
在 /root/.ssh 文件夹下新建或者修改了 authorized_keys 文件,内容为 Redis 生成的 db 文件,包含上述公钥,完成root权限获取。
3、满足以下条件Redis实例存在此安全隐患
Redis使用root用户启动
Redis未设置密码或密码过于简单
Redis允许任意地址连接,即bind 0.0.0.0
Redis未重命名或禁用config, flushdb/flushall,[bg]save等命令
使用默认端口6379(非强制)
四、 Redis安全规范
1、 禁止root用户启动Redis
为 Redis 服务创建单独的用户和home目录,使用普通用户启动,安全性往往高很多;业务程序永远别用root用户运行。
2、 限制redis文件目录访问权限
设置redis的主目录权限为700;如果redis配置文件独立于redis主目录,权限修改为600,因为Redis密码明文存储在配置文件中。
$chmod 600 /<filepath>/redis.conf #redis配置文件
3、开启redis密码,并设置高复杂度密码
Redis没有实现访问控制这个功能,但是它提供了一个轻量级的认证方式,可以编辑redis.conf配置来启用认证。Redis因查询效率高,auth这种命令每秒能处理10w次以上,简单的redis的密码极容易为攻击者暴破。
# requirepass foobared
打开redis.conf,找到requirepass所在的地方,修改为指定的密码,密码应符合复杂性要求。
4、 禁用或重命名危险命令
这个漏洞就利用config/save两个命令完成攻击 。 因redis无用户权限限制,建议危险的命令,使用rename配置项进行禁用或重命名,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 ""
```
然后重启redis。
重命名为"" 代表禁用命令,如想保留命令,可以重命名为不可猜测的字符串,如:
`rename-command FLUSHALL FLUSHALL_abcd`
5、 配置redis仅监听在本地地址
Redis监听在0.0.0.0,可能导致服务对外或内网横向移动渗透风险,极易被黑客利用入侵。编辑配置文件redis.conf,bind 127.0.0.1或者内网IP。
另外,也可以通过iptables或安全组做白名单限制。
6、修改默认6379端口
避免使用熟知的端口,降低被初级扫描的风险,编辑文件redis的配置文件redis.conf,找到包含port的行,将默认的6379修改为自定义的端口号。
7、打开保护模式
redis默认开启保护模式。要是配置里没有指定bind和密码,开启该参数后,redis只能本地访问,拒绝外部访问。
Redis.conf安全设置: # 打开保护模式 protected-mode yes