Redis安全——访问控制

        Redis安全

        这篇文章从Redis的角度提供了一个关于安全的介绍,包括访问控制、恶意攻击等话题。

        更多关于安全的话题请打开GitHub中的问题,或者当你严重程度的依赖安全,请使用文章最后介绍的GPG。

        Redis通用的安全模式

        Redis设计时允许被信任的客户端访问。这意味着将Redis暴露在互联网上,或者一个不被信任的客户端可以访问Redis TCP或者UNIX套接字的环境中是不好的。

       举个例子,在通常的web应用环境中,Redis被用作数据库、缓存或者消息系统,web应用前端请求Redis的数据并生成页面或者执行用户的请求。在这种情况下,web应用成为不信任前端简介访问Redis的桥梁。这是个特殊的例子,但是不信任的对象对Redis大访问应该总是被实现了ACLs的应用层引导、验证用户的输入或者确定执行在Redis上的操作。一般而言,Redis的优化是针对的是性能而不是安全。

       网络安全

       Redis端口应该拒绝除了网络中信任的客户端的访问,所以Redis服务器应该只和基于Redis开发的应用部署服务器通信。通常而言,一台单独的服务器直接暴露在互联网,应该开启防火墙保护,而客户端通过回路接口访问。

       在redis.conf中添加一行如下的配置,就可以将Redis绑定到单一的接口了。

bind  127.0.0.1

       无法保护Redis端口的安全将会造成重大的影响,这是Redis性质所决定的。比如,一个flushall可以在外部被攻击者用来删除数据库中所有的数据。

       保护模式

       遗憾的是,大多数用户被没有做好保护措施,使得Redis可以在外部被访问。有太多的Redis被简单的暴露在互联网上。鉴于此,从3.2.0版本开始,当Redis使用缺省的配置并且没有密码保护的时,我们称之为保护模式。

       在保护模式下,Redis只响应绑定ip客户端的请求,对于其他外部建立连接的的客户端都会响应错误,并且解释为什么以及引导客户正确地配置Redis。

       我们期望可以使用安全模式减少由未保护的Redis实例执行没有管理员权限的操作造成的安全问题,但是系统管理员可以忽略这些错误提示,而是禁用安全模式或者手动修改配置绑定所有的访问ip。

        验证的特点

        Redis没有实现访问控制,它提供了一个小的验证层,可以供用户选择在redis.conf中配置。一旦开启了安全验证,Redis将拒绝任何未验证客户端的请求。客户端的安全验证使用auth命令,后面跟随密码。其中的密码是配置在redis.conf中的,它应该足够长以防止暴力破解,原因如下:

       1)Redis响应请求速度非常快。大多数密码都可以在一秒钟被验证。

       2)Redis密码是存储在redis.conf中或者可以使用客户端配置,不需要系统管理员记住,所以可以足够长。

       密码验证提供了一个冗余的多重的验证,以应对防火墙或者保护措施失败后,Redis仍然可以被保护。auth命令是非加密传送的,所以并不能避免网络窃取。

       数据加密支持

       Redis是不支持加密的。为了实现信任客户端可以访问互联网或者其他的不信任的网络的设置,需要实现一个额外的保护层,如SSL协议。推荐使用spided

       禁用特殊命令

       可以禁用Redis中的命令或者重命名它为不易被猜透的名称。举个例子,假设一个虚拟机供应商需要提供对Redis的管理服务。在这种情况下,普通用户应该不能使用config命令更改虚拟机上的Redis的相关配置。但是系统本身却可以使用特殊的名利实现这些功能。

       既然这样,我们可以屏蔽掉命令表中的命令或者重命名它。这种特性可以在redis.conf文件中声明如下:

rename-command config b840fc02d524045429941cc15f59e41cb7be6c52

       在上面的例子中,config命令被重命名为一个不太可能被猜到的值。如果想要屏蔽之,只需要将它重命名为空的字符串即可:

rename-command config ""

       外部输入攻击

       有一类攻击是这样的,攻击者不需要访问Redis而只是选择合适的输入就可以实现外部攻击。这些攻击可以插入数据到Redis中,修改Redis内部数据结构的复杂逻辑。

       举个例子,攻击者可以以web的形式向Redis中的哈希表注入大量的数据,将其时间复杂度从O(1)增加到O(n),从而耗尽服务器的CPU,从而造成服务的假死。为了解决这个问题,Redis在每次执行前都生成一个随机的hash种子。

        在Redis中,sort命令使用了快速排序的逻辑。目前为止,算法不是随机的,所以在最坏情况下通过选择合适的输入实现一个平方级别的性能。

       字符串溢出Nosql注入

        Redis protocol中没有字符串溢出的概念,所以在正常情况下,使用正常的客户端类库进行注入是不可能的,protocol是二进制安全的。

      通过eval和evalsha命令执行的lua脚本遵循相同的规则,所以这些命令也同样是安全的。但是有一点是需要注意的,那就是lua脚本需要避免从不信任的来源获取的字符串生成脚本。

       代码安全

       在Redis的典型设置中,客户端允许访问所有的命令集,但是访问Redis不能控制Redis所在系统。

       在内部,Redis众所周知的实践为了保证代码安全,以防止缓冲区溢出、格式错误或者其他内存问题。但是使用命令config可以使得客户端有能力改变工作目录和转储文件的名字,这是一个严重的安全问题,它可能随意更改文件转储的位置。

       Redis不需要root权限运行。我们推荐使用普通权限的用户就是为了这个目的。Redis的作者正在研究使用一个新的配置参数保护config set/get dir和其他的运行时配置参数。  

猜你喜欢

转载自worldly.iteye.com/blog/2365063