如何在 Ubuntu 18.04 上安装和保护 Redis
介绍
Redis 是一种内存中的键值存储,以其灵活性、性能和广泛的语言支持而闻名。本教程演示如何在 Ubuntu 18.04 服务器上安装、配置和保护 Redis。
先决条件
要完成本指南,您需要访问 Ubuntu 18.04 服务器,该服务器具有具有 sudo
权限的非根用户并配置了基本防火墙。您可以按照我们的初始服务器设置指南进行设置。
当您准备好开始时,以您的 sudo
用户身份登录到您的 Ubuntu 18.04 服务器,然后继续下面的操作。
第 1 步 — 安装和配置 Redis
为了获得最新版本的 Redis,我们将使用 apt
从官方 Ubuntu 存储库安装它。
首先,如果您最近没有更新本地 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
:
. . .
# 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
如果它运行没有任何错误,此命令将产生类似于以下内容的输出:
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 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 正在运行并且已经启用,这意味着它被设置为在每次服务器启动时启动。
注意:此设置适用于许多 Redis 常见用例。但是,如果您希望每次服务器启动时都手动启动 Redis,则可以使用以下命令进行配置:
- sudo systemctl disable redis
要测试 Redis 是否正常运行,请使用命令行客户端连接到服务器:
- 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 步 — 绑定到本地主机
默认情况下,Redis 只能从本地主机访问。但是,如果您按照与本教程不同的教程安装和配置 Redis,您可能已经更新了配置文件以允许来自任何地方的连接。这不如绑定到本地主机安全。
要更正此问题,请打开 Redis 配置文件进行编辑:
- sudo nano /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
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
此输出显示 redis-server
程序已绑定到本地主机 (127.0.0.1
),反映了 Redis 配置文件中的 bind
设置。如果您在该列中看到另一个 IP 地址(例如 0.0.0.0
),那么您应该仔细检查您是否取消注释了正确的行并再次重新启动 Redis 服务。
现在您的 Redis 安装仅在本地主机上侦听,恶意行为者将更难发出请求或访问您的服务器。但是,Redis 目前并未设置为要求用户在更改其配置或它持有的数据之前进行身份验证。为了解决这个问题,Redis 允许您要求用户在通过 Redis 客户端 (redis-cli
) 进行更改之前使用密码进行身份验证。
第 4 步 — 配置 Redis 密码
配置 Redis 密码可启用其两个内置安全功能之一 - auth
命令,该命令需要客户端进行身份验证才能访问数据库。密码直接在 Redis 的配置文件 /etc/redis/redis.conf
中配置,因此请使用您喜欢的编辑器再次打开该文件:
- sudo nano /etc/redis/redis.conf
滚动到 SECURITY
部分并查找带有注释的指令,内容如下:
# requirepass foobared
通过删除 #
取消注释,并将 foobared
更改为安全密码。
注意:在 redis.conf
文件中的 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
您的输出应该类似于:
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
部分中配置的。
一些被认为是危险的命令包括:FLUSHDB、FLUSHALL、KEYS、PEXPIRE、DEL、CONFIG、SHUTDOWN、BGREWRITEAOF、BGSAVE、SAVE、SPOP、SREM、RENAME 和 DEBUG。这不是一个完整的列表,但重命名或禁用该列表中的所有命令是增强 Redis 服务器安全性的良好起点。
是否应该禁用或重命名命令取决于您的特定需求或您站点的需求。如果您知道您永远不会使用可能被滥用的命令,那么您可以禁用它。否则,重命名它可能符合您的最佳利益。
要启用或禁用 Redis 命令,请再次打开配置文件:
- sudo nano /etc/redis/redis.conf
警告:以下显示如何禁用和重命名命令的步骤是示例。您应该只选择禁用或重命名对您有意义的命令。您可以在 redis.io/commands 查看完整的命令列表并确定它们可能被滥用的方式。
要禁用命令,请将其重命名为空字符串(用一对引号表示,引号之间没有字符),如下所示:
. . .
# 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 ""
. . .
通过添加这些 rename-command
指令并在它们后面加上空字符串,FLUSHDB
、FLUSHALL
和 DEBUG
将是在此 Redis 安装中禁用。
要重命名命令,请给它另一个名称,如下例所示。重命名的命令应该让别人很难猜到,但对你来说很容易记住:
. . .
# rename-command CONFIG ""
rename-command SHUTDOWN SHUTDOWN_MENOT
rename-command CONFIG ASC12_CONFIG
. . .
这些示例将 SHUTDOWN
和 CONFIG
命令分别重命名为 SHUTDOWN_MENOT
和 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'
但是,调用重命名的命令将会成功。它不区分大小写:
- asc12_config get requirepass
Redis 的 config
命令允许运行它的任何人与安装的配置文件进行交互。当与 get
组合并后跟来自配置文件的指令时,该命令将返回该指令及其当前设置:
Output1) "requirepass"
2) "your_redis_password"
最后,您可以退出 redis-cli
:
- exit
请注意,如果您已经在使用 Redis 命令行,然后重新启动 Redis,则需要重新进行身份验证。否则,如果您键入命令,您将收到此错误:
OutputNOAUTH Authentication required.
警告:关于重命名命令的做法,在 /etc/redis/redis.conf
的 SECURITY
部分末尾有一个警告声明,内容如下:
. . .
# Please note that changing the name of commands that are logged into the
# AOF file or transmitted to slaves may cause problems.
. . .
这意味着如果重命名的命令不在 AOF 文件中,或者如果在 AOF 文件中但 AOF 文件尚未传输到从属服务器,则应该没有问题。
因此,在尝试重命名命令时请记住这一点。重命名命令的最佳时间是在您未使用 AOF 持久性时,或刚安装后,即在部署使用 Redis 的应用程序之前。
当您使用 AOF 并处理主从安装时,请考虑该项目的 GitHub 问题页面中的这个答案。以下是对作者问题的回复:
命令被记录到 AOF 并以与发送相同的方式复制到从站,因此如果您尝试在没有相同重命名的实例上重放 AOF,您可能会遇到不一致,因为命令无法执行(奴隶也一样)。
因此,在这种情况下处理重命名的最佳方法是确保重命名的命令应用于主从安装中的所有实例。
注意: Redis 项目选择使用术语“master”和“slave”,而 DigitalOcean 通常更喜欢替代术语“primary”和“replica”。为了避免混淆,我们在这里选择使用 Redis 文档中使用的术语。
结论
在本教程中,您安装并配置了 Redis,验证了您的 Redis 安装是否正常运行,并使用其内置的安全功能使其不易受到恶意行为者的攻击。
请记住,一旦有人登录到您的服务器,就很容易绕过我们已部署的特定于 Redis 的安全功能。因此,Redis 服务器上最重要的安全功能是您的防火墙(如果您按照先决条件初始服务器设置教程进行了配置),因为这使得恶意行为者极难越过该防护栏。