Rocky Linux 8上安装与安全配置Redis:完整指南
Redis简介与安装准备
Redis是一个开源的、内存中的键值数据存储,尤其擅长缓存。作为一种非关系型数据库,Redis以其灵活性、高性能、可扩展性以及广泛的语言支持而闻名。
Redis设计之初是为可信客户端在可信环境中使用,因此其自身不具备健全的安全功能。然而,Redis确实提供了一些安全特性,例如密码身份验证以及重命名或禁用部分命令的能力。本教程将指导您如何在Rocky Linux 8上安装Redis并配置这些安全功能。此外,我们还将介绍一些其他设置,以增强独立Redis安装的安全性。
请注意,本指南不涵盖Redis服务器和客户端应用程序位于不同主机或不同数据中心的情况。在Redis流量必须穿越不安全或不可信网络的部署中,需要进行一套不同的配置,例如设置SSL代理或在Redis机器之间建立VPN。
您也可以考虑使用Silicon Cloud的托管Redis服务。
先决条件
为了完成本教程,您需要一台运行Rocky Linux 8的服务器。该服务器应配置一个具有管理员权限的非root用户,并已设置防火墙(firewalld)。如需设置,请参考我们的Rocky Linux 8初始服务器设置指南。
第一步:安装和启动Redis
您可以使用DNF软件包管理器安装Redis。通过DNF,您可以安装Redis及其依赖项,同时也可以安装一个用户友好的文本编辑器nano。虽然安装nano并非强制,但本指南中我们将使用它进行示例演示。
- sudo dnf install redis nano
此命令会提示您确认是否安装所选软件包。请按下y
键,然后按回车键进行确认。
输出
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”指令。此指令允许您声明一个初始化系统来管理Redis作为服务,并为您提供更多对其操作的控制。默认情况下,“supervised”指令的设置为“no”。由于您正在运行使用systemd初始化系统的Rocky Linux,请将其更改为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配置文件做出的唯一更改,所以完成后请保存并关闭。如果您使用nano编辑文件,可以使用CTRL + X
来保存并退出,然后按提示选择Y
键,最后按Enter
键。
编辑文件后,启动Redis服务:
- sudo systemctl start redis.service
如果您希望Redis在启动时自动运行,可以使用enable
命令来启用它:
- sudo systemctl enable redis
请注意,此命令在单元文件名后面没有包含“.service”后缀。通常情况下,您可以在systemctl命令中省略这个后缀,因为它能从服务名称中自动解析出来。
您可以通过运行以下命令来检查Redis的状态:
- sudo systemctl status redis
输出
● 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”作为响应。
输出
PONG
如果显示“PONG”,则表示您现在已在服务器上成功运行Redis,可以开始配置它以增强其安全性。
第二步:配置Redis并通过防火墙保护
保护Redis的一种有效方法是确保其运行的服务器安全。您可以通过确保Redis仅绑定到localhost或私有IP地址,并且服务器运行着防火墙来实现这一点。
如果您选择使用其他教程来设置Redis,那么您可能已经更新了配置文件以允许任意位置的连接。这不如绑定到本地主机或私有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区域。
- 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区域中的规则。所有其他连接将由默认的公共区域处理。默认区域中的服务适用于每个连接,不仅仅是那些没有明确匹配的连接,因此您无需将其他服务(如SSH)添加到Redis区域,因为这些规则将自动应用于该连接。
请记住,您可以使用任何防火墙工具,无论是firewalld
、ufw
还是iptables
。重要的是,防火墙处于启动状态,以防止未经授权的个体访问您的服务器。在下一步中,您将配置Redis,使其只能通过强密码访问。
第三步 — 配置 Redis 密码
在Redis配置文件(/etc/redis.conf
)中重新打开它,配置Redis密码可以启用其内置的安全功能之一——AUTH
命令——该命令要求客户端在被允许访问数据库之前进行身份验证。与bind
设置类似,密码直接配置在Redis的配置文件中。
- sudo nano /etc/redis.conf
滚动到“安全”部分并寻找一条被注释的指令:
/etc/redis.conf
请作出更换。
. . .
# requirepass foobared
取消它的注释,即移除“#”号,并将“foobared”修改为您选择的一个非常强大的密码。
注意:
apg
或pwgen
这样的工具来生成一个。但是,如果您不想安装一个只用来生成密码的应用程序,您可以使用下面的命令。该命令将回显一个字符串值,并将其导入到以下的sha256sum
命令中,该命令将显示字符串的SHA256校验和。
请注意,按原样输入此命令将每次生成相同的密码。要创建一个唯一的密码,请将引号内的字符串更改为任何其他单词或短语:echo "digital-ocean" | sha256sum
虽然生成的密码可能不易记住,但它将非常强大且长,这正是Redis所需的密码类型。在将该命令的输出复制并粘贴为requirepass
的新值之后,它应该是这样的:/etc/redis.conf
. . .
requirepass 密码_从输出中复制
或者,如果您更喜欢一个较短的密码,您可以使用不同校验和的输出。同样,将引号中的单词更改为不会生成与该命令相同密码的单词:echo "digital-ocean" | sha1sum
设置密码后,保存并关闭文件,然后重新启动Redis。
- sudo systemctl restart redis
为了测试密码是否有效,请打开Redis客户端。
- redis-cli
以下是用于测试Redis密码是否有效的命令序列。第一个命令在认证之前尝试将一个键设置为一个值:
- set key1 10
因为您尚未进行验证,所以这样做行不通,Redis会返回一个错误。
输出(error) NOAUTH Authentication required.
以下命令将使用Redis配置文件中指定的密码进行身份验证:
- auth your_redis_password
Redis将会确认您已经通过身份验证。
输出OK
之后,再次运行先前的命令应该会成功。
- set key1 10
输出OK
使用get key1
命令查询Redis中新键的值。
- get key1
输出"10"
最后一个命令是退出redis-cli
。您也可以使用exit
来退出。
- quit
现在,未经授权的用户应该很难访问您的Redis安装。请注意,如果您已经在使用Redis命令行客户端并重新启动Redis,则需要重新进行身份验证。此外,请注意,如果您远程连接到Redis,并且没有使用SSL或VPN,该密码仍可能被外部方拦截。
接下来,本指南将介绍如何重新命名Redis命令,以进一步保护Redis免受恶意用户的攻击。
第四步 – 重命名危险命令
Redis内置的另一个安全功能允许您重命名或完全禁用某些被认为危险的命令。当未经授权的用户运行这些命令时,它们可以用来重新配置、销毁或者清除您的数据。一些被认为危险的命令包括:
- FLUSHDB
- FLUSHALL
- KEYS
- PEXPIRE
- DEL
- CONFIG
- SHUTDOWN
- BGREWRITEAOF
- BGSAVE
- SAVE
- SPOP
- SREM
- RENAME
- DEBUG
这不是一个详尽无遗的列表,但是重新命名或禁用列表中的所有命令可以帮助提升您的数据存储的安全性。是否应禁用或重命名某个命令将取决于您的具体需求。如果您知道您永远不会使用某个可能被滥用的命令,那么您可以禁用它。否则,您应该选择重命名它。
与认证密码一样,重命名或禁用命令是在/etc/redis.conf
文件的安全部分进行配置的。要启用或禁用Redis命令,请再次打开配置文件以进行编辑。
- sudo nano /etc/redis.conf
注意:以下是示例。您可以选择禁用或重命名对您有意义的命令。您可以在 redis.io/commands 了解更多关于 Redis 命令的信息,并确定它们可能如何被滥用。
要禁用或终止一个命令,请将其重命名为空字符串,如下所示:
/etc/redis.conf
。# 也可以通过将其重命名为空字符串来完全禁用一个命令:
#
rename-command FLUSHDB ""
rename-command FLUSHALL ""
rename-command DEBUG ""
要重命名一个命令,请给它一个像下面例子中那样的另一个名字。重命名的命令应该对他人难以猜测,但对您来说易于记住。
/etc/redis.conf
。# 也可以通过将其重命名为空字符串来完全禁用一个命令:
#
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
输出OK
假设您将 CONFIG
命令重命名为 ASC12_CONFIG
,尝试使用 config
命令将会失败。
- config get requirepass
输出(error) ERR unknown command 'config'
调用重命名的命令将会成功。请注意,Redis 命令对大小写不敏感。
- asc12_config get requirepass
输出1) "requirepass"
2) "your_redis_password"
最后,您可以从 redis-cli
退出。
- exit
警告:关于重命名命令,在 /etc/redis.conf
文件的安全部分末尾有一个警示语句,如下所示:
/etc/redis.conf
. . .
# 请注意,将被记录到 AOF 文件中或传输到副本中的命令的名称更改可能会导致问题。
. . .
这意味着如果重命名的命令不在 AOF 文件中,或者如果它在 AOF 文件中但尚未传输到副本,则应该没有问题。在您重命名命令时请记住这一点。在不使用 AOF 持久性或安装后(即在 Redis 使用的应用程序部署之前)是重命名命令的最佳时机。
步骤 5 – 设置数据目录所有权和文件权限
这一步将涉及一些您可能需要进行的所有权和权限更改,以改善您的 Redis 安装的安全配置。这包括确保只有需要访问 Redis 的用户具有读取其数据的权限。默认情况下,这个用户是 redis
用户。
您可以通过在其父目录的长列表中使用 grep
命令来验证这一点,查找 Redis 数据目录。以下是该命令及其输出:
- ls -l /var/lib | grep redis
输出drwxr-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
输出-rw-r-----. 1 redis root 62192 Sep 6 22:20 /etc/redis.conf
权限 (640) 的意思是 Redis 配置文件只能被 redis
用户和 root
用户组读取。由于配置文件包含了在第四步中配置的未加密密码,redis.conf
应该属于 redis
用户,并且有 redis
用户组作为第二属主。要设置这个权限,请运行以下命令:
- sudo chown redis:redis /etc/redis.conf
然后更改文件的权限,使得只有文件的所有者能读取和写入。
- sudo chmod 600 /etc/redis.conf
您可以再次运行以前的 ls
命令来验证新的所有权和权限。
- ls -l /var/lib | grep redis
输出
总计 40
drwxrwx---. 2 redis redis 22 9月 6 22:22 redis
- ls -l /etc/redis.conf
输出
总计 40
-rw-------. 1 redis redis 62192 9月 6 22:20 /etc/redis.conf
最后,重新启动 Redis 以使这些更改生效。
- sudo systemctl restart redis
通过以上步骤,您的 Redis 安装已得到保护。
结论
请记住,一旦有人登录到您的服务器,就有可能绕过您设置的 Redis 特定安全功能。这就是为什么本教程中最重要的安全功能是防火墙,因为它可以阻止未知用户首次登录到您的服务器。
如果您正在尝试在不受信任的网络上保护 Redis 通信,您将需要使用 SSL 代理,正如 Redis 开发者在官方 Redis 安全指南中建议的那样。