介绍
Redis是一个内存中的键值存储,以其灵活性,性能和广泛的语言支持而闻名。本教程演示如何在Debian 9服务器上安装,配置和保护Redis。
先决条件
要完成本指南,您需要访问Debian 9服务器,该服务器具有sudo
权限非root用户并配置了基本防火墙,如果您使用的是腾讯云的CVM服务器,您可以直接在腾讯云控制台中的安全组进行设置。您可以按照我们的初始服务器设置指南进行设置。
没有服务器的同学可以在这里购买,不过我个人更推荐您使用免费的腾讯云开发者实验室进行试验,学会安装后再购买服务器。
准备好开始时,请以启用sudo的用户身份登录服务器并继续下面的操作。
第1步 - 安装和配置Redis
为了获得最新版本的Redis,我们将使用apt
从官方Debian存储库安装它。
通过键入以下内容更新本地apt
包缓存并安装Redis:
sudo apt update
sudo apt install redis-server
这将下载并安装Redis及其依赖项。在此之后,Redis配置文件中将进行一项重要的配置更改,该文件是在安装期间自动生成的。
使用首选文本编辑器打开此文件:
代码语言:javascript复制sudo nano /etc/redis/redis.conf
在文件中,找到该supervised
指令。该指令允许您声明一个init系统来管理Redis作为服务,使您可以更好地控制其操作。该supervised
指令默认设置为no
。由于您运行的是使用systemd init系统的Debian,因此将其更改为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配置文件进行的唯一更改,因此请在完成后保存并关闭它。然后,重新加载Redis服务文件以反映您对配置文件所做的更改:
代码语言:javascript复制sudo systemctl restart redis
有了这个,你已经安装并配置了Redis,它正在你的机器上运行。但是,在开始使用它之前,首先要检查Redis是否正常运行是明智的。
第2步 - 测试Redis
与任何新安装的软件一样,在对其配置进行任何进一步更改之前,确保Redis按预期运行是个好主意。我们将通过一些方法来检查Redis在此步骤中是否正常工作。
首先检查Redis服务是否正在运行:
代码语言:javascript复制sudo systemctl status redis
如果它正在运行而没有任何错误,则此命令将生成类似于以下内容的输出:
代码语言:javascript复制● redis-server.service - Advanced key-value store
Loaded: loaded (/lib/systemd/system/redis-server.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2018-09-05 20:19:44 UTC; 41s ago
Docs: http://redis.io/documentation,
man:redis-server(1)
Process: 10829 ExecStopPost=/bin/run-parts --verbose /etc/redis/redis-server.post-down.d (code=exited, status=0/SUCCESS)
Process: 10825 ExecStop=/bin/kill -s TERM $MAINPID (code=exited, status=0/SUCCESS)
Process: 10823 ExecStop=/bin/run-parts --verbose /etc/redis/redis-server.pre-down.d (code=exited, status=0/SUCCESS)
Process: 10842 ExecStartPost=/bin/run-parts --verbose /etc/redis/redis-server.post-up.d (code=exited, status=0/SUCCESS)
Process: 10838 ExecStart=/usr/bin/redis-server /etc/redis/redis.conf (code=exited, status=0/SUCCESS)
Process: 10834 ExecStartPre=/bin/run-parts --verbose /etc/redis/redis-server.pre-up.d (code=exited, status=0/SUCCESS)
Main PID: 10841 (redis-server)
Tasks: 3 (limit: 4915)
CGroup: /system.slice/redis-server.service
└─10841 /usr/bin/redis-server 127.0.0.1:6379
. . .
在这里,您可以看到Redis正在运行并且已经启用,这意味着它设置为每次服务器启动时启动。
注意:此设置适用于Redis的许多常见用例。但是,如果您希望每次服务器引导时手动启动Redis,则可以使用以下命令对其进行配置:
代码语言:javascript复制sudo systemctl disable redis
要测试Redis是否正常运行,请使用命令行客户端连接到服务器:
代码语言:javascript复制redis-cli
在随后的提示中,使用以下ping
命令测试连接:
ping
PONG
此输出确认服务器连接仍处于活动状态。接下来,检查您是否可以通过运行来设置密钥:
代码语言:javascript复制set test "It's working!"
OK
键入以下内容检索值:
代码语言:javascript复制get test
假设一切正常,您将能够检索存储的值:
代码语言:javascript复制Output"It's working!"
确认您可以获取该值后,退出Redis提示符以返回到shell:
代码语言:javascript复制exit
作为最终测试,我们将检查Redis是否能够在数据被停止或重新启动后保留数据。要执行此操作,请首先重新启动Redis实例:
代码语言:javascript复制sudo systemctl restart redis
然后再次与命令行客户端连接并确认您的测试值仍然可用:
代码语言:javascript复制redis-cli
get test
您的密钥值仍应可访问:
代码语言:javascript复制"It's working!"
完成后再次退出shell:
代码语言:javascript复制exit
这样,您的Redis安装即可完全运行,随时可供您使用。但是,它的某些默认配置设置不安全,并为恶意攻击者提供攻击和访问服务器及其数据的机会。本教程中的其余步骤涵盖了减轻这些漏洞的方法,正如Redis官方网站所规定的那样。虽然这些步骤是可选的,如果您选择不遵循它们,Redis仍然可以运行,强烈建议您完成它们以加强系统的安全性。
第3步 - 绑定到localhost
默认情况下,只能从localhost访问Redis 。但是,如果您通过遵循与此不同的教程来安装和配置Redis,则可能已更新配置文件以允许来自任何位置的连接。这不如绑定到localhost那样安全。
要更正此问题,请打开Redis配置文件进行编辑:
代码语言:javascript复制sudo nano /etc/redis/redis.conf
找到此行并确保它已取消注释(#
如果存在则删除它):
bind 127.0.0.1
保存并完成后关闭文件(按CTRL X
,Y
之后再ENTER
)。
然后,重新启动服务以确保systemd读取您的更改:
代码语言:javascript复制sudo systemctl restart redis
要检查此更改是否已生效,请运行以下netstat
命令:
sudo netstat -lnp | grep redis
tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 10959/redis-server
此输出显示redis-server
程序绑定到localhost(127.0.0.1
),反映您刚刚对配置文件所做的更改。如果您在该列中看到另一个IP地址(例如0.0.0.0
),则应仔细检查是否取消注释了正确的行并再次重新启动Redis服务。
现在您的Redis安装仅在localhost上进行侦听,恶意攻击者更难以发出请求或访问您的服务器。但是,Redis当前未设置为要求用户在更改其配置或其所拥有的数据之前进行身份验证。为了解决这个问题,Redis允许您在通过Redis客户端(redis-cli
)进行更改之前要求用户使用密码进行身份验证。
第4步 - 配置Redis密码
配置Redis密码可启用其两个内置安全功能之一 - 该auth
命令,该命令要求客户端进行身份验证以访问数据库。密码直接在Redis的配置文件/etc/redis/redis.conf
中配置,因此请使用首选编辑器再次打开该文件:
sudo nano /etc/redis/redis.conf
滚动到该SECURITY
部分并查找注释指令:
# requirepass foobared
通过删除#
来取消注释,并将foobared
更改为安全密码。
注意:在redis.conf
文件中的requirepass
指令上方,有一个注释警告:
# 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 rand 60 | openssl base64 -A
您的输出应该类似于:
代码语言:javascript复制RBOJ9cCNoGCKhlEBwQLHri1g atWgn4Xn4HwNUbtzoVxAYxkiYBi7aufl4MILv1nxBqR4L6NNzI0X6cE
复制并粘贴该命令的输出作为requirepass
的新值后,它应显示为:
requirepass RBOJ9cCNoGCKhlEBwQLHri1g atWgn4Xn4HwNUbtzoVxAYxkiYBi7aufl4MILv1nxBqR4L6NNzI0X6cE
设置密码后,保存并关闭文件,然后重新启动Redis:
代码语言:javascript复制sudo systemctl restart redis.service
要测试密码是否有效,请访问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
OK
get key1
查询Redis以获取新密钥的值。
get key1
"10"
在确认您能够在验证后在Redis客户端中运行命令后,您可以退出redis-cli
:
quit
接下来,我们将介绍重命名Redis命令,如果错误输入或恶意行为者输入,可能会对您的计算机造成严重损害。
第5步 - 重命名危险命令
Redis内置的其他安全功能涉及重命名或完全禁用某些被视为危险的命令。
当由未经授权的用户运行时,此类命令可用于重新配置,销毁或以其他方式擦除数据。与身份验证密码一样,重命名或禁用命令也在/etc/redis/redis.conf
文件的同SECURITY
部分中配置。
一些被认为是危险的命令包括:FLUSHDB,FLUSHALL,KEYS,PEXPIRE,DEL,CONFIG,SHUTDOWN,BGREWRITEAOF,BGSAVE,SAVE,SPOP,SREM,RENAME和DEBUG。这不是一个全面的列表,但重命名或禁用该列表中的所有命令是增强Redis服务器安全性的良好起点。
是否应禁用或重命名命令取决于您的特定需求或站点的需求。如果您知道永远不会使用可能被滥用的命令,那么您可以禁用它。否则,重命名它可能符合您的最佳利益。
要启用或禁用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 systemctl restart redis
要测试新命令,请输入Redis命令行:
代码语言:javascript复制redis-cli
然后,验证:
代码语言:javascript复制auth your_redis_password
OutputOK
假设您将CONFIG
命令重命名为ASC12_CONFIG
,如前面的示例所示。首先,尝试使用原始CONFIG
命令。它应该失败,因为你已经重命名它:
config get requirepass
(error) ERR unknown command 'config'
但是,调用重命名的命令将会成功。它不区分大小写:
代码语言:javascript复制asc12_config get requirepass
1) "requirepass"
2) "your_redis_password"
最后,您可以退出redis-cli
:
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.
注意: Redis项目选择使用术语“master”和“slave”,而DigitalOcean通常更喜欢替代描述符。为了避免混淆,我们选择使用Redis文档中使用的术语。
这意味着如果重命名的命令不在AOF文件中,或者如果它是但AOF文件尚未传输给从属,则应该没有问题。
因此,在尝试重命名命令时请记住这一点。重命名命令的最佳时间是在您不使用AOF持久性时,或者在安装后,即在部署Redis-using应用程序之前。
当您使用AOF并处理主从安装时,请从项目的GitHub问题页面中考虑此答案。以下是对作者问题的回复:
这些命令记录到AOF并以与发送方式相同的方式复制到从站,因此如果您尝试在没有相同重命名的实例上重放AOF,则可能会因为命令无法执行而面临不一致(奴隶一样)。
因此,在这种情况下处理重命名的最佳方法是确保重命名的命令应用于主从安装中的所有实例。
结论
在本教程中,您安装并配置了Redis,验证了Redis安装是否正常运行,并使用其内置的安全功能使其不易受到恶意攻击者的攻击。
请记住,一旦有人登录到您的服务器,就很容易绕过我们已经实施的Redis特定的安全功能。因此,Redis服务器上最重要的安全功能是防火墙(如果您遵循先决条件初始服务器安装教程,则配置了防火墙),因为这使得恶意攻击者很难跳过该防火墙。
更多Debian教程请前往腾讯云 社区学习更多知识。
参考文献:《How To Install and Secure Redis on Debian 9》