如何在Ubuntu 18.04上保护您的Redis安装

内存中的Redis,NoSQL,键值缓存和存储,内置了一些安全功能。本教程将介绍如何通过设置身份验证密码并重命名潜在危险的命令来保护Redis安装。

介绍

Redis是内存中的NoSQL,键值缓存和存储,也可以保存到磁盘。 它专为 信任环境中 受信任的客户端使用而设计,没有自己的强大安全功能。 为了强调这一点,下面是Redis官方网站的一段引文:

Redis被设计为可信赖环境中的可信客户访问。 这意味着通常将Redis实例直接暴露给互联网,或者通常不受信任的客户端可以直接访问Redis TCP端口或UNIX套接字的环境并不是一个好主意。

一般来说,Redis没有针对最高安全性进行优化,但却具有最高的性能和简单性。

尽管如此,Redis确实有一些内置的基本安全功能。 这些包括创建未加密密码的能力以及重命名和禁用命令的自由。 值得注意的是,它缺乏真正的门禁系统。

这些功能本身不能确保您的Redis安装的安全性。 但是,配置它们仍然是使数据库完全不安全的一大步。

在本教程中,您将了解如何配置Redis提供的少数安全功能,并对系统配置进行一些更改,这将增强Ubuntu服务器上独立Redis安装的安全状况。

请注意,本指南不涉及Redis服务器和客户端应用程序位于不同主机或不同数据中心的情况。 Redis流量必须遍历不安全或不可信网络的安装需要一套完全不同的配置,例如在Redis机器之间设置SSL代理或VPN ,以及此处给出的配置。

先决条件

对于本教程,您需要:

第1步 - 验证Redis正在运行

首先,使用非root用户将SSH连接到您的服务器。

要检查Redis是否正在运行,请使用redis-cli命令打开Redis命令行:

redis-cli

注意 :如果您已经为Redis设置了密码,则必须在连接后使用auth命令进行身份验证:

auth your_redis_password
OK

如果您尚未为Redis设置密码,则可以在本教程的第4步中阅读该如何操作。

ping命令测试连接:

ping

如果Redis正常工作,您将看到以下内容:

PONG

在此之后,退出Redis命令行:

quit

既然您已确认Redis正在运行并正常工作,那么您可以继续执行增强服务器安全性的最重要步骤:配置防火墙。

第2步 - 用UFW保护服务器

Redis只是一个在您的服务器上运行的应用程序。 因为它只有自己的一些基本安全功能,所以真正保护它的第一步是保护它运行的服务器。 对于像Ubuntu 18.04服务器这样的面向公众的服务器,按照Ubuntu 18.04初始服务器安装指南中的描述配置防火墙就是第一步。 如果您尚未这样做,请按照该链接并设置您的防火墙。

如果您不确定是否设置了防火墙或其是否处于活动状态,则可以通过运行以下命令来检查:

sudo ufw status

如果您遵循了Ubuntu 18.04的初始服务器安装指南,您将看到以下输出:

Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere                  
OpenSSH (v6)               ALLOW       Anywhere (v6)             

如果您已经使用该指南实施了防火墙规则,那么您无需为Redis添加额外的规则,因为默认情况下,UFW会丢弃所有传入流量,除非明确允许。 由于Redis服务器的默认独立安装仅在回送接口( 127.0.0.1localhost )上进行监听,因此不应该在其默认端口上关注传入流量。

有关如何添加规则的更多信息,请参阅本指南关于常见的UFW规则和命令

第3步 - 绑定到本地主机

默认情况下,Redis只能从本地主机访问。 但是,如果您按照不同的教程来配置Redis,而不是在先决条件部分中给出的教程,则可能已更新配置文件以允许从任何地方进行连接。 这不像绑定到localhost那样安全。

打开Redis配置文件进行编辑:

sudo nano /etc/redis/redis.conf

找到这一行并确保它没有注释(删除#如果存在):

/etc/redis/redis.conf
bind 127.0.0.1

完成后保存并关闭文件(按CTRL + XY ,然后按ENTER )。

然后,重新启动服务以确保systemd读取您的更改:

sudo systemctl restart redis

要检查此更改是否已生效,请运行以下netstat命令:

sudo netstat -lnp | grep redis
tcp        0      0 127.0.0.1:6379          0.0.0.0:*               LISTEN      2855/redis-server 1

此输出显示redis-server程序绑定到localhost127.0.0.1 ),反映您刚才对配置文件所做的更改。 如果您在该列中看到另一个IP地址(例如, 0.0.0.0 ),则应该仔细检查是否取消注释了正确的行并重新启动Redis服务。

既然您的Redis安装只能在本地主机上进行监听,那么对于恶意角色来说,请求或访问您的服务器将更加困难。 但是,Redis目前并未设置为要求用户在对其配置或其所拥有的数据进行更改之前进行身份验证。 为了弥补这一点,Redis允许您在通过Redis客户端( redis-cli )进行更改之前要求用户使用密码进行身份验证。

第4步 - 配置Redis密码

配置Redis密码将启用其两个内置安全功能之一 - auth命令,该命令需要客户端进行身份验证才能访问数据库。 密码直接在Redis的配置文件/etc/redis/redis.conf配置,因此请使用您的首选编辑器再次打开该文件:

sudo nano /etc/redis/redis.conf

滚动到SECURITY部分并查找注释如下的指令:

/etc/redis/redis.conf
# requirepass foobared

通过删除#取消注释,并将其更改为安全密码。

注意:redis.conf文件中的requirepass指令redis.conf ,有一条注释警告:

/etc/redis/redis.conf
# Warning: since Redis is pretty fast an outside user can try up to
# 150k passwords per second against a good box. This means that you should
# use a very strong password otherwise it will be very easy to break.
#

因此,指定一个非常强大和非常长的值作为密码很重要。 您可以使用openssl命令生成一个随机的密码,而不是自己openssl密码,如下例所示。 到第二个openssl命令的管道将删除由第一个命令输出的任何换行符:

openssl rand 60 | openssl base64 -A

你的输出应该如下所示:

RBOJ9cCNoGCKhlEBwQLHri1g+atWgn4Xn4HwNUbtzoVxAYxkiYBi7aufl4MILv1nxBqR4L6NNzI0X6cE

在复制并粘贴该命令的输出作为requirepass的新值requirepass ,它应为:

requirepass RBOJ9cCNoGCKhlEBwQLHri1g+atWgn4Xn4HwNUbtzoVxAYxkiYBi7aufl4MILv1nxBqR4L6NNzI0X6cE

设置密码后,保存文件并重新启动Redis:

sudo systemctl restart redis.service

要测试密码是否有效,请访问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新密钥的值。

get key1
"10"

在确认您能够在认证后在Redis客户端中运行命令后,您可以退出redis-cli

quit

接下来,我们将重新命名Redis命令,如果错误输入或恶意演员输入,可能会对您的机器造成严重损坏。

第5步 - 重命名危险命令

Redis内置的另一个安全功能涉及重命名或完全禁用某些被认为危险的命令。

当错误或未经授权的用户运行时,这些命令可用于重新配置,销毁或以其他方式擦除数据。 与验证密码一样,重命名或禁用命令也是在/etc/redis/redis.conf文件的同一SECURITY部分中配置的。

一些被认为是危险的命令包括: FLUSHDBFLUSHALLKEYSPEXPIREDELCONFIGSHUTDOWNBGREWRITEAOFBGSAVESAVESPOPSREMRENAMEDEBUG 这不是一个全面的列表,但重命名或禁用该列表中的所有命令对于增强Redis服务器的安全性来说是一个很好的起点。

您是否应该禁用或重命名命令取决于您的特定需求或您的站点的特定需求。 如果你知道你永远不会使用可能被滥用的命令,那么你可以禁用它。 否则,重命名它可能是最有利的。

要启用或禁用Redis命令,请再次打开配置文件:

sudo nano /etc/redis/redis.conf

警告:以下显示如何禁用和重命名命令的步骤是示例。 您只应选择禁用或重命名对您有意义的命令。 您可以查看完整的命令列表,并确定它们在redis.io/commands中的使用方式

要禁用某个命令,只需将其重命名为一个空字符串(由一对引号表示,而其间没有其他字符),如下所示:

/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 systemctl restart redis.service

要测试新命令,请输入Redis命令行:

redis-cli

接下来,验证:

auth your_redis_password
OK

假设您将CONFIG命令重命名为ASC12_CONFIG ,如上例所示。 首先,尝试使用原始的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.

注意: Redis项目选择使用术语“主”和“从属”,而DigitalOcean通常更倾向于选择“主要”和“次要”。为避免混淆,我们选择使用Redis文档中使用的术语这里。

这意味着,如果重命名的命令不在AOF文件中,或者如果它是,但AOF文件没有传输到从机,那么应该没有问题。

因此,当您尝试重命名命令时请记住这一点。 重命名命令的最佳时机是在不使用AOF持久性时,或在安装之后,即在部署了Redis使用应用程序之前。

当您使用AOF并处理主从安装时,请从项目的GitHub问题页面中考虑此答案 以下是对作者问题的回复:

这些命令会记录到AOF并以与发送方式相同的方式复制到从机,所以如果您尝试在不具有相同重命名的实例上重播AOF,则可能会遇到不一致情况,因为命令无法执行(同样的Minion)。

因此,在这种情况下处理重命名的最佳方式是确保重命名的命令应用于主从安装中的所有实例。

结论

请记住,一旦有人登录到您的服务器,就很容易规避我们实施的Redis特有的安全功能。 因此,最重要的安全功能是防火墙,这使得恶意演员非常难以跳过这一篱笆。

如果您尝试通过不可信网络保护Redis通信,则必须采用SSL代理,正如Redis 官方Redis安全指南中的Redis开发人员所建议的那样。