Redis 安全

Redis 的安全模型和功能

Redis 开源版

本文档从 Redis 的角度介绍了安全主题。它涵盖了 Redis 提供的访问控制、代码安全问题、可通过恶意输入从外部触发的攻击以及其他类似主题。您可以参加 Redis 大学安全课程,了解更多关于访问控制、数据保护和加密、安全的 Redis 架构以及安全部署技术。

对于安全相关的联系事宜,请在 GitHub 上提出 issue,或者如果您认为保护通信安全非常重要,请使用本文档末尾的 GPG 密钥。

安全模型

Redis 的设计初衷是供受信任环境中的受信任客户端访问。这意味着通常情况下,直接将 Redis 实例暴露给互联网或任何不受信任客户端可以直接访问 Redis TCP 端口或 UNIX 套接字的环境不是一个好主意。

例如,在常见的 Web 应用程序上下文中使用 Redis 作为数据库、缓存或消息系统时,应用程序前端(Web 端)内的客户端将查询 Redis 以生成页面或执行由 Web 应用程序用户请求或触发的操作。

在这种情况下,Web 应用程序充当了 Redis 和不受信任客户端(访问 Web 应用程序的用户浏览器)之间的中介访问层。

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

网络安全

Redis 端口的访问应仅限于网络中的受信任客户端,因此运行 Redis 的服务器应该只能由使用 Redis 的应用程序所运行的计算机直接访问。

在直接暴露于互联网的单个计算机的常见情况下,例如虚拟化的 Linux 实例 (Linode, EC2, ...),Redis 端口应使用防火墙进行保护,以防止外部访问。客户端仍然可以使用环回接口访问 Redis。

请注意,可以通过在 redis.conf 文件中添加以下行来将 Redis 绑定到单个接口

bind 127.0.0.1

未能保护 Redis 端口免受外部访问可能会产生很大的安全影响,这是因为 Redis 的特性。例如,外部攻击者可以使用一个简单的 FLUSHALL 命令删除整个数据集。

保护模式

不幸的是,许多用户未能保护 Redis 实例免受外部网络访问。许多实例简单地暴露在互联网上,拥有公共 IP。自 3.2.0 版本以来,当 Redis 在默认配置(绑定所有接口)且没有密码访问时,会进入一个名为保护模式的特殊模式。在此模式下,Redis 只回复来自环回接口的查询,并回复来自其他地址的客户端,并返回一个解释问题以及如何正确配置 Redis 的错误。

我们预计保护模式将显著减少由于未经适当管理的非保护 Redis 实例引起的安全问题。但是,系统管理员仍然可以忽略 Redis 给出的错误,禁用保护模式或手动绑定所有接口。

身份验证

Redis 提供了两种客户端身份验证方式。推荐的身份验证方法是 ACL(访问控制列表),于 Redis 6 引入,允许创建命名用户并分配细粒度权限。请参阅 此处 了解更多关于访问控制列表的信息。

旧版身份验证方法通过编辑 redis.conf 文件启用,使用 requirepass 设置提供数据库密码。此密码随后由所有客户端使用。

启用 requirepass 设置后,Redis 将拒绝所有未经身份验证的客户端的查询。客户端可以通过发送 AUTH 命令后跟密码来进行身份验证。

系统管理员在 redis.conf 文件中以明文形式设置密码。密码应足够长,以防止暴力破解攻击,原因有二:

  • Redis 在处理查询方面非常快。外部客户端每秒可以测试多个密码。
  • Redis 密码存储在 redis.conf 文件和客户端配置中。由于系统管理员不需要记住它,密码可以非常长。

身份验证层的目的是可选地提供一层冗余。如果防火墙或任何其他旨在保护 Redis 免受外部攻击的系统失败,外部客户端仍然无法在不知道身份验证密码的情况下访问 Redis 实例。

由于 AUTH 命令与其他所有 Redis 命令一样,是未加密发送的,因此它无法防御具有足够网络访问权限进行窃听的攻击者。

TLS 支持

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

禁用特定命令

在 Redis 中可以禁用命令或将其重命名为无法猜测的名称,以便普通客户端仅限于特定的命令集。

例如,虚拟化服务器提供商可能会提供托管的 Redis 实例服务。在这种情况下,普通用户可能不应该能够调用 Redis CONFIG 命令来更改实例的配置,但提供和移除实例的系统应该能够这样做。

在这种情况下,可以将命令从命令表中重命名或完全隐藏。此功能作为一条语句提供,可以在 redis.conf 配置文件中使用。例如:

rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52

在上面的示例中,CONFIG 命令被重命名为一个无法猜测的名称。也可以将其(或任何其他命令)重命名为空字符串来完全禁用,如下例所示:

rename-command CONFIG ""

由外部客户端的恶意输入触发的攻击

即使没有对实例的外部访问权限,攻击者也可以从外部触发一类攻击。例如,攻击者可能会向 Redis 插入数据,从而触发 Redis 内部实现的数据结构的病态(最坏情况)算法复杂度。

攻击者可以通过网页表单提供一组字符串,这些字符串已知在哈希表中散列到同一个桶,以将 O(1) 预期时间(平均时间)转换为 O(N) 最坏情况。这可能会消耗超出预期的 CPU,并最终导致拒绝服务。

为了防止这种特定的攻击,Redis 对哈希函数使用每次执行的伪随机种子。

Redis 使用 qsort 算法实现 SORT 命令。目前,该算法未随机化,因此通过精心选择正确的输入集,可以触发二次方最坏情况行为。

字符串转义和 NoSQL 注入

Redis 协议没有字符串转义的概念,因此在正常情况下使用普通客户端库是不可能发生注入的。该协议使用带前缀长度的字符串,并且是完全二进制安全的。

由于由 EVALEVALSHA 命令执行的 Lua 脚本遵循相同的规则,这些命令也是安全的。

虽然这是一种奇怪的使用情况,但应用程序应避免从不受信任的来源获取字符串来构成 Lua 脚本的主体。

代码安全

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

在内部,Redis 使用所有众所周知的安全编码实践来防止缓冲区溢出、格式错误和其他内存损坏问题。但是,使用 CONFIG 命令控制服务器配置的能力允许客户端更改程序的工作目录和 dump 文件名。这允许客户端将 RDB Redis 文件写入任意路径。这 是一个安全问题,可能导致能够危害系统和/或以运行 Redis 的用户身份运行不受信任的代码。

Redis 不需要 root 权限即可运行。建议将其作为仅用于此目的的非特权 redis 用户运行。

GPG 密钥

-----BEGIN PGP PUBLIC KEY BLOCK-----

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
=J9BD
-----END PGP PUBLIC KEY BLOCK-----
评价本页
回到顶部 ↑