Redis常规安全模式
Redis 被设计成仅有可信环境下的可信用户才可以访问。这意味着将 Redis 实例直接暴露在网络上或者让不可信用户可以直接访问 Redi s的 tcp 端口或 Unix 套接字,是不安全的。
正常情况下,使用Redis的web应用程序是将Redis作为数据库,缓存,消息系统,网站的前端用户将会查询Redis来生成页面,或者执行所请求的操作,或者被web应用程序用户所触发。这种情况下,web应用程序需要对不可信的用户(访问web应用程序的用户浏览器)访问Redis进行处理。这是个特殊的例子,但是,正常情况下,对 Redis 的非法访问需要通过实现 ACLs,验证用户输入和决定 Redis 实例上可以执行哪些操作这些方式来控制。
总而言之,Redis 并没有最大地去优化安全方面,而是尽最大可能去优化高性能和易用性。
网络安全
仅有可信的网络用户才可以访问 Redis 的端口,因此运行 Redis 的服务器应该只能被用 Redis 实现的应用程序的计算机直接访问。
一般情况下一台直接暴露在 Internet 的计算机,例如一个虚拟化 Linux 实例(Linode, EC2,…),防火墙应该防止外部用户访问它的redis端口。用户仍可以通过本地接口来访问 Redis。
记住在redis.conf 文件中增加下面这一行配置就可以把 Redis 绑定在单个接口上。
bind 127.0.0.1
不禁止外部访问 Redis 的话,将会产生非常严重的后果。比如,一个 FLUSHALL 操作就可以当做外部攻击来删除 Redis 上的所有数据。
认证的特性
虽然 Redis 没有尝试去实现访问控制,但是提供了一个轻量级的认证方式,可以编辑redis.conf 文件来启用。当认证授权方式启用后,Redis 将会拒绝来自没有认证的用户的任何查询。一个客户端可以通过发送 AUTH 命令并带上密码来给自己授权。
这个密码由系统管理员在redis.conf 文件里面用明文设置,它需要足够长以应对暴力攻击,这样子设置有以下两个原因:
redis.conf
但同时密码控制也会影响到从库复制,从库必须在配置文件里使用masterauth 指令配置相应的密码才可以进行复制操作。
masterauth yoursecurepasswordhereplease
认证层的目标是提供多一层的保护。假如防火墙或者其它任何系统防护攻击失败的话,外部客户端如果没有认证密码的话将依然无法访问 Redis 实例。AUTH 命令就像其它Redis命令一样,是通过非加密方式发送的,因此无法防止拥有足够的访问网络权限的攻击者进行窃听。
数据加密支持
Redis并不支持加密。为了实现在网络上或者其它非可信网络访问 Redis 实例,需要实现新增的保护层,例如 SSL 代理。
官方推荐的SSL 代理:spiped
禁用的特殊命令
在 Redis 中可以禁用命令或者将它们重命名成难以推测的名称,这样子普通用户就只能使用部分命令了。例如,一个虚拟化的服务器提供商可能提供管理Redis实例的服务。在这种情况下,普通用户可能不被允许调用 CONFIG 命令去修改实例的配置,但是能够提供删除实例的系统需要支持修改配置。
在这种情况下,你可以从命令表中重命名命令或者禁用命令。这个特性可以在redis.conf 文件中进行配置。例如:
rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52
在上面这个例子中,CONFIG 命令被重命名成一个不好猜测的名称。把命令重命名成一个空字符串可以禁用掉该命令,例如下面这个例子:
rename-command CONFIG ""
外部客户端通过仔细构造的输入触发的攻击
即便没有外部访问权限,也有种攻击可以让攻击者从外部触发。例如一些攻击者有能力向 Redis 中插入数据,触发 Redis 内部数据结构中最差的算法复杂度,例如一个攻击者可以通过提交表单提交大量一样的字符串到哈希表里,使得 O(1) 的算法复杂度(平均时间)达到最差的O(N) ,Redis 将需要更多的CPU来处理,到最后会导致无法提供服务为了防范这类特殊的攻击,Redis 的哈希函数使用per-excution 的伪随机种子。
Redis 用qsort 算法来实现 SORT 命令。当前这个算法还不算随机的,所以通过有意构造输入可能引发最糟糕情况的算法复杂度。
字符串转义和NoSQL注入
Redis 的协议没有字符串转移的概念,因此一般情况下普通客户端无法实现注入的。该协议采用二进制安全的前缀长度字符串。通过 EVAL 和 EVALSHA 命令运行 Lua 脚本也是安全的。虽然这是个很奇怪的用法,应用程序应避免使用不明来源的字符串来写Lua 脚本。
代码安全
在传统架构的 Redis 中,客户端是可以使用全部命令的,但是访问 Redis 实例时是没有能力控制运行着 Redis 的系统的。本质上,Redis 使用一直的最好的编程方法来写安全的代码,防止出现缓存溢出,格式错误和其他内存损坏问题。但是,使用 CONFIG 命令修改服务器配置的能力使得用户可以改变程序的工作目录和备份文件的名字。这让用户可以将 RDB 文件写在任意路径,这个安全问题容易引起不受信任的代码在 Redis 上运行。
Redis 不需要 root 权限来运行,建议使用仅能运行 Redis 的用户运行。Redis 的作者正在调查给 Redis 增加一个新参数来防止 CONFIG SET/GET dir 和其它命令运行时配置指令的可能。这可以防止客户端强制要求服务器在任意位置写文件。
领取专属 10元无门槛券
私享最新 技术干货