介绍
Redis是一个开源的内存关键值数据存储,在缓存方面表现出色。
Redis 被设计用于可信客户在受信任的环境中使用,并且没有强大的安全功能。 然而,Redis 确实有 一些安全功能如密码身份验证和重新命名或禁用某些命令的能力。
请注意,本指南不涉及 Redis 服务器和客户端应用程序在不同的主机或不同数据中心的情况。 安装中 Redis 流量必须穿过不安全或不受信任的网络将需要不同的配置,例如在 Redis 机器之间设置 SSL 代理或 VPN。
您还可以使用 DigitalOcean’s Managed Redis Service。
前提条件
要完成本教程,您将需要一个运行Rocky Linux 8的服务器。本服务器应该有一个非根用户,具有管理权限,并配置了防火墙
。
步骤 1 – 安装和启动 Redis
您可以使用 DNF 包管理器安装 Redis. 使用 DNF,您可以安装 Redis,它的依赖,以及用户友好的文本编辑器「nano」。
1sudo dnf install redis nano
此命令会提示您确认您想要安装所选包,然后按y
,然后按ENTER
:
1[secondary_label Output]
2. . .
3
4Total download size: 1.5 M
5Installed size: 5.4 M
6Is this ok [y/N]: y
接下来,在安装过程中自动生成的 Redis 配置文件中需要进行一个重要的配置更改。
使用您喜爱的文本编辑器打开此文件. 在这里,我们将使用nano
:
1sudo nano /etc/redis.conf
在文件中,找到监督
指令. 此指令允许您宣布 init 系统以管理 Redis 作为服务,为您提供对其运作的更多控制权。 该监督
指令默认设置为不
。 由于您正在运行 Rocky Linux,该系统使用 systemd init 系统,请将此设置更改为systemd
:
1[label /etc/redis.conf]
2. . .
3
4# If you run Redis from upstart or systemd, Redis can interact with your
5# supervision tree. Options:
6# supervised no - no supervision interaction
7# supervised upstart - signal upstart by putting Redis into SIGSTOP mode
8# supervised systemd - signal systemd by writing READY=1 to $NOTIFY_SOCKET
9# supervised auto - detect upstart or systemd method based on
10# UPSTART_JOB or NOTIFY_SOCKET environment variables
11# Note: these supervision methods only signal "process is ready."
12# They do not enable continuous liveness pings back to your supervisor.
13supervised systemd
14
15. . .
这是你需要在这个时候对 Redis 配置文件进行的唯一更改,所以在你完成时保存并关闭它. 如果你使用了nano
来编辑该文件,你会用CTRL + X
保存并停止,然后在提示时,Y
然后输入。
编辑文件后,启动 Redis 服务:
1sudo systemctl start redis.service
如果你想让 Redis 启动,你可以使用启用
命令启用它:
1sudo systemctl enable redis
请注意,此命令不包括单元文件名之后的.service
字符串,您通常可以将此字符串排除在systemctl
命令中,因为它可以从服务名称中自动解析。
您可以通过运行以下操作来检查 Redis 的状态:
1sudo systemctl status redis
1[secondary_label Output]
2● redis.service - Redis persistent key-value database
3 Loaded: loaded (/usr/lib/systemd/system/redis.service; enabled; vendor preset: disabled)
4 Drop-In: /etc/systemd/system/redis.service.d
5 └─limit.conf
6 Active: active (running) since Tue 2022-09-06 22:11:52 UTC; 40s ago
7 Main PID: 14478 (redis-server)
8 Tasks: 4 (limit: 11152)
9 Memory: 6.6M
10 CGroup: /system.slice/redis.service
11 └─14478 /usr/bin/redis-server 127.0.0.1:6379
一旦您确认 Redis 确实在运行,您可以使用以下命令测试其功能:
1redis-cli ping
这应该打印PONG
作为答案:
1[secondary_label Output]
2PONG
如果是这样,这意味着您现在在您的服务器上运行了 Redis,您可以开始配置它以增强其安全性。
步骤 2 – 配置 Redis 并使用防火墙保护它
你可以这样做,确保Redis只与本地主机或私人IP地址绑定,而且服务器有一个防火墙并运行。
但是,如果您选择使用另一个教程来设置 Redis,那么您可能已经更新了配置文件,以允许从任何地方连接。
若要修复此问题,请使用您喜爱的文本编辑器再次打开 Redis 配置文件:
1sudo nano /etc/redis.conf
查找从绑定
开始的行,并确保它没有 commented out 或禁用,通过删除必要的行开始的#
标志:
1[label /etc/redis.conf]
2. . .
3bind 127.0.0.1
如果您需要将 Redis 绑定到另一个 IP 地址(例如在您将从单独的主机访问 Redis 的情况下),您应该强烈考虑将其绑定到私人 IP 地址。
1[label /etc/redis.conf]
2. . .
3bind your_private_ip
确认绑定
指令没有被评论后,您可以保存和关闭文件。
如果您已遵循初始服务器设置教程和 在您的服务器上安装了防火墙,并且您没有计划从另一个主机连接到Redis,那么您不需要为Redis添加任何额外的防火墙规则。
然而,如果您计划从另一个主机访问 Redis,则需要使用防火墙-cmd
命令对您的防火墙配置做出一些更改。
首先,在您的防火墙策略中添加一个专用的 Redis 区域:
1sudo firewall-cmd --permanent --new-zone=redis
然后指定您想要打开哪个端口 Redis 默认使用端口 6379
:
1sudo firewall-cmd --permanent --zone=redis --add-port=6379/tcp
接下来,指定任何私人IP地址,应该允许通过防火墙并访问Redis:
1sudo firewall-cmd --permanent --zone=redis --add-source=client_server_private_IP
运行这些命令后,重新加载防火墙以执行新规则:
1sudo firewall-cmd --reload
在此配置下,当防火墙从您的客户端 IP 地址遇到一个包时,它会将专用 Redis 区的规则应用于该连接。所有其他连接将由默认的公共
区处理。默认区中的服务适用于每个连接,而不仅仅是那些不明确匹配的连接,因此您不需要将其他服务(如 SSH)添加到 Redis 区,因为这些规则将自动应用于该连接。
请记住,使用任何防火墙工具都会起作用,无论您是否使用防火墙
,ufw
或iptables
。重要的是,防火墙正在运行,以便未知的人无法访问您的服务器。
步骤 3 – 配置 Redis 密码
配置 Redis 密码允许其内置的安全功能之一 - 命令auth
- 要求客户端在允许访问数据库之前进行身份验证。
1sudo nano /etc/redis.conf
滚动到安全
部分,并寻找评论的指令,该指令写道:
1[label /etc/redis.conf]
2. . .
3# requirepass foobared
删除#
并将foobared
更改为您选择的非常强大的密码。
<$>[注]
注 :您可以使用apg
或pwgen
等工具来生成密码,而不是自己创建密码。如果您不希望安装一个应用程序来生成密码,您可以使用下面的命令。
请注意,输入此命令以书面方式将每次生成相同的密码. 要创建一个独特的密码,请将引文中的字符串更改为任何其他单词或短语:
1echo "digital-ocean" | sha256sum
虽然生成的密码不会被记住,但它将非常强大和长,这正是Redis所需的密码类型。复制并粘贴该命令的输出作为requirepass
的新值后,应该读到:
1[label /etc/redis.conf]
2. . .
3requirepass password_copied_from_output
或者,如果您喜欢一个更短的密码,您可以使用不同的支票总量的输出。 再次,更改引用中的单词,以便它不会生成与此命令相同的密码:
1echo "digital-ocean" | sha1sum
美元
设置密码后,保存并关闭文件,然后重新启动 Redis:
1sudo systemctl restart redis
要测试密码是否有效,请打开 Redis 客户端:
1redis-cli
以下是用于测试 Redis 密码是否有效的命令序列:第一个命令试图在身份验证之前为值设置密钥:
1set key1 10
因为您尚未验证,所以Redis会返回错误:
1[secondary_label Output]
2(error) NOAUTH Authentication required.
以下命令使用 Redis 配置文件中指定的密码进行身份验证:
1auth your_redis_password
Redis 将确认您已被验证:
1[secondary_label Output]
2OK
此后,运行前一个命令应该再次成功:
1set key1 10
1[secondary_label Output]
2OK
get key1
命令请求为新密钥的值 Redis:
1get key1
1[secondary_label Output]
2"10"
这个最后的命令输出redis-cli
。你也可以使用exit
:
1quit
现在对于未经授权的用户来说,访问您的 Redis 安装应该非常困难。请注意,如果您已经使用了 Redis 命令行客户端,然后重新启动 Redis,您将需要重新验证。
接下来,本指南将讨论重新命名 Redis 命令,以进一步保护 Redis 免受恶意行为者影响。
步骤 4 – 重命名危险命令
Redis 内置的另一个安全功能允许您更名或完全禁用被认为是危险的某些命令. 当未经授权的用户运行时,这些命令可以用于重新配置,破坏或以其他方式删除您的数据。
FLUSHDB
FLUSHALL
KEYS
PEXPIRE
DEL
CONFIG
SHUTDOWN
BGREWRITEAOF
BGSAVE
SAVE
SPOP
SREM
RENAME
DEBUG
这不是一个完整的列表,但重命名或禁用本列表中的所有命令可以帮助改善数据存储的安全性。您是否应该禁用或重命名一个命令将取决于您的具体需求。
就像身份验证密码一样,重命名或禁用命令也被配置在 /etc/redis.conf
文件的 'SECURITY' 部分中。
1sudo nano /etc/redis.conf
<$>[注] 注 :这些是例子. 您应该选择禁用或更名对您有意义的命令. 您可以了解更多关于 Redis 的命令,并确定它们如何被滥用在 redis.io/commands。
若要禁用或杀死命令,请将命名为空串,如下:
1[label /etc/redis.conf]
2# It is also possible to completely kill a command by renaming it into
3# an empty string:
4#
5rename-command FLUSHDB ""
6rename-command FLUSHALL ""
7rename-command DEBUG ""
若要重新命名命令,请将命令命名为另一个名称,如下面的示例。
1[label /etc/redis.conf]
2# It is also possible to completely kill a command by renaming it into
3# an empty string:
4#
5rename-command FLUSHDB ""
6rename-command FLUSHALL ""
7rename-command DEBUG ""
8rename-command SHUTDOWN SHUTDOWN_MENOT
9rename-command CONFIG ASC12_CONFIG
保存您的更改并关闭文件,然后通过重新启动 Redis 来应用更改:
1sudo systemctl restart redis.service
要测试新命令,请输入 Redis 命令行:
1redis-cli
使用您之前定义的密码进行身份验证:
1auth your_redis_password
1[secondary_label Output]
2OK
假设您将CONFIG
命令更名为ASC12_CONFIG
,尝试使用config
命令将失败:
1config get requirepass
1[secondary_label Output]
2(error) ERR unknown command 'config'
相反,重新命名命令将是成功的。 请注意,Redis命令不是案例敏感:
1asc12_config get requirepass
1[secondary_label Output]
21) "requirepass"
32) "your_redis_password"
最后,你可以离开redis-cli
:
1exit
<$>[警告]
警告 :关于重命名命令,在 /etc/redis.conf
文件中的 SECURITY
部分末尾有一个警告声明,该声明是:
1[label /etc/redis.conf]
2. . .
3
4# Please note that changing the name of commands that are logged into the
5# AOF file or transmitted to replicas may cause problems.
6
7. . .
这意味着,如果重命令不在AOF文件中,或者如果它是,但AOF文件没有被传输到复制品中,那么应该没有问题。当您重命令时,请记住这一点。改命令的最佳时间是当您不使用AOF持久性或安装后(即在您的使用Redis的应用程序部署之前)。
步骤 5 — 设置数据目录所有权和文件权限
此步骤将通过一些所有权和权限的更改,您可能需要改进您的 Redis 安装的安全配置文件. 这涉及确保只有需要访问 Redis 的用户才能读取其数据。
您可以通过在其母目录的长列表中对 Redis 数据目录进行抓取
来验证。
1ls -l /var/lib | grep redis
1[secondary_label Output]
2drwxr-x---. 2 redis redis 22 Sep 6 22:22 redis
此输出表示 Redis 数据目录属于 redis 用户,并授予 ** redis** 组副访问权. 此所有权设置是安全的,以及使用 octal 标记的文件夹的权限设置为 750
。
如果您的 Redis 数据目录具有不安全的权限,则可以通过运行chmod
命令来确保只有 Redis 用户和组可以访问该文件夹及其内容。
1sudo chmod 770 /var/lib/redis
您可能需要更改的另一个权限是 Redis 配置文件的权限. 默认情况下,它具有 640
的文件权限,由 root 拥有,由 root 组拥有次要权限:
1ls -l /etc/redis.conf
1[secondary_label Output]
2-rw-r-----. 1 redis root 62192 Sep 6 22:20 /etc/redis.conf
该权限(640
)意味着 Redis 配置文件只能被 redis 用户和 ** root** 组读取,因为配置文件包含您在步骤 4 中配置的未加密密码,所以 `redis.conf' 应该由 ** redis** 用户拥有,由 ** redis** 组拥有次要所有权。
1sudo chown redis:redis /etc/redis.conf
然后更改权限,以便只有文件的所有者才能阅读和写入它:
1sudo chmod 600 /etc/redis.conf
您可以通过重新运行以前的ls
命令来验证新的所有权和权限:
1ls -l /var/lib | grep redis
1[secondary_label Output]
2total 40
3drwxrwx---. 2 redis redis 22 Sep 6 22:22 redis
1ls -l /etc/redis.conf
1[secondary_label Output]
2total 40
3-rw-------. 1 redis redis 62192 Sep 6 22:20 /etc/redis.conf
最后,重新启动 Redis 以反映这些更改:
1sudo systemctl restart redis
通过此,您的 Redis 安装已得到保障。
结论
请记住,一旦有人登录到您的服务器,您可以绕过所设置的 Redis 特定的安全功能,这就是为什么本教程中涵盖的最重要的安全功能是防火墙,因为它首先防止未知用户登录您的服务器。
如果您试图通过不受信任的网络保护 Redis 通信,则需要使用 SSL 代理,正如 Redis 开发人员在 官方 Redis 安全指南中推荐的那样。