如何在Ubuntu14.04上保护您的Redis安装
介绍
Redis 是一种内存中的 NoSQL 键值缓存和存储,也可以持久化到磁盘。
本教程展示了如何为 Redis 服务器实现基本安全性。
但是,请记住,Redis 是为 受信任的客户端 在 受信任的环境 中使用而设计的,它本身没有强大的安全功能。 为了强调这一点,这里引用 官方 Redis 网站 的一段话:
Redis 旨在由受信任环境中的受信任客户端访问。 这意味着通常将 Redis 实例直接暴露给 Internet 或者通常暴露给不受信任的客户端可以直接访问 Redis TCP 端口或 UNIX 套接字的环境不是一个好主意。
. . .
通常,Redis 并未针对最大安全性进行优化,而是针对最大性能和简单性进行了优化。
没有安全性的性能和简单性是灾难的根源。 即使是 Redis 的少数安全功能,也确实没什么值得称赞的。 其中包括:基本的未加密密码,以及命令重命名和禁用。 它缺乏真正的访问控制系统。
但是,配置现有的安全功能仍然是让您的数据库不安全的一大步。
在本教程中,您将了解如何配置 Redis 具有的一些安全功能,以及一些其他系统安全功能,这些功能将提高 Ubuntu 14.04 上独立 Redis 安装的安全状态。
请注意,本指南不涉及 Redis 服务器和客户端应用程序位于不同主机或不同数据中心的情况。 Redis 流量必须穿过不安全或不受信任的网络的安装需要一组完全不同的配置,例如在 Redis 机器之间设置 SSL 代理或 VPN,除了此处给出的配置。
先决条件
对于本教程,您需要:
- 添加了 sudo 用户的 Ubuntu 14.04 服务器,来自 初始服务器设置
- 使用 this iptables guide 配置的 iptables,通过 (可选)更新名称服务器 步骤(如果您不执行名称服务器配置部分,APT 将无法工作)。 配置名称服务器后,您就完成了
- Redis 已安装并使用 this Redis guide 中的仅主安装中的说明进行工作,直至 步骤 2 — 配置 Redis 主 步骤
第 1 步 - 验证 Redis 是否正在运行
首先使用 SSH 登录到您的服务器:
ssh username@server-ip-address
要检查 Redis 是否正常工作,请使用 Redis 命令行。 redis-cli
命令用于访问 Redis 命令行。
redis-cli
如果你已经为 Redis 设置了密码,连接后必须 auth
。
auth your_redis_password
输出
OK
测试数据库服务器:
ping
回复:
输出
PONG
出口:
quit
第 2 步 — 使用 iptables 保护服务器
如果您遵循 iptables 的先决条件,请随意跳过此步骤。 或者,您现在可以这样做。
Redis 只是一个在您的服务器上运行的应用程序,并且由于它自己没有真正的安全功能,因此真正保护它的第一步是首先保护它运行的服务器。
对于像 Ubuntu 14.04 服务器这样的面向公众的服务器,按照 this iptables guide 中给出的配置防火墙是第一步。 点击该链接并立即设置您的防火墙。
如果您使用该指南实施了防火墙规则,则无需为 Redis 添加额外规则,因为默认情况下,除非明确允许,否则所有传入流量都会被丢弃。 由于 Redis 服务器的默认独立安装仅在环回接口(127.0.0.1 或 localhost)上侦听,因此无需担心其默认端口上的传入流量。
如果您需要专门为 Redis 允许 IP 地址,您可以通过 grep
来检查 Redis 正在侦听的 IP 地址以及它绑定到的端口 - 执行 netstat
命令的输出. 第四列——此处为 127.0.0.1:6379——表示与 Redis 关联的 IP 地址和端口组合:
sudo netstat -plunt | grep -i redis
输出
tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 8562/redis-server 1
确保您的防火墙策略中允许此 IP 地址。 有关如何添加规则的更多信息,请参阅这篇 iptables 基础文章。
第 3 步 - 绑定到 localhost
默认情况下,Redis 服务器只能从 localhost 访问。 但是,如果您按照教程设置 Redis 主服务器,则更新了配置文件以允许从任何地方进行连接。 这不如绑定到 localhost 安全。
打开 Redis 配置文件进行编辑:
sudo nano /etc/redis/redis.conf
找到此行并确保它未注释(如果存在则删除 #
):
/etc/redis/redis.conf
bind 127.0.0.1
我们将继续使用这个文件,所以暂时保持打开状态。
第 4 步 — 配置 Redis 密码
如果您使用 如何在 Ubuntu 14.04 上配置 Redis 集群一文安装了 Redis,您应该已经为其配置了密码。 根据您的判断,您现在可以按照本节操作来设置更安全的密码。 如果不是,本节中的说明显示如何设置数据库服务器密码。
配置 Redis 密码可启用其两个内置安全功能之一 - auth
命令,该命令需要客户端进行身份验证才能访问数据库。 密码直接在 Redis 的配置文件 /etc/redis/redis.conf
中配置,您应该仍然在上一步中打开该文件。
滚动到 SECURITY
部分并查找注释指令,内容如下:
/etc/redis/redis.conf
# requirepass foobared
通过删除 #
取消注释,并将 foobared
更改为非常强且非常长的值。
您可以使用 apg
或 pwgen
之类的工具生成密码,而不是自己编写密码。 如果您不想安装应用程序只是为了生成密码,您可以使用下面的单行。 要生成与生成的密码不同的密码,请更改引号中的单词。
echo "digital-ocean" | sha256sum
您的输出应类似于:
输出
960c3dac4fa81b4204779fd16ad7c954f95942876b9c4fb1a255667a9dbe389d
虽然生成的密码不会发音,但它会为您提供一个非常强大且非常长的密码,这正是 Redis 所需的密码类型。 将该命令的输出复制并粘贴为 requirepass
的新值后,应显示为:
/etc/redis/redis.conf
requirepass 960c3dac4fa81b4204779fd16ad7c954f95942876b9c4fb1a255667a9dbe389d
如果您喜欢较短的密码,请改用以下命令的输出。 再次,更改引号中的单词,使其不会生成与此相同的密码:
echo "digital-ocean" | sha1sum
这次你会得到更短的输出:
输出
10d9a99851a411cdae8c3fa09d7290df192441a9
设置密码后,保存文件,重启Redis:
sudo service redis-server restart
要测试密码是否有效,请访问 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 命令。
第 5 步 - 重命名危险命令
Redis 内置的其他安全功能允许您重命名或完全禁用某些被认为是危险的命令。
当由未经授权的用户运行时,此类命令可用于重新配置、销毁或以其他方式擦除您的数据。 与验证密码一样,重命名或禁用命令在 /etc/redis/redis.conf
文件的相同 SECURITY
部分中配置。
一些已知危险的命令包括:FLUSHDB、FLUSHALL、KEYS、PEXPIRE、DEL[X138X ], CONFIG, SHUTDOWN, BGREWRITEAOF, BGSAVE, SAVE, SPOP, SREM、RENAME 和 DEBUG。 这不是一个完整的列表,但重命名或禁用该列表中的所有命令是一个很好的起点。
是否禁用或重命名命令是特定于站点的。 如果您知道您永远不会使用可能被滥用的命令,那么您可以禁用它。 否则,重命名它。
要启用或禁用 Redis 命令,请再次打开配置文件进行编辑:
sudo nano /etc/redis/redis.conf
这些都是例子。 您应该选择禁用或重命名对您有意义的命令。 您可以自己检查命令并确定它们可能会如何被滥用 redis.io/命令 .
要禁用或终止命令,只需将其重命名为空字符串,如下所示:
/etc/redis/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/redis.conf
rename-command CONFIG "" rename-command SHUTDOWN SHUTDOWN_MENOT rename-command CONFIG ASC12_CONFIG
保存您的更改。
重命名命令后,通过重新启动 Redis 应用更改:
sudo service redis-server restart
要测试新命令,请输入 Redis 命令行:
redis-cli
然后,假设您将 CONFIG 命令重命名为 ASC12_CONFIG,以下输出显示如何测试新命令是否已应用。
认证后:
auth your_redis_password
输出
OK
第一次尝试使用 config
命令应该会失败,因为它已被重命名。
config get requirepass
输出
(error) ERR unknown command 'config'
调用重命名的命令应该是成功的(它不区分大小写):
asc12_config get requirepass
输出
1) "requirepass" 2) "your_redis_password"
最后,可以从redis-cli
退出:
exit
注意:如果您已经在使用 Redis 命令行,然后重新启动 Redis,则需要重新进行身份验证。 否则,如果您键入命令,您将收到此错误:
输出
NOAUTH Authentication required.
关于重命名命令,在 /etc/redis/redis.conf
的 SECURITY
部分末尾有一个警告声明,内容如下:
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 文件没有被传输到从站,那么应该没有问题。
因此,当您尝试重命名命令时请记住这一点。 重命名命令的最佳时间是不使用 AOF 持久性时,或者在安装之后,即在使用 Redis 的应用程序部署之前。
当您使用 AOF 并处理主从安装时,请考虑项目 GitHub 问题页面中的这个答案。 以下是对作者问题的回复:
命令会记录到 AOF 并以与发送相同的方式复制到从属设备,因此如果您尝试在没有相同重命名的实例上重放 AOF,您可能会遇到不一致,因为无法执行命令(奴隶也一样)。
因此,在这种情况下处理重命名的最佳方法是确保将重命名的命令应用于主从安装中的所有实例。
第 6 步 — 设置数据目录所有权和文件权限
在此步骤中,我们将考虑您可以进行的一些所有权和权限更改,以改进 Redis 安装的安全配置文件。 这涉及确保只有需要访问 Redis 的用户才有权读取其数据。 默认情况下,该用户是 redis 用户。
您可以通过 grep
-ing 在其父目录的长列表中对 Redis 数据目录进行验证。 该命令及其输出如下所示。
ls -l /var/lib | grep redis
输出
drwxr-xr-x 2 redis redis 4096 Aug 6 09:32 redis
可以看到 Redis 数据目录归 redis 用户所有,二级访问权限授予 redis 组。 那部分很好。
不是文件夹的权限,即 755。 为确保只有 Redis 用户可以访问该文件夹及其内容,请将权限更改为 700:
sudo chmod 700 /var/lib/redis
您应该更改的另一个权限是 Redis 配置文件的权限。 默认情况下,它的文件权限为 644,由 root 拥有,由 root 组拥有第二所有权:
ls -l /etc/redis/redis.conf
输出
-rw-r--r-- 1 root root 30176 Jan 14 2014 /etc/redis/redis.conf
该权限 (644) 是世界可读的,这不是一个好主意,因为它包含在步骤 4 中配置的未加密密码。
我们需要更改所有权和权限。 理想情况下,它应该由 redis 用户拥有,由 root 用户拥有第二所有权。 为此,请运行以下命令:
sudo chown redis:root /etc/redis/redis.conf
然后更改所有权,以便只有文件的所有者可以读取和/或写入它:
sudo chmod 600 /etc/redis/redis.conf
您可以使用以下方法验证新的所有权和权限:
ls -l /etc/redis/redis.conf
输出
total 40 -rw------- 1 redis root 29716 Sep 22 18:32 /etc/redis/redis.conf
最后,重启 Redis:
sudo service redis-server restart
结论
请记住,一旦有人登录到您的服务器,就很容易绕过我们设置的特定于 Redis 的安全功能。 因此,最重要的安全功能是让您很难越过这道栅栏。
那应该是你的防火墙。
要将您的服务器安全性提升到一个新的水平,您可以配置一个入侵检测系统,如 OSSEC。 要在 Ubuntu 14.04 上配置 OSSEC,请参阅 this OSSEC guide。
如果您尝试通过不受信任的网络保护 Redis 通信,则必须使用 SSL 代理,正如 Redis 开发人员在 官方 Redis 安全指南 中推荐的那样。 设置 SSL 代理以保护 Redis 通信是一个单独的主题。
我们没有在重命名部分包含完整的 Redis 命令列表。 但是,您可以自己检查并确定它们可能如何在 redis.io/commands 上被滥用。