如何在Ubuntu20.04上安装和保护Redis

来自菜鸟教程
跳转至:导航、​搜索

介绍

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

先决条件

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

第 1 步 — 安装和配置 Redis

我们将使用 APT 包管理器从官方 Ubuntu 存储库安装 redis。 在撰写本文时,默认存储库中可用的版本是 5.0.7

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

sudo apt update

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

sudo apt install redis-server

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

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

sudo nano /etc/redis/redis.conf

在文件中,找到 supervised 指令。 该指令允许您声明一个初始化系统来将 Redis 管理为服务,从而为您提供对其操作的更多控制。 supervised 指令默认设置为 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 配置文件进行的唯一更改,因此请在完成后保存并关闭它。 如果您使用 nano 编辑文件,请按 CTRL + XY,然后按 ENTER

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

sudo systemctl restart redis.service

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

第 2 步 — 测试 Redis

与任何新安装的软件一样,在对其配置进行任何进一步更改之前,确保 Redis 按预期运行是一个好主意。 我们将介绍几种方法来检查 Redis 在这一步中是否正常工作。

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

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 Thu 2020-04-30 23:26:54 UTC; 4s ago
       Docs: http://redis.io/documentation,
             man:redis-server(1)
    Process: 36552 ExecStart=/usr/bin/redis-server /etc/redis/redis.conf (code=exited, status=0/SUCCESS)
   Main PID: 36561 (redis-server)
      Tasks: 4 (limit: 2345)
     Memory: 1.8M
     CGroup: /system.slice/redis-server.service
             └─36561 /usr/bin/redis-server 127.0.0.1:6379
. . .

在这里,您可以看到 Redis 正在运行并且已经启用,这意味着它被设置为每次服务器启动时启动。

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

sudo systemctl disable redis

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

redis-cli

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

ping
OutputPONG

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

set test "It's working!"
OutputOK

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

get test

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

Output"It's working!"

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

exit

作为最终测试,我们将检查 Redis 是否能够在停止或重新启动后保留数据。 为此,首先重启 Redis 实例:

sudo systemctl restart redis

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

redis-cli

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

get test

您的密钥值应该仍然可以访问:

Output"It's working!"

完成后再次退出到 shell:

exit

这样,您的 Redis 安装就可以完全运行并可供您使用。 但是,它的一些默认配置设置是不安全的,并且为恶意行为者提供了攻击和访问您的服务器及其数据的机会。 本教程中的其余步骤包括缓解这些漏洞的方法,如 官方 Redis 网站 所述。 尽管这些步骤是可选的,如果您选择不执行这些步骤,Redis 仍然可以运行,但 强烈 建议您完成它们以加强系统的安全性。

第 3 步 - 绑定到 localhost

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

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

sudo nano /etc/redis/redis.conf

找到此行并确保它未注释(如果存在则删除 #):

/etc/redis/redis.conf

bind 127.0.0.1 ::1

完成后保存并关闭文件(按 CTRL + XY,然后按 ENTER)。

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

sudo systemctl restart redis

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

sudo netstat -lnp | grep redis
Outputtcp        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命令在您的系统上可能默认不可用。 如果是这种情况,您可以使用以下命令安装它(以及许多其他方便的网络工具):

sudo apt install net-tools

此输出显示 redis-server 程序绑定到 localhost (127.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 中配置,因此请使用您喜欢的编辑器再次打开该文件:

sudo nano /etc/redis/redis.conf

滚动到 SECURITY 部分并查找注释指令,内容如下:

/etc/redis/redis.conf

. . .
# requirepass foobared
. . .

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

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

/etc/redis/redis.conf

. . .
# 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

您的输出应类似于:

OutputRBOJ9cCNoGCKhlEBwQLHri1g+atWgn4Xn4HwNUbtzoVxAYxkiYBi7aufl4MILv1nxBqR4L6NNzI0X6cE

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

/etc/redis/redis.confrequirepass RBOJ9cCNoGCKhlEBwQLHri1g+atWgn4Xn4HwNUbtzoVxAYxkiYBi7aufl4MILv1nxBqR4L6NNzI0X6cE

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

sudo systemctl restart redis.service

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

redis-cli

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

set key1 10

这不起作用,因为您没有进行身份验证,因此 Redis 返回错误:

Output(error) NOAUTH Authentication required.

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

auth your_redis_password

Redis 承认:

OutputOK

之后,再次运行之前的命令就会成功:

set key1 10
OutputOK

get key1 向 Redis 查询新键的值。

get key1
Output"10"

验证通过后确认可以在Redis客户端运行命令后,可以退出redis-cli

quit

接下来,我们将研究重命名 Redis 命令,如果输入错误或由恶意行为者输入,可能会对您的机器造成严重损坏。

第 5 步 - 重命名危险命令

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

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

一些被认为是危险的命令包括:FLUSHDBFLUSHALLKEYSPEXPIREDEL、[X119X ], SHUTDOWN, BGREWRITEAOF, BGSAVE, SAVE, SPOP, SREM, RENAME , 和 DEBUG。 这不是一个完整的列表,但是重命名或禁用该列表中的所有命令是增强 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
OutputOK

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

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

但是,调用重命名的命令会成功。 它不区分大小写:

asc12_config get requirepass
Output1) "requirepass"
2) "your_redis_password"

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

exit

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

OutputNOAUTH Authentication required.

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

/etc/redis/redis.conf

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

笔记: Redis 项目选择使用术语“master”和“slave”,而 DigitalOcean 通常更喜欢使用“primary”和“secondary”的替代词。 为了避免混淆,我们选择在这里使用 Redis 文档中使用的术语。

这意味着如果重命名的命令不在 AOF 文件中,或者如果在 AOF 文件中但 AOF 文件没有传输到从站,那么应该没有问题。

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

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

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

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


结论

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

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