系列教程导航

  1. 如何在 Ubuntu 18.04 上安装和保护 Redis
  2. 如何连接到 Redis 数据库
  3. 如何管理 Redis 数据库和 Keys
  4. 如何在 Redis 中管理副本和客户端
  5. 如何在 Redis 中管理字符串
  6. 如何在 Redis 中管理 list
  7. 如何在 Redis 中管理 Hashes
  8. 如何在 Redis 中管理 Sets
  9. 如何在 Redis 中管理 Sorted Sets
  10. 如何在 Redis 中运行事务
  11. 如何使 Redis 中的 Key 失效
  12. 如何解决 Redis 中的故障
  13. 如何从命令行更改 Redis 的配置
  14. Redis 数据类型简介

简介

Redis 是一款知名的内存键值存储系统(In-Memory Key-Value Store),以其灵活性、高性能和广泛的语言支持而著称。本教程将演示如何在 Ubuntu 18.04 服务器上安装、配置和保护 Redis。

先决条件

要完成本指南,您需要满足以下条件:

  • 访问一台 Ubuntu 18.04 服务器。
  • 拥有一个具有 sudo 权限的非 root 用户。
  • 配置了基本防火墙。

您可以按照我们的 初始服务器安装指南 进行设置。

准备就绪后,请以 sudo 用户身份登录到 Ubuntu 18.04 服务器,然后继续后续步骤。

第 1 步:安装和配置 Redis

为了获得适用于 Ubuntu 存储库的稳定版本,我们将使用 apt 包管理器进行安装。

首先,更新本地包缓存并安装 Redis:

sudo apt update
sudo apt install redis-server

这将下载并安装 Redis 及其依赖项。安装完成后,我们需要对自动生成的 Redis 配置文件进行一项重要的更改。

使用您喜欢的文本编辑器打开配置文件:

sudo nano /etc/redis/redis.conf

在文件内部,找到 supervised 指令。该指令允许您声明一个初始化系统来将 Redis 作为服务进行管理,从而为您提供对其操作的更多控制。默认情况下,该指令设置为 no。由于您正在运行使用 systemd 初始化系统的 Ubuntu,请将其更改为 systemd

# /etc/redis/redis.conf

# If you run Redis from upstart or systemd, Redis can interact with your
# supervision tree. Options:
#   supervised no      - no supervision interaction
#   supervised upstart - signal upstart by putting Redis into SIGSTOP mode
#   supervised systemd - signal systemd by writing READY=1 to $NOTIFY_SOCKET
#   supervised auto    - detect upstart or systemd method based on
#                        UPSTART_JOB or NOTIFY_SOCKET environment variables
# Note: these supervision methods only signal "process is ready."
#       They do not enable continuous liveness pings back to your supervisor.
supervised systemd

这是目前唯一需要对 Redis 配置文件进行的更改。完成后保存并关闭文件。然后,重新启动 Redis 服务以应用配置更改:

sudo systemctl restart redis.service

至此,您已经安装并配置了 Redis,且服务正在运行。但在开始使用之前,建议先检查 Redis 是否运行正常。

第 2 步:测试 Redis

与任何新安装的软件一样,在进行进一步配置更改之前,最好确保 Redis 能够按预期运行。我们将通过几种方法来检查 Redis 在此步骤中是否正常工作。

首先,检查 Redis 服务状态:

sudo systemctl status redis

如果它正在运行且无错误,命令将输出类似于以下内容的信息:

● redis-server.service - Advanced key-value store
   Loaded: loaded (/lib/systemd/system/redis-server.service; enabled; vendor preset: enabled)
   Active: active (running) since Wed 2018-06-27 18:48:52 UTC; 12s ago
     Docs: http://redis.io/documentation,
           man:redis-server(1)
  Process: 2421 ExecStop=/bin/kill -s TERM $MAINPID (code=exited, status=0/SUCCESS)
  Process: 2424 ExecStart=/usr/bin/redis-server /etc/redis/redis.conf (code=exited, status=0/SUCCESS)
 Main PID: 2445 (redis-server)
    Tasks: 4 (limit: 4704)
   CGroup: /system.slice/redis-server.service
           └─2445 /usr/bin/redis-server 127.0.0.1:6379

输出显示 Redis 正在运行且已启用(enabled),这意味着它被设置为在服务器每次启动时自动启动。

注意: 对于许多常见用例,此设置是理想的。但是,如果您希望每次服务器启动时手动启动 Redis,可以使用以下命令禁用自动启动:

sudo systemctl disable redis

接下来,使用命令行客户端连接到服务器以测试功能:

redis-cli

在随后的提示符中,使用 ping 命令测试连接性:

ping
PONG

此输出确认服务器连接有效。接下来,检查是否可以通过运行以下命令设置密钥(Key):

set test "It's working!"
OK

通过键入以下内容来检索值:

get test

假设一切正常,您将能够检索存储的值:

"It's working!"

确认可以获取该值后,退出 Redis 提示符以返回 Shell:

exit

作为最终测试,我们将检查 Redis 即使在停止或重新启动后也能够持久保存数据。为此,请首先重新启动 Redis 实例:

sudo systemctl restart redis

然后再次与命令行客户端连接,并确认您的测试值仍然可用:

redis-cli
get test

您的密钥值仍应可访问:

"It's working!"

完成后再次退出:

exit

这样,您的 Redis 安装就可以完全运行并使用了。但是,其某些默认配置设置是不安全的,可能为恶意行为者提供攻击服务器及数据的机会。本教程的其余步骤介绍了 Redis 官方网站 所规定的缓解这些漏洞的方法。尽管这些步骤是可选的(如果不遵循,Redis 仍将工作),但强烈建议您完成这些步骤以增强系统安全性。

第 3 步:绑定到本地主机

默认情况下,Redis 仅能从 localhost 访问。但是,如果您通过遵循与本教程不同的指南安装和配置 Redis,可能已更新了配置文件以允许从任何地方连接。这不如绑定到 localhost 安全。

要更正此问题,请打开 Redis 配置文件进行编辑:

sudo nano /etc/redis/redis.conf

找到以下行,并确保其未注释(如果存在 # 请删除):

# /etc/redis/redis.conf
bind 127.0.0.1 ::1

保存并关闭文件(按 CTRL + X,然后按 Y 确认,最后按 ENTER)。

然后,重新启动服务以确保 systemd 读取您的更改:

sudo systemctl restart redis

要检查此更改是否已生效,请运行以下 netstat 命令:

sudo netstat -lnp | grep redis

输出应显示 redis-server 程序已绑定到 localhost127.0.0.1):

tcp        0      0 127.0.0.1:6379          0.0.0.0:*               LISTEN      14222/redis-server  
tcp6       0      0 ::1:6379                :::*                    LISTEN      14222/redis-server  

如果您在该列中看到另一个 IP 地址(例如 0.0.0.0),则应再次检查是否取消了正确的行注释,然后重新启动 Redis 服务。

现在,您的 Redis 安装仅在 localhost 上监听,恶意行为者更难发出请求或访问您的服务器。但是,Redis 当前未设置为要求用户在更改配置或数据之前进行身份验证。为了解决这个问题,Redis 允许您要求用户通过密码进行身份验证,然后才能通过 Redis 客户端(redis-cli)进行更改。

第 4 步:配置 Redis 密码

配置 Redis 密码可启用其内置安全功能之一 —— auth 命令,该命令要求客户端进行身份验证才能访问数据库。密码直接在 Redis 配置文件 /etc/redis/redis.conf 中配置,因此请再次使用编辑器打开该文件:

sudo nano /etc/redis/redis.conf

滚动到 SECURITY 部分,查找带有以下注释的指令:

# /etc/redis/redis.conf
# requirepass foobared

通过删除 # 取消注释,然后将 foobared 更改为安全密码。

注意: requirepass 指令上方有一条注释警告:

# Warning: since Redis is pretty fast an outside user can try up to
# 150k passwords per second against a good box. This means that you should
# use a very strong password otherwise it will be very easy to break.

因此,指定一个非常强且很长的值作为密码至关重要。您可以使用 openssl 命令生成随机密码,而无需自己编写。通过将第一个命令的输出传递到第二个 openssl 命令,如下所示,它将删除由第一个命令产生的任何换行符:

openssl rand 60 | openssl base64 -A

您的输出应类似于:

RBOJ9cCNoGCKhlEBwQLHri1g+atWgn4Xn4HwNUbtzoVxAYxkiYBi7aufl4MILv1nxBqR4L6NNzI0X6cE

将命令的输出复制并粘贴为 requirepass 的新值,它应显示为:

# /etc/redis/redis.conf
requirepass RBOJ9cCNoGCKhlEBwQLHri1g+atWgn4Xn4HwNUbtzoVxAYxkiYBi7aufl4MILv1nxBqR4L6NNzI0X6cE

设置密码后,保存并关闭文件,然后重新启动 Redis:

sudo systemctl restart redis.service

要测试密码是否有效,请访问 Redis 命令行:

redis-cli

以下显示了用于测试 Redis 密码是否有效的命令序列。第一条命令尝试在验证之前将密钥设置为一个值:

set key1 10
(error) NOAUTH Authentication required.

由于您未进行身份验证,无法使用,因此 Redis 返回错误。下一条命令使用 Redis 配置文件中指定的密码进行身份验证:

auth your_redis_password
OK

Redis 确认认证通过。之后,再次运行前面的命令将成功:

set key1 10
OK

向 Redis 查询新密钥的值:

get key1
10

确认身份验证后可以在 Redis 客户端中运行命令后,您可以退出 redis-cli

quit

接下来,我们将研究重命名 Redis 命令,以防错误或由恶意参与者输入 Redis 命令严重损坏您的计算机。

第 5 步:重命名危险命令

Redis 内置的另一个安全功能涉及重命名或完全禁用某些被认为是危险的命令。

当由未经授权的用户运行时,此类命令可用于重新配置、破坏或擦除您的数据。与身份验证密码一样,重命名或禁用命令也在 /etc/redis/redis.conf 文件的 SECURITY 部分中配置。

一些被认为是危险的命令包括:FLUSHDBFLUSHALLKEYSPEXPIREDELCONFIGSHUTDOWNBGREWRITEAOFBGSAVESAVESPOPSREMRENAMEDEBUG。这不是一个完整的列表,但是重命名或禁用该列表中的所有命令是增强 Redis 服务器安全性的一个很好的起点。

是否应禁用或重命名命令取决于您的特定需求。如果您知道永远不会使用可能会被滥用的命令,则可以将其禁用。否则,重命名可能是更好的选择。

要启用或禁用 Redis 命令,请再次打开配置文件:

sudo nano /etc/redis/redis.conf
警告: 以下显示如何禁用和重命名命令的步骤是示例。您应该只选择禁用或重命名对您有意义的命令。您可以自己查看命令的完整列表,并在 redis.io/commands 中确定如何滥用它们。

要禁用命令,只需将其重命名为一个空字符串(由一对引号引起,它们之间没有字符),如下所示:

# /etc/redis/redis.conf
# It is also possible to completely kill a command by renaming it into
# an empty string:
rename-command FLUSHDB ""
rename-command FLUSHALL ""
rename-command DEBUG ""

要重命名命令,请给其另一个名称,如下面的示例所示。重命名的命令应该使其他人难以猜到,但容易记住:

# /etc/redis/redis.conf
# rename-command CONFIG ""
rename-command SHUTDOWN SHUTDOWN_MENOT
rename-command CONFIG ASC12_CONFIG

保存您的更改并关闭文件。重命名命令后,通过重新启动 Redis 来应用更改:

sudo systemctl restart redis.service

要测试新命令,请输入 Redis 命令行:

redis-cli

然后,验证身份:

auth your_redis_password
OK

假设您像前面的示例一样将 CONFIG 命令重命名为 ASC12_CONFIG。首先,尝试使用原始 CONFIG 命令。它应该失败,因为您已将其重命名:

config get requirepass
(error) ERR unknown command 'config'

但是,调用重命名的命令将成功(不区分大小写):

asc12_config get requirepass
1) "requirepass"
2) "your_redis_password"

最后,您可以从 redis-cli 退出:

exit

请注意,如果您已经在使用 Redis 命令行,然后重新启动 Redis,则需要重新进行身份验证。否则,如果键入命令,则会出现此错误:

NOAUTH Authentication required.

关于重命名命令的做法,/etc/redis/redis.confSECURITY 节末尾有一条警告性声明:

Please note that changing the name of commands that are logged into the AOF file or transmitted to slaves may cause problems.

注意: Redis 项目选择使用术语“主(Master)”和“从(Slave)”,而 DigitalOcean 通常更喜欢使用“主要(Primary)”和“次要(Replica)”替代方案。为了避免混淆,我们选择在此处使用 Redis 文档中使用的术语。

这意味着,如果重命名的命令不在 AOF 文件中,或者如果该重命名的命令尚未将 AOF 文件传输到从属设备,则应该没有问题。

因此,在尝试重命名命令时,请记住这一点。重命名命令的最佳时间是在不使用 AOF 持久性时,或者在安装后即刚部署使用 Redis 的应用程序之前。

当您使用 AOF 并处理主从安装时,请考虑 此答案(来自项目的 GitHub 问题页面)。以下是对作者问题的答复:

命令将以发送命令的相同方式记录到 AOF 并复制到从属设备,因此,如果您尝试在没有相同重命名的实例上重播 AOF,则可能会遇到不一致的情况,因为命令无法执行(奴隶也一样)

因此,在这种情况下处理重命名的最佳方法是确保将重命名的命令应用于主从安装中的所有实例。

结论

在本教程中,您已安装和配置 Redis,验证了您的 Redis 安装是否正常运行,并使用其内置的安全功能使其较不容易受到恶意行为者的攻击。

说明: 本教程基于 Ubuntu 18.04 编写。截至 2023 年,Ubuntu 18.04 已结束标准支持(进入 ESM 阶段),且默认仓库中的 Redis 版本可能较旧(如 Redis 4.x 或 5.x)。如果您使用的是更新的 Ubuntu 版本或需要最新 Redis 特性,请参考官方文档调整安装源或配置项。