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