介绍
Redis是一款开源的内存键值数据存储系统,以其出色的缓存功能而闻名。Redis是一款非关系型数据库,以其灵活性、性能、可扩展性和广泛的语言支持而著称。
Redis被设计用于受信任的客户端在受信任的环境中使用,本身没有强大的安全功能。然而,Redis确实具有一些安全功能,如密码身份验证以及重命名或禁用某些命令的功能。本教程提供了有关如何安装Redis并配置这些安全功能的说明。它还涵盖了一些可以增强在Rocky Linux 8上独立安装的Redis的安全性的其他设置。
请注意,本指南不涵盖Redis服务器和客户端应用程序位于不同主机或不同数据中心的情况。需要在Redis流量必须经过不安全或不受信任的网络的情况下进行安装,将需要一组不同的配置,例如设置SSL代理或在Redis机器之间设置VPN。
您还可以使用DigitalOcean的托管Redis服务。
先决条件
为了完成本教程,您需要一台运行Rocky Linux 8的服务器。此服务器应具有一个具有管理权限的非根用户,并配置了使用firewalld
的防火墙。要完成设置,请按照我们的Rocky Linux 8初始服务器设置指南。
步骤1 — 安装和启动Redis
您可以使用DNF软件包管理器安装Redis。使用DNF,您可以安装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.conf
在文件中,找到supervised
指令。该指令允许您声明一个init系统来管理Redis作为服务,从而提供更多对其操作的控制。supervised
指令默认设置为no
。由于您正在运行Rocky Linux,它使用systemd init系统,因此将其更改为systemd
:
. . .
# 如果您从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服务:
- sudo systemctl start redis.service
如果您希望Redis在启动时启动,则可以使用enable
命令启用它:
- sudo systemctl enable redis
请注意,在单元文件名称后面没有.service
后缀。通常可以在systemctl
命令中省略此后缀,因为它可以从服务名称中自动解析出来。
您可以通过运行以下命令来检查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 Tue 2022-09-06 22:11:52 UTC; 40s ago
Main PID: 14478 (redis-server)
Tasks: 4 (limit: 11152)
Memory: 6.6M
CGroup: /system.slice/redis.service
└─14478 /usr/bin/redis-server 127.0.0.1:6379
确认Redis确实正在运行后,您可以使用此命令测试其功能:
- redis-cli ping
这应该会将PONG
打印为响应:
OutputPONG
如果是这种情况,这意味着您现在已经在服务器上运行了Redis,并且可以开始配置它以增强其安全性。
步骤2 —— 配置Redis并使用防火墙保护
保护Redis的有效方法是确保运行Redis的服务器仅绑定到localhost或私有IP地址,并且服务器正在运行防火墙。
但是,如果您选择使用另一个教程设置Redis,则可能已更新配置文件以允许从任何地方进行连接。这不像绑定到localhost或私有IP那样安全。
为了解决这个问题,请再次使用您喜欢的文本编辑器打开Redis配置文件:
- sudo nano /etc/redis.conf
定位以bind
开头的行,并确保它没有被注释掉或禁用,必要时删除行首的#
符号:
. . .
bind 127.0.0.1
如果您需要将Redis绑定到另一个IP地址(例如,您将从另一台主机访问Redis的情况),强烈建议将其绑定到私有IP地址。绑定到公共IP地址会增加Redis接口对外部方的暴露:
. . .
bind your_private_ip
确认bind
指令没有被注释掉后,您可以保存并关闭文件。
如果您已经按照先决条件的初始服务器设置教程进行了操作,并在服务器上安装了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 仅可通过强密码访问。
第三步 — 配置 Redis 密码
配置Redis密码启用了其中一个内置的安全功能 – auth
命令 – 它要求客户端在被允许访问数据库之前进行身份验证。与bind
设置类似,密码直接在Redis的配置文件/etc/redis.conf
中配置。重新打开该文件:
- sudo nano /etc/redis.conf
滚动到SECURITY
部分,并查找一个被注释的指令,内容如下:
. . .
# requirepass foobared
取消注释,即删除#
,并将foobared
更改为您选择的非常强大的密码。
注意: 您可以使用像apg
或pwgen
这样的工具来生成密码,而不是自己编造密码。但是,如果您不想安装应用程序来生成密码,您可以使用以下命令。此命令会将字符串值回显并将其传送到以下sha256sum
命令,后者将显示字符串的SHA256校验和。
请注意,按照原样输入此命令将每次生成相同的密码。要创建唯一的密码,请将引号中的字符串更改为任何其他单词或短语:
- echo "digital-ocean" | sha256sum
尽管生成的密码可能不容易记住,但它将非常强大且长,这正是Redis所需的密码类型。将该命令的输出复制并粘贴为requirepass
的新值,应该是:
. . .
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
用于查询新密钥的值:
- get key1
Output"10"
最后一个命令退出redis-cli
。您还可以使用exit
:
- quit
现在,未经授权的用户应该很难访问您的Redis安装。请注意,如果您已经在使用Redis命令行客户端,然后重新启动Redis,您将需要重新进行身份验证。此外,请注意,如果您远程连接到Redis而没有使用SSL或VPN,此密码仍然可能被外部方拦截:
接下来,本指南将介绍如何重命名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命令的更多信息,并确定它们可能被滥用的方式。
要禁用或终止命令,请将其重命名为空字符串,如下所示:
# 还可以通过将其重命名为空字符串来完全终止命令:
#:
#
rename-command FLUSHDB ""
rename-command FLUSHALL ""
rename-command DEBUG ""
要重命名命令,请像下面的示例中那样给它另一个名称。重命名的命令应该对其他人难以猜测,但对您来说易于记忆:
# 还可以通过将其重命名为空字符串来完全终止命令:
#:
#
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
警告: 关于重命名命令,在 /etc/redis.conf
文件的 SECURITY
部分末尾有一条警告声明:
. . .
#请注意,更改记录在
AOF 文件中或传输到副本中的命令的名称可能会引起问题。
. . .
这意味着,如果重命名的命令不在 AOF 文件中,或者如果它在 AOF 文件中但 AOF 文件尚未传输到副本,则应该没有问题。在重命名命令时,请记住这一点。重命名命令的最佳时间是在不使用 AOF 持久性或安装后立即进行(即,在部署了您的 Redis 应用程序之前)。
步骤 5 —— 设置数据目录所有权和文件权限
此步骤将介绍您可能需要进行的一些所有权和权限更改,以改善 Redis 安装的安全性配置文件。这涉及确保只有需要访问 Redis 的用户具有读取其数据的权限。默认情况下,该用户是 redis 用户。
您可以通过在其父目录的长列表中 grep
Redis 数据目录来验证这一点。以下是此命令及其输出:
- ls -l /var/lib | grep redis
Outputdrwxr-x---. 2 redis redis 22 Sep 6 22:22 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 62192 Sep 6 22:20 /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 6 22:22 redis
- ls -l /etc/redis.conf
Outputtotal 40
-rw-------. 1 redis redis 62192 Sep 6 22:20 /etc/redis.conf
最后,重新启动 Redis 以反映这些更改:
- sudo systemctl restart redis
至此,您的 Redis 安装已经得到了安全保障。
结论
请记住,一旦有人登录到您的服务器,就有可能绕过您设置的特定于Redis的安全功能。这就是为什么在本教程中涵盖的最重要的安全功能是防火墙,因为它可以阻止未知用户首先登录到您的服务器。
如果您尝试在不受信任的网络上保护Redis通信,您将不得不使用SSL代理,正如Redis开发人员在 官方Redis安全指南中推荐的那样。
Source:
https://www.digitalocean.com/community/tutorials/how-to-install-and-secure-redis-on-rocky-linux-8