*Redis 安全指南

本文从 Redis 的角度介绍安全主题,涵盖访问控制、代码安全问题、外部恶意输入触发的攻击等。

*安全模型

Redis 设计为在可信环境中由可信客户端访问。通常不建议将 Redis 实例直接暴露在互联网上,或暴露给不可信客户端可以直接访问 Redis TCP 端口或 UNIX 套接字的环境。

例如,在使用 Redis 作为数据库、缓存或消息系统的 Web 应用中,前端(Web 端)的客户端会查询 Redis 来生成页面或执行操作。在这种情况下,Web 应用充当 Redis 和不可信客户端(用户浏览器)之间的中介。

不可信访问 Redis 应始终由实现 ACL、验证用户输入并决定针对 Redis 实例执行哪些操作的层来中介。

*网络安全

除可信客户端外,应拒绝所有人访问 Redis 端口。运行 Redis 的服务器应仅由使用 Redis 的应用程序计算机直接访问。

在直接暴露于互联网的常见情况下(如虚拟化 Linux 实例),应使用防火墙阻止外部访问 Redis 端口。客户端仍可使用回环接口访问 Redis。

可以在 redis.conf 中添加以下行将 Redis 绑定到单个接口:

bind 127.0.0.1

未能保护 Redis 端口可能产生重大安全影响。例如,单个 FLUSHALL 命令即可被外部攻击者用来删除整个数据集。

*保护模式(Protected Mode)

许多用户未能保护 Redis 实例免受外部网络访问。自 3.2.0 版本起,当 Redis 以默认配置执行(绑定所有接口)且未设置密码时,会进入保护模式。在此模式下,Redis 仅回复来自回环接口的查询,对其他地址的连接返回错误并解释如何正确配置 Redis。

*认证

Redis 提供两种客户端认证方式:

*推荐方式:访问控制列表(ACL)

Redis 6 引入的推荐认证方法。允许创建命名用户并分配细粒度权限。

*传统方式:密码认证

redis.conf 中通过 requirepass 设置数据库密码。启用后,Redis 将拒绝未经认证客户端的所有查询。客户端可通过发送 AUTH 命令加密码进行认证。

密码应足够长以防止暴力破解,因为:

  • Redis 查询速度非常快,外部客户端每秒可测试大量密码
  • 密码存储在 redis.conf 和客户端配置中,管理员无需记住,因此可以设置非常长的密码

由于 AUTH 命令像其他 Redis 命令一样以未加密方式发送,它无法防御能够进行网络窃听的攻击者。

*TLS 支持

Redis 在所有通信通道上可选支持 TLS,包括客户端连接、复制链接和 Redis Cluster 总线协议。

*禁用特定命令

警告:此方法已弃用,未来版本可能移除。请改用 ACL 规则。

可以在 Redis 中禁用命令或将其重命名为不可猜测的名称。例如:

rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52

或完全禁用:

rename-command CONFIG ""

*外部恶意输入触发的攻击

攻击者可能插入触发 Redis 内部数据结构最坏情况算法复杂度的数据。例如,提供一组已知会哈希到同一桶的字符串,将 O(1) 预期时间变为 O(N) 最坏情况。

为防止此攻击,Redis 使用每次执行伪随机种子到哈希函数。

*字符串转义和 NoSQL 注入

Redis 协议没有字符串转义概念,因此使用正常客户端库时不可能发生注入。协议使用前缀长度字符串,完全二进制安全。

*代码安全

在经典 Redis 设置中,客户端允许完全访问命令集,但访问实例不应导致控制运行 Redis 的系统的能力。

Redis 内部使用所有已知的安全编码实践来防止缓冲区溢出、格式错误和其他内存损坏问题。但使用 CONFIG 命令控制服务器配置的能力允许客户端更改程序工作目录和转储文件名,从而允许客户端将 RDB 文件写入随机路径。

Redis 不需要 root 权限运行。建议以仅用于此目的的特权受限的 redis 用户运行。

*其他安全主题

  • ACL:Redis 访问控制列表
  • TLS:Redis TLS 支持