介绍
Redis是一种开源的内存数据结构存储,擅长缓存。作为一个非关系型数据库,Redis 以其灵活性、性能、可扩展性和广泛的语言支持而闻名。
Redis 旨在供受信任环境中受信任的客户端使用,并且自身没有强大的安全功能。但是,Redis 确实具有一些安全功能,包括基本的未加密密码以及命令重命名和禁用。本教程提供了有关如何配置这些安全功能的说明,还介绍了一些其他设置,可以提高 CentOS 7 上独立 Redis 安装的安全性。
请注意,本指南不涉及 Redis 服务器和客户端应用程序位于不同主机或不同数据中心的情况。Redis 流量必须穿越不安全或不受信任的网络的安装将需要一组不同的配置,例如在 Redis 机器之间设置 SSL 代理或VPN。
先决条件
要学习本教程,您需要:
- 使用我们的 CentOS 7 初始服务器设置配置的一个 CentOS 7 Droplet 。
- 使用本指南安装和配置 Firewalld ,直至并包括“打开防火墙”步骤。
有了这些先决条件,我们就可以安装 Redis 并执行一些初始配置任务。
第 1 步 – 安装 Redis
在我们安装 Redis 之前,我们必须首先将Extra Packages for Enterprise Linux (EPEL) 存储库添加到服务器的软件包列表中。EPEL 是一个包含许多开源附加软件包的软件包存储库,其中大部分由 Fedora 项目维护。
我们可以使用yum
以下方法安装 EPEL :
- sudo yum install epel-release
EPEL 安装完成后,您可以安装 Redis,再次使用yum
:
- sudo yum install redis -y
这可能需要几分钟才能完成。安装完成后,启动Redis服务:
- sudo systemctl start redis.service
如果您希望 Redis 在启动时启动,可以使用以下enable
命令启用它:
- sudo systemctl enable redis
您可以通过运行以下命令来检查 Redis 的状态:
- sudo systemctl status redis.service
Output● redis.service - Redis persistent key-value database
Loaded: loaded (/usr/lib/systemd/system/redis.service; disabled; vendor preset: disabled)
Drop-In: /etc/systemd/system/redis.service.d
└─limit.conf
Active: active (running) since Thu 2018-03-01 15:50:38 UTC; 7s ago
Main PID: 3962 (redis-server)
CGroup: /system.slice/redis.service
└─3962 /usr/bin/redis-server 127.0.0.1:6379
一旦确认 Redis 确实在运行,请使用以下命令测试设置:
- redis-cli ping
这应该PONG
作为响应打印。如果是这种情况,则意味着您现在在服务器上运行了 Redis,我们可以开始对其进行配置以增强其安全性。
第 2 步 – 绑定 Redis 并使用防火墙保护它
保护 Redis 的一种有效方法是保护它运行的服务器。为此,您可以确保 Redis 仅绑定到本地主机或私有 IP 地址,并且服务器已启动并运行防火墙。
但是,如果您选择使用本教程设置 Redis 集群,那么您将更新配置文件以允许来自任何地方的连接,这不像绑定到 localhost 或私有 IP 那样安全。
要解决此问题,请打开 Redis 配置文件进行编辑:
- sudo vi /etc/redis.conf
找到以 开头的行bind
并确保它没有被注释:
bind 127.0.0.1
如果您需要将 Redis 绑定到另一个 IP 地址(例如您将从单独的主机访问 Redis 的情况),我们强烈建议您将其绑定到一个私有 IP 地址。绑定到公共 IP 地址会增加您的 Redis 接口对外界的暴露。
bind your_private_ip
如果您已遵循先决条件并在您的服务器上安装了 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),因为这些规则将自动应用于该连接。
如果您选择使用 Iptables 设置防火墙,则需要使用以下命令授予辅助主机访问 Redis 正在使用的端口的权限:
- sudo iptables -A INPUT -i lo -j ACCEPT
- sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
- sudo iptables -A INPUT -p tcp -s client_servers_private_IP/32 --dport 6379 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
- sudo iptables -P INPUT DROP
确保使用您的发行版提供的机制保存您的 Iptables 防火墙规则。您可以通过查看我们的Iptables 基本指南了解有关 Iptables 的更多信息。
请记住,使用任一防火墙工具都可以。重要的是防火墙已启动并正在运行,以便未知人员无法访问您的服务器。在下一步中,我们将配置 Redis 以使其只能使用强密码访问。
第 3 步 – 配置 Redis 密码
如果您使用如何在 CentOS 7 上配置 Redis 集群教程安装了 Redis,您应该已经为其配置了密码。根据您的判断,您现在可以按照本节设置一个更安全的密码。如果您尚未设置密码,本节中的说明将显示如何设置数据库服务器密码。
配置 Redis 密码可启用其内置安全功能之一——auth
命令——要求客户端在被允许访问数据库之前进行身份验证。和bind
设置一样,密码是直接在Redis的配置文件中配置的,/etc/redis.conf
. 重新打开该文件:
- sudo vi /etc/redis.conf
滚动到该SECURITY
部分并查找注释指令,内容如下:
# requirepass foobared
通过删除 取消注释#
,然后更改foobared
为您选择的非常强的密码。您可以使用诸如apg
或 之类的工具pwgen
来生成密码,而不是自己编造密码。但是,如果您不想安装应用程序只是为了生成密码,则可以使用以下命令。
请注意,按写入的方式输入此命令将每次生成相同的密码。要创建与生成的密码不同的密码,请将引号中的单词更改为任何其他单词或短语。
- echo "digital-ocean" | sha256sum
虽然生成的密码不会发音,但它是一个非常强大且非常长的密码,这正是 Redis 所需的密码类型。复制并粘贴该命令的输出作为 的新值后requirepass
,它应为:
requirepass password_copied_from_output
如果您更喜欢较短的密码,请改用以下命令的输出。同样,更改引号中的单词,使其不会生成与此相同的密码:
- echo "digital-ocean" | sha1sum
设置密码后,保存并关闭文件,然后重启Redis:
- sudo systemctl restart redis.service
要测试密码是否有效,请访问 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,则在没有 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 vi /etc/redis.conf
注意:这些是示例。您应该选择禁用或重命名对您有意义的命令。您可以在redis.io/commands 上自行检查命令并确定它们可能如何被滥用。
要禁用或终止命令,只需将其重命名为空字符串,如下所示:
# 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 CONFIG ""
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'
调用重命名的命令应该会成功(不区分大小写):
- asc12_config get requirepass
Output1) "requirepass"
2) "your_redis_password"
最后,您可以退出redis-cli
:
- exit
请注意,如果您已经在使用 Redis 命令行,然后重新启动 Redis,则需要重新进行身份验证。否则,如果您键入命令,您将收到此错误:
OutputNOAUTH Authentication required.
关于重命名命令,文件中该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 并处理主从安装时,请考虑项目的 GitHub 问题页面中的此答案。以下是对作者问题的回复:
命令记录到 AOF 并以与发送它们相同的方式复制到从属设备,因此如果您尝试在没有相同重命名的实例上重放 AOF,您可能会面临不一致,因为命令无法执行(奴隶也一样)。
在这种情况下处理重命名的最佳方法是确保重命名的命令应用于主从安装的所有实例。
步骤 5 — 设置数据目录所有权和文件权限
在此步骤中,我们将考虑您可以进行的一些所有权和权限更改,以改进 Redis 安装的安全配置文件。这涉及确保只有需要访问 Redis 的用户才有权读取其数据。默认情况下,该用户是redis用户。
您可以通过grep
-ing 在其父目录的长列表中对 Redis 数据目录进行验证。命令及其输出如下所示。
- ls -l /var/lib | grep redis
Outputdrwxr-xr-x 2 redis redis 4096 Aug 6 09:32 redis
可以看到Redis数据目录归redis用户所有,二级访问权限授予redis组。此所有权设置是安全的,但文件夹的权限(设置为 755)不安全。要确保只有 Redis 用户可以访问文件夹及其内容,请将权限设置更改为 770:
- sudo chmod 770 /var/lib/redis
您应该更改的另一个权限是 Redis 配置文件的权限。默认情况下,它的文件权限为 644 并且由root拥有,由root组拥有二级所有权:
- ls -l /etc/redis.conf
Output-rw-r--r-- 1 root root 30176 Jan 14 2014 /etc/redis.conf
该权限 (644) 是全球可读的。这会带来安全问题,因为配置文件包含您在第 4 步中配置的未加密密码,这意味着我们需要更改配置文件的所有权和权限。理想情况下,它应该由redis用户拥有,redis组拥有二级所有权。为此,请运行以下命令:
- sudo chown redis:redis /etc/redis.conf
然后更改权限,以便只有文件的所有者可以读取和/或写入它:
- sudo chmod 600 /etc/redis.conf
您可以使用以下方法验证新的所有权和权限:
- ls -l /etc/redis.conf
Outputtotal 40
-rw------- 1 redis redis 29716 Sep 22 18:32 /etc/redis.conf
最后,重启Redis:
- sudo systemctl restart redis.service
恭喜,您的 Redis 安装现在应该更安全了!
结论
请记住,一旦有人登录到您的服务器,就很容易绕过我们已实施的特定于 Redis 的安全功能。这就是本教程中介绍的最重要的安全功能是防火墙的原因,因为它首先可以防止未知用户登录您的服务器。
如果您试图在不受信任的网络上保护 Redis 通信,则必须按照 Redis 开发人员在官方 Redis 安全指南中的建议使用 SSL 代理。