如何在CentOS8上安装和保护Redis
###介绍
Redis 是一个开源的内存键值数据存储,擅长缓存。 Redis 是一种非关系型数据库,以其灵活性、性能、可扩展性和广泛的语言支持而闻名。
Redis 旨在供受信任的客户端在受信任的环境中使用,并且它自己没有强大的安全功能。 然而,Redis 确实具有 一些安全功能 ,例如基本的未加密密码以及命令重命名和禁用。 本教程提供有关如何安装 Redis 和配置这些安全功能的说明。 它还涵盖了一些其他设置,可以提高 CentOS 8 上独立 Redis 安装的安全性。
请注意,本指南不涉及 Redis 服务器和客户端应用程序位于不同主机或不同数据中心的情况。 Redis 流量必须穿越不安全或不受信任的网络的安装将需要一组不同的配置,例如在 Redis 机器之间设置 SSL 代理或 VPN。
- 先决条件
要完成本教程,您需要一台运行 CentOS 8 的服务器。 此服务器应具有具有管理权限的非 root 用户和配置为 firewalld
的防火墙。 要进行此设置,请按照我们的 CentOS 8 初始服务器设置指南进行操作。
- Step 1 — 安装和启动 Redis
您可以使用 DNF 包管理器安装 Redis。 以下命令将安装 Redis、其依赖项和 nano
,一个用户友好的文本编辑器。 您不必安装 nano
,但我们将在本指南的示例中使用它:
sudo dnf install redis nano
此命令将提示您确认是否要安装选定的软件包。 按 y
然后按 ENTER
这样做:
Output. . . Total download size: 1.5 M Installed size: 5.4 M Is this ok [y/N]: y
在此之后,需要在 Redis 配置文件中进行一项重要的配置更改,该文件是在安装过程中自动生成的。
使用您喜欢的文本编辑器打开此文件。 这里我们将使用 nano
:
sudo nano /etc/redis/redis.conf
在文件中,找到 supervised
指令。 该指令允许您声明一个初始化系统来将 Redis 管理为服务,从而为您提供对其操作的更多控制。 supervised
指令默认设置为 no
。 由于您正在运行使用 systemd 初始化系统的 CentOS,请将其更改为 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 + X
、Y
,然后按 ENTER
。
编辑完文件后,启动 Redis 服务:
sudo systemctl start redis.service
如果您希望 Redis 在启动时启动,您可以使用 enable
命令启用它:
sudo systemctl enable redis
请注意,此命令在单元文件名后不包含 .service
后缀。 您通常可以将此后缀从 systemctl
命令中去掉,因为它通常在与 systemd 交互时隐含。
您可以通过运行以下命令检查 Redis 的状态:
sudo systemctl status redis
Output● redis.service - Redis persistent key-value database Loaded: loaded (/usr/lib/systemd/system/redis.service; enabled; vendor preset: disabled) Drop-In: /etc/systemd/system/redis.service.d └─limit.conf Active: active (running) since Wed 2020-09-30 20:05:24 UTC; 13s ago Main PID: 13734 (redis-server) Tasks: 4 (limit: 11489) Memory: 6.6M CGroup: /system.slice/redis.service └─13734 /usr/bin/redis-server 127.0.0.1:6379
确认 Redis 确实在运行后,您可以使用以下命令测试其功能:
redis-cli ping
这应该打印 PONG
作为响应:
OutputPONG
如果是这种情况,则意味着您现在在服务器上运行了 Redis,您可以开始对其进行配置以增强其安全性。
第 2 步 — 配置 Redis 并使用防火墙保护它
保护 Redis 的一种有效方法是保护运行它的服务器。 为此,您可以确保 Redis 仅绑定到 localhost 或私有 IP 地址,并且服务器已启动并运行防火墙。
但是,如果您选择使用其他教程设置 Redis,那么您可能已经更新了配置文件以允许从任何地方进行连接。 这不如绑定到本地主机或私有 IP 安全。
要解决此问题,请使用您喜欢的文本编辑器再次打开 Redis 配置文件:
sudo nano /etc/redis.conf
找到以 bind
开头的行并确保它没有被注释:
/etc/redis.conf
. . . bind 127.0.0.1
如果您需要将 Redis 绑定到另一个 IP 地址(例如您将从单独的主机访问 Redis),我们 强烈 建议您将其绑定到私有 IP 地址。 绑定到公共 IP 地址会增加 Redis 接口对外部各方的暴露:
/etc/redis.conf
. . . bind your_private_ip
确认 bind
指令没有被注释掉后,您可以保存并关闭文件。
如果您已遵循先决条件 Initial Server Setup 教程并 在您的服务器 上安装了 firewalld,并且您不打算从其他主机连接到 Redis,那么您不需要为 Redis 添加任何额外的防火墙规则. 毕竟,除非防火墙规则明确允许,否则默认情况下将丢弃任何传入流量。 由于 Redis 服务器的默认独立安装仅侦听环回接口(127.0.0.1
或 localhost),因此无需担心其默认端口上的传入流量。
但是,如果您确实计划从其他主机访问 Redis,则需要使用 firewall-cmd
命令对您的 firewalld 配置进行一些更改。 同样,您应该只允许使用主机的私有 IP 地址从您的主机访问您的 Redis 服务器,以限制您的服务暴露给的主机数量。
首先,将一个专用的 Redis 区域添加到您的 firewalld 策略中:
sudo firewall-cmd --permanent --new-zone=redis
然后指定您想要打开的端口。 Redis 默认使用端口 6379
:
sudo firewall-cmd --permanent --zone=redis --add-port=6379/tcp
接下来,指定应允许通过防火墙并访问 Redis 的任何私有 IP 地址:
sudo firewall-cmd --permanent --zone=redis --add-source=client_server_private_IP
运行这些命令后,重新加载防火墙以实施新规则:
sudo firewall-cmd --reload
在此配置下,当防火墙遇到来自您客户端 IP 地址的数据包时,它会将专用 Redis 区域中的规则应用于该连接。 所有其他连接将由默认的 public
区域处理。 默认区域中的服务适用于每个连接,而不仅仅是那些不明确匹配的服务,因此您不需要添加其他服务(例如 SSH) 到 Redis 区域,因为这些规则将自动应用于该连接。
请记住,无论您使用 firewalld
、ufw
还是 iptables
,都可以使用任何防火墙工具。 重要的是防火墙已启动并运行,以便未知个人无法访问您的服务器。 在下一步中,您将配置 Redis 以仅使用强密码访问。
- Step 3 — 配置 Redis 密码
配置 Redis 密码会启用其内置的安全功能之一——auth
命令——它要求客户端在被允许访问数据库之前进行身份验证。 和bind
设置一样,密码直接在Redis的配置文件/etc/redis.conf
中配置。 重新打开该文件:
sudo nano /etc/redis.conf
滚动到 SECURITY
部分并查找注释指令,内容如下:
/etc/redis.conf
. . . # requirepass foobared
通过删除 #
取消注释,并将 foobared
更改为您选择的非常强的密码。
注意:您可以使用apg
或pwgen
等工具生成密码,而不是自己编写密码。 但是,如果您不想安装应用程序只是为了生成密码,则可以使用以下命令。 此命令回显一个字符串值并将其通过管道传送到以下 sha256sum
命令中,该命令将显示字符串的 SHA256 校验和。
请注意,以书面形式输入此命令每次都会生成相同的密码。 要创建唯一密码,请将引号中的字符串更改为任何其他单词或短语:
echo "digital-ocean" | sha256sum
虽然生成的密码不会发音,但它会非常强且长,这正是 Redis 所需的密码类型。 将该命令的输出复制并粘贴为 requirepass
的新值后,应显示为:
/etc/redis.conf
. . . requirepass password_copied_from_output
或者,如果您更喜欢较短的密码,则可以改用以下命令的输出。 同样,更改引号中的单词,使其不会生成与此命令相同的密码:
echo "digital-ocean" | sha1sum
设置密码后,保存并关闭文件,然后重启 Redis:
sudo systemctl restart redis
要测试密码是否有效,请打开 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-cli
。 您也可以使用 exit
:
quit
现在,未经授权的用户应该很难访问您的 Redis 安装。 请注意,如果您已经在使用 Redis 客户端,然后重新启动 Redis,则需要重新进行身份验证。 另外,请注意,如果没有 SSL 或 VPN,如果您远程连接到 Redis,未加密的密码仍然对外部各方可见。
接下来,本指南将介绍重命名 Redis 命令以进一步保护 Redis 免受恶意攻击者的侵害。
第 4 步 — 重命名危险命令
Redis 内置的其他安全功能允许您重命名或完全禁用某些被认为是危险的命令。 当由未经授权的用户运行时,此类命令可用于重新配置、销毁或以其他方式擦除您的数据。 一些被认为是危险的命令包括:
FLUSHDB
FLUSHALL
KEYS
PEXPIRE
DEL
CONFIG
SHUTDOWN
BGREWRITEAOF
BGSAVE
SAVE
SPOP
SREM
RENAME
DEBUG
这不是一个完整的列表,但重命名或禁用此列表中的所有命令有助于提高数据存储的安全性。 是否应该禁用或重命名给定命令将取决于您的特定需求。 如果您知道您永远不会使用可能被滥用的命令,那么您可以禁用它。 否则,您应该重命名它。
与验证密码一样,重命名或禁用命令在 /etc/redis.conf
文件的 SECURITY
部分中配置。 要启用或禁用 Redis 命令,请再次打开配置文件进行编辑:
sudo nano /etc/redis.conf
注:这些是示例。 您应该选择禁用或重命名对您有意义的命令。 您可以在 redis.io/commands 上了解有关 Redis 命令的更多信息并确定它们可能如何被滥用。
要禁用或终止命令,请将其重命名为空字符串,如下所示:
/etc/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.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 "" 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'
改为调用重命名的命令将成功。 请注意,Redis 命令不区分大小写:
asc12_config get requirepass
Output1) "requirepass" 2) "your_redis_password"
最后,可以从redis-cli
退出:
exit
Warning:关于重命名命令,在/etc/redis.conf
文件的SECURITY
部分末尾有一个警告声明,内容如下:
/etc/redis.conf
. . . # 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 持久性时或在安装之后(即,在部署使用 Redis 的应用程序之前)。
当您使用 AOF 并处理 Redis 复制时,请考虑 这个来自项目的 GitHub 问题页面 的答案。 以下是对作者问题的回复:
命令会记录到 AOF 并以与发送相同的方式复制到从属设备,因此如果您尝试在没有相同重命名的实例上重放 AOF,您可能会遇到不一致,因为无法执行命令(奴隶也一样)。
在这种情况下处理重命名的最佳方法是确保将重命名的命令应用于主实例以及 Redis 安装中的每个辅助实例。
第 5 步 — 设置数据目录所有权和文件权限
此步骤将完成您可能需要进行的一些所有权和权限更改,以改进 Redis 安装的安全配置文件。 这涉及确保只有需要访问 Redis 的用户才有权读取其数据。 默认情况下,该用户是 redis 用户。
您可以通过 grep
-ing 在其父目录的长列表中对 Redis 数据目录进行验证。 该命令及其输出如下所示:
ls -l /var/lib | grep redis
Outputdrwxr-x---. 2 redis redis 22 Sep 30 20:15 redis
此输出表明 Redis 数据目录归 redis 用户所有,并授予 redis 组辅助访问权限。 此所有权设置是安全的,因为文件夹的权限使用八进制表示法设置为 750
。
如果您的 Redis 数据目录具有不安全的权限(例如,它是全球可读的),您可以通过运行 chmod
命令确保只有 Redis 用户和组有权访问该文件夹及其内容。 以下示例将此文件夹的权限设置更改为 770
:
sudo chmod 770 /var/lib/redis
您可能需要更改的另一个权限是 Redis 配置文件的权限。 默认情况下,它的文件权限为 640
,由 root 拥有,由 root 组拥有第二所有权:
ls -l /etc/redis.conf
Output-rw-r-----. 1 redis root 62344 Sep 30 20:14 /etc/redis.conf
该权限 (640
) 意味着 Redis 配置文件只能由 redis 用户和 root 组读取。 由于配置文件中包含您在步骤 4 中配置的未加密密码,因此 redis.conf
应归 redis 用户所有,次要所有权归 redis 组。 要设置它,请运行以下命令:
sudo chown redis:redis /etc/redis.conf
然后更改权限,以便只有文件的所有者可以对其进行读写:
sudo chmod 600 /etc/redis.conf
您可以通过再次运行之前的 ls
命令来验证新的所有权和权限:
ls -l /var/lib | grep redis
Outputtotal 40 drwxrwx---. 2 redis redis 22 Sep 30 20:15 redis
ls -l /etc/redis.conf
Outputtotal 40 -rw-------. 1 redis redis 62344 Sep 30 20:14 /etc/redis.conf
最后,重启 Redis 以反映这些变化:
sudo systemctl restart redis
这样,您的 Redis 安装就得到了保护。
结论
请记住,一旦有人登录到您的服务器,就很容易绕过您设置的特定于 Redis 的安全功能。 这就是为什么本教程中涵盖的最重要的安全功能是防火墙,因为它首先可以防止未知用户登录到您的服务器。
如果您尝试在不受信任的网络上保护 Redis 通信,则必须按照 Redis 开发人员在 官方 Redis 安全指南 中的建议使用 SSL 代理。