介绍
Redis是一种开源的内存键值数据存储,擅长缓存。作为一个非关系型数据库,Redis 以其灵活性、性能、可扩展性和广泛的语言支持而闻名。
Redis 旨在供受信任环境中受信任的客户端使用,并且自身没有强大的安全功能。但是,Redis 确实具有一些安全功能,例如基本的未加密密码以及命令重命名和禁用。本教程提供有关如何安装 Redis 和配置这些安全功能的说明。它还涵盖了一些其他设置,可以提高 CentOS 8 上独立 Redis 安装的安全性。
请注意,本指南不涉及 Redis 服务器和客户端应用程序位于不同主机或不同数据中心的情况。Redis 流量必须穿越不安全或不受信任的网络的安装将需要一组不同的配置,例如在 Redis 机器之间设置 SSL 代理或VPN。
先决条件
要完成本教程,您需要一台运行 CentOS 8 的服务器。该服务器应具有具有管理权限的非 root 用户和配置为firewalld
. 要进行设置,请遵循我们的 CentOS 8 初始服务器设置指南。
第 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
指令。该指令允许您声明一个 init 系统来将 Redis 作为服务进行管理,从而为您提供对其操作的更多控制。该supervised
指令no
默认设置为。由于您正在运行使用systemd init 系统的CentOS,请将其更改为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
命令中去掉,因为它通常在与 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 仅绑定到本地主机或私有 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 服务器,以限制您的服务公开的主机数量。
首先,向您的 firewalld 策略添加一个专用的 Redis 区域:
- sudo firewall-cmd --permanent --new-zone=redis
然后指定您要打开的端口。Redis6379
默认使用端口:
- 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
区域处理。默认区域中的服务适用于每个连接,而不仅仅是那些不明确匹配的服务,因此您无需向 Redis 区域添加其他服务(例如 SSH),因为这些规则将自动应用于该连接。
请记住,使用任何防火墙工具都可以使用firewalld
,无论您使用ufw
、 或iptables
。重要的是防火墙已启动并正在运行,以便未知人员无法访问您的服务器。在下一步中,您将配置 Redis 以使其只能使用强密码访问。
第 3 步 – 配置 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
命令查询 Redis 以获取新键的值:
- 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
这不是一个完整的列表,但重命名或禁用此列表中的所有命令有助于提高数据存储的安全性。您是否应该禁用或重命名给定命令取决于您的特定需求。如果你知道你永远不会使用一个可以被滥用的命令,那么你可以禁用它。否则,您应该重命名它。
与身份验证密码一样,重命名或禁用命令也是在文件SECURITY
部分配置的/etc/redis.conf
。要启用或禁用 Redis 命令,请再次打开配置文件进行编辑:
- sudo nano /etc/redis.conf
注意:这些是示例。您应该选择禁用或重命名对您有意义的命令。您可以在redis.io/commands 上了解有关 Redis 命令的更多信息并确定它们可能如何被滥用。
要禁用或终止命令,请将其重命名为空字符串,如下所示:
# 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 ""
要重命名命令,请给它另一个名称,如下例所示。重命名的命令对于其他人来说应该很难猜到,但对你来说很容易记住:
# 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
警告:关于重命名命令,文件中该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 配置文件的权限。默认情况下,它的文件权限为root640
并由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 代理。