如何在Ubuntu 22.04上安装和保护Redis

介绍

Redis是一种内存中的键值存储,以其灵活性、性能和广泛的语言支持而闻名。本教程演示了如何在Ubuntu 22.04服务器上安装、配置和保护Redis。

先决条件

要完成本指南,您需要访问一个具有非root用户和sudo特权以及配置了ufw防火墙的Ubuntu 22.04服务器。您可以按照我们的Ubuntu 22.04的初始服务器设置指南进行设置。

步骤1 — 安装和配置Redis

我们将使用APT软件包管理器从官方Ubuntu仓库安装redis。截至撰写本文时,默认仓库中可用的版本是6.0.16

首先更新本地的apt软件包缓存:

  1. sudo apt update

然后通过键入以下命令来安装Redis:

  1. sudo apt install redis-server

这将下载并安装Redis及其依赖项。之后,需要在Redis配置文件中进行一个重要的配置更改,该文件在安装过程中自动生成。

使用您偏好的文本编辑器打开此文件:

  1. sudo nano /etc/redis/redis.conf

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

/etc/redis/redis.conf
. . .

# 如果您从upstart或systemd运行Redis,则Redis可以与您的
# 监视树交互。选项:
#   supervised no      - 无监督交互
#   supervised upstart - 通过将Redis置于SIGSTOP模式来通知upstart
#   supervised systemd - 通过向$NOTIFY_SOCKET写入READY=1来通知systemd
#   supervised auto    - 根据
#                        UPSTART_JOB或NOTIFY_SOCKET环境变量检测upstart或systemd方法
# 注意:这些监视方法只是信号“进程已准备就绪”。
#       它们不会启用与监督者之间的连续存活性ping。
supervised systemd

. . .

这是您目前需要对 Redis 配置文件进行的唯一更改,完成后请保存并关闭它。如果您使用 nano 编辑文件,请按 CTRL + X,然后按 Y,最后按 ENTER

然后,重新启动 Redis 服务以反映您对配置文件所做的更改:

  1. sudo systemctl restart redis.service

至此,您已经安装并配置了 Redis,并且它正在您的机器上运行。但在开始使用之前,最好先检查 Redis 是否正常运行。

第二步 — 测试 Redis

与任何新安装的软件一样,确保 Redis 正常运行是个好主意,然后再对其配置进行进一步更改。在此步骤中,我们将介绍几种检查 Redis 是否正常运行的方法。

首先,检查 Redis 服务是否正在运行:

  1. sudo systemctl status redis

如果它正在运行且没有任何错误,此命令将产生类似以下的输出:

Output
● redis-server.service - Advanced key-value store Loaded: loaded (/lib/systemd/system/redis-server.service; enabled; vendor preset: enabled) Active: active (running) since Wed 2022-04-20 20:40:52 UTC; 4s ago Docs: http://redis.io/documentation, man:redis-server(1) Main PID: 2899 (redis-server) Status: "Ready to accept connections" Tasks: 5 (limit: 2327) Memory: 2.5M CPU: 65ms CGroup: /system.slice/redis-server.service └─2899 "/usr/bin/redis-server 127.0.0.1:6379 . . .

此输出表示 Redis 正在运行,并且已经启用,这意味着它已设置为在服务器启动时启动。

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

  1. sudo systemctl disable redis

要测试 Redis 是否正常运行,请使用 redis-cli 连接到服务器,这是 Redis 的命令行客户端:

  1. redis-cli

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

  1. ping
Output
PONG

此输出确认服务器连接仍然有效。接下来,通过运行以下命令来检查是否能够设置键:

  1. set test "It's working!"
Output
OK

通过输入以下命令检索值:

  1. get test

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

Output
"It's working!"

确认您可以获取值后,退出 Redis 提示符以返回到 shell:

  1. exit

作为最后的测试,我们将检查 Redis 是否能够在停止或重新启动后仍然持久化数据。首先,重新启动 Redis 实例:

  1. sudo systemctl restart redis

然后再次使用命令行客户端连接:

  1. redis-cli

确认您的测试值仍然可用:

  1. get test

您的键的值应该仍然是可访问的:

Output
"It's working!"

完成后再次退出到 shell:

  1. exit

至此,您的 Redis 安装已完全可用并准备好供您使用。但是,其一些默认配置设置存在安全风险,并为恶意行为者提供机会攻击并访问您的服务器及其数据。本教程中的剩余步骤涵盖了通过 官方 Redis 网站提供的方法来减轻这些漏洞的方法。虽然这些步骤是可选的,如果您选择不遵循它们,Redis 仍然会正常工作,但强烈建议您完成它们以加强系统的安全性。强烈

步骤 3 — 绑定到 localhost

默认情况下,Redis 只能从 localhost 访问。但是,如果您根据不同于本教程的教程安装和配置了 Redis,则可能已经更新了配置文件以允许从任何地方进行连接。这不如绑定到 localhost 安全。

为了更正这个问题,打开 Redis 配置文件进行编辑:

  1. sudo nano /etc/redis/redis.conf

找到这一行并确保它没有被注释掉(如果存在 #,则移除它):

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

完成编辑后保存并关闭文件(按下 CTRL + X,然后输入 Y,最后按下 ENTER)。

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

  1. sudo systemctl restart redis

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

  1. sudo netstat -lnp | grep redis
Output
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

注意:默认情况下,您的系统可能没有 netstat 命令。如果是这种情况,您可以使用以下命令安装它(以及其他一些方便的网络工具):

  1. sudo apt install net-tools

此输出显示 redis-server 程序绑定到 localhost127.0.0.1),反映了您刚刚对配置文件进行的更改。如果在该列中有另一个 IP 地址(例如 0.0.0.0),则您应该再次检查是否取消了正确的行,并重新启动 Redis 服务。

现在您的Redis安装仅监听localhost,恶意行为者将更难以发出请求或访问您的服务器。但是,Redis当前未设置要求用户在对其配置或保存的数据进行更改之前进行身份验证。为解决此问题,Redis允许您要求用户在通过Redis客户端(redis-cli)进行更改之前进行身份验证。

步骤 4 — 配置 Redis 密码

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

  1. sudo nano /etc/redis/redis.conf

滚动到SECURITY部分,并找到一个已注释的指令,内容如下:

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

通过删除#取消对其的注释,并将foobared更改为安全密码。

注意:redis.conf文件中的requirepass指令上方,有一个已注释的警告:

/etc/redis/redis.conf
. . .
# 警告:由于 Redis 非常快速,外部用户可以每秒尝试多达
# 15万个密码对一台性能良好的服务器。这意味着您应该
# 使用非常强大的密码,否则很容易被破解。
#
. . .

因此,指定一个非常强大且非常长的值作为密码非常重要。您可以使用 openssl 命令生成一个随机密码,如下例所示。通过将第一个命令的输出导入到第二个openssl 命令,就像这里所示,它会移除第一个命令生成的任何换行符:

  1. openssl rand 60 | openssl base64 -A

此命令将返回如下输出:

Output
RBOJ9cCNoGCKhlEBwQLHri1g+atWgn4Xn4HwNUbtzoVxAYxkiYBi7aufl4MILv1nxBqR4L6NNzI0X6cE

复制并粘贴该命令的输出作为 requirepass 的新值,应如下所示:

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

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

  1. sudo systemctl restart redis.service

为了测试密码是否有效,打开 Redis 客户端:

  1. redis-cli

以下是用于测试 Redis 密码是否有效的一系列命令。第一个命令尝试在认证之前将键设置为一个值:

  1. set key1 10

那样是行不通的,因为您尚未进行身份验证,因此 Redis 返回错误:

Output
(error) NOAUTH Authentication required.

下一个命令使用 Redis 配置文件中指定的密码进行身份验证:

  1. auth your_redis_password

Redis 确认:

Output
OK

之后,再次运行上一个命令将成功:

  1. set key1 10
Output
OK

get key1 查询 Redis 的新键值。

  1. get key1
Output
"10"

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

  1. quit

接下来,我们将讨论重命名 Redis 命令,这些命令如果错误输入或被恶意操作者输入,可能会对您的数据产生严重影响。

步骤 5 — 重命名危险命令

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

当未经授权的用户运行此类命令时,这些命令可能被用于重新配置、销毁或以其他方式清除您的数据。与身份验证密码一样,重命名或禁用命令是在相同的 /etc/redis/redis.conf 文件的 SECURITY 部分配置的。

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

无论您是否应该禁用或重命名命令,都取决于您的具体需求或站点的需求。如果您知道您永远不会使用可能被滥用的命令,那么您可以将其禁用。否则,重命名可能符合您的最佳利益。

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

  1. sudo nano /etc/redis/redis.conf

警告:以下显示如何禁用和重命名命令的步骤仅为示例。您应仅选择禁用或重命名适合您的命令。您可以自行查看完整的命令列表,并确定它们可能如何被滥用,网址为:redis.io/commands

要禁用命令,请将其重命名为空字符串(由一对没有字符的引号表示),如下所示:

/etc/redis/redis.conf
. . .
# 还可以通过将其重命名为空字符串来彻底禁用命令:
# 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 应用更改:

  1. sudo systemctl restart redis.service

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

  1. redis-cli

然后,进行身份验证:

  1. auth your_redis_password
Output
OK

假设您已将 CONFIG 命令重命名为 ASC12_CONFIG,如上例所示。首先,尝试使用原始的 CONFIG 命令。它应该失败,因为您已经将其重命名:

  1. config get requirepass
Output
(error) ERR unknown command `config`, with args beginning with:

调用重命名命令将成功。它不区分大小写:

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

最后,您可以退出redis-cli

  1. exit

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

Output
NOAUTH Authentication required.

警告:关于重命名命令的实践,在/etc/redis/redis.confSECURITY部分末尾有一条警告性声明,内容如下:

/etc/redis/redis.conf
. . .
# 请注意,更改记录到 AOF 文件或传输到副本的命令名称可能会导致问题。

. . .

注意:Redis 项目选择使用 “master” 和 “slave” 一词,而 DigitalOcean 通常更喜欢 “primary” 和 “secondary” 的替代方案。为了避免混淆,我们选择在此处使用 Redis 文档中使用的术语。

这意味着如果重命名的命令不在 AOF 文件中,或者如果它在其中但 AOF 文件尚未传输到从服务器,则不应出现问题。

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

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

命令被记录到 AOF 并以与发送的方式相同的方式复制到从节点,因此,如果尝试在没有相同重命名的实例上重放 AOF,则可能会面临不一致性,因为无法执行该命令(从节点也是如此)。

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

结论

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

请记住,一旦有人登录到您的服务器,绕过我们设置的特定于 Redis 的安全功能就变得非常容易。因此,您 Redis 服务器上最重要的安全功能是您的防火墙(如果您遵循了先决条件 初始服务器设置 教程进行了配置),因为这使得恶意行为者极其难以越过这道防线。

Source:
https://www.digitalocean.com/community/tutorials/how-to-install-and-secure-redis-on-ubuntu-22-04