介绍
托管Redis实例可以提供高可用性和自动更新等优势。但是,任何时候您连接到远程数据库服务器时,您都会冒着恶意行为者嗅探您发送给它的敏感信息的风险。
redis-cli
,Redis 命令行界面,本身不支持通过TLS 的连接,TLS是一种允许通过网络进行安全通信的加密协议。这意味着没有进一步配置,redis-cli
不是连接到远程 Redis 服务器的安全方式。与托管 Redis 实例建立安全连接的一种方法是创建使用 TLS 协议的隧道。
Stunnel是一个开源代理,用于创建安全隧道,允许您通过 TLS 与其他机器通信。在本指南中,我们将逐步安装和配置 stunnel,以便您可以使用redis-cli
.
先决条件
要完成本指南,您需要:
- 访问 Ubuntu 18.04 服务器。此服务器应具有具有管理权限的非 root 用户和配置为
ufw
. 要进行设置,请按照我们针对 Ubuntu 18.04 的初始服务器设置指南进行操作。 - 托管 Redis 数据库实例。本教程中概述的步骤在 DigitalOcean 托管 Redis 数据库上进行了测试,但它们通常适用于来自任何云提供商的托管数据库。要配置 DigitalOcean 托管 Redis 数据库,请遵循我们的托管 Redis 产品文档。
步骤 1 — 安装 Stunnel 和 redis-cli
当您安装 Redis 服务器时,它通常带有redis-cli
. 但是,您可以在redis-cli
没有 Redis 服务器redis-tools
的情况下通过从默认 Ubuntu 存储库安装软件包来进行安装。您还可以通过下载stunnel4
软件包从默认的 Ubuntu 存储库安装 stunnel 。
首先,如果您最近没有更新服务器的包索引:
- sudo apt update
然后使用 APT安装redis-tools
和stunnel4
包:
- sudo apt install redis-tools stunnel4
出现提示时,按ENTER
确认您要安装软件包。
您可以通过运行以下命令来检查 stunnel 是否已正确安装及其systemd服务是否正常工作:
- sudo systemctl status stunnel4
Output● stunnel4.service - LSB: Start or stop stunnel 4.x (TLS tunnel for network daemons)
Loaded: loaded (/etc/init.d/stunnel4; generated)
Active: active (exited) since Thu 2019-09-12 14:34:05 UTC; 8s ago
Docs: man:systemd-sysv-generator(8)
Tasks: 0 (limit: 2362)
CGroup: /system.slice/stunnel4.service
Sep 12 14:34:05 stunnel systemd[1]: Starting LSB: Start or stop stunnel 4.x (TLS tunnel for network daemons)...
Sep 12 14:34:05 stunnel stunnel4[2034]: TLS tunnels disabled, see /etc/default/stunnel4
Sep 12 14:34:05 stunnel systemd[1]: Started LSB: Start or stop stunnel 4.x (TLS tunnel for network daemons).
在这里,您可以看到 stunnel 服务处于活动状态,但该进程立即退出。这告诉我们 stunnel 正在运行,但它实际上不能做任何事情,因为我们还没有配置它。
第 2 步 – 配置 Stunnel
现代 Linux 系统依赖 systemd 来初始化和管理服务和守护进程。但是,stunnel 使用 SysV 样式的 init 脚本进行启动,该脚本基于较旧的UNIX System V init 系统。您需要修改该/etc/default/stunnel4
文件以启用此 init 脚本。
使用您首选的文本编辑器打开此文件。在这里,我们将使用nano
:
- sudo nano /etc/default/stunnel4
ENABLED
在文件顶部附近找到选项。它将0
默认设置为,但将其更改为1
以启用 stunnel 在引导时启动:
# /etc/default/stunnel
# Julien LEMOINE <[email protected]>
# September 2003
# Change to one to enable stunnel automatic startup
ENABLED=1
. . .
保存并关闭文件。如果您曾经nano
编辑过该文件,请按CTRL+X
、Y
、来进行编辑ENTER
。
接下来,您需要为 stunnel 创建一个配置文件,它将告诉程序需要将流量路由到哪里。
stunnel.conf
在/etc/stunnel
目录下打开一个名为的新文件:
- sudo nano /etc/stunnel/stunnel.conf
将以下内容添加到此文件中:
fips = no
setuid = nobody
setgid = nogroup
pid = /home/sammy/pids/stunnel.pid
debug = 7
delay = yes
[redis-cli]
client = yes
accept = 127.0.0.1:8000
connect = managed_redis_hostname_or_ip:managed_redis_port
文件中的前五行是global options,这意味着它们将应用于您包含在此文件中的每个服务:
fips
:启用或禁用 stunnel 的 FIPS 140-2 模式。在这种模式下,stunnel 将验证连接是否符合联邦信息处理标准。将此设置为no
禁用此功能。请注意,禁用它并不会降低安全性,但保持启用(默认情况下)需要一些额外的配置。setuid
: 定义 stunnel 将在其下运行的 Unix 用户 ID。默认情况下,stunnel 进程由root用户拥有。但是,隧道文档建议您在隧道启动后放弃管理权限,因为不这样做会带来安全风险。将setuid
参数设置为nobody
将导致没有特权的用户nobody在隧道建立后接管 stunnel 进程。setgid
: 定义 stunnel 将在其下运行的 Unix 组 ID。与 一样setuid
,此配置指定一个没有任何特殊权限的组 – nogroup – 以避免任何潜在的安全问题。pid
: 定义 stunnel 将在其中创建.pid
文件的文件位置,该文件类型包含进程的PID。.pid
其他程序通常使用文件来查找正在运行的进程的 PID。默认情况下,stunnel.pid
在/var/run/stunnel4/
目录中创建一个文件,但由于nobody用户没有访问该目录的权限,它将阻止隧道正确启动。取而代之的是,该行指定一个文件名为stunnel.pid
在一个名为目录保持pids
在Ubuntu用户的主目录。我们将stunnel.pid
很快创建此目录和文件。添加此行时,请务必更改sammy
为 Ubuntu 系统用户的名称。debug
: 设置 stunnel 的调试级别,范围从0
到7
。在此示例中,我们将其设置为7
可用的最高级别,因为如果 stunnel 遇到任何问题,它将提供最详细的信息。您可以将其设置为您喜欢的任何级别,但请注意默认设置为5
.delay
:当设置为 时yes
,此选项会导致 stunnel 延迟对connect
选项中列出的地址的 DNS 查找。它还可以防止 stunnel 缓存 IP 地址。即使托管 Redis 实例离线,此设置也有助于保持隧道打开,扩展集群时可能会发生这种情况。
其余的行是服务级别选项,仅适用于我们将为其创建的隧道redis-cli
:
[redis-cli]
:这是一个服务名称,并指定以下几行代表客户端程序的单个服务配置。您可以在一个 stunnel 配置文件中拥有多个服务,但每个服务都必须与现有客户端应用程序相关联,并且同一应用程序不能拥有两个服务。client
:将此设置为yes
告诉 stunnel 在客户端模式下运行,这意味着 stunnel 将连接到 TLS 服务器(托管 Redis 实例)而不是充当 TLS 服务器。accept
:定义 stunnel 将接受来自客户端的连接的主机和端口。在这里,我们指定 IP address127.0.0.1
,这是一个用于表示localhost的 IPv4 环回地址和 port8000
。这意味着 stunnel 将在端口上侦听源自 Ubuntu 服务器的连接8000
并对其进行加密。请注意,您可以将端口设置为您喜欢的任何端口号,只要它尚未被使用即可。connect
:定义 stunnel 将建立连接的远程地址和端口。请务必更改此参数以与托管数据库的端口和主机名或 IP 地址保持一致。
注意:您应该在connect
指令中指定的主机名或 IP 地址和端口将特定于您自己的托管 Redis 数据库。这些通常可以在您配置 Redis 实例的云提供商的数据库管理用户界面中找到。
如果您使用的是 DigitalOcean Managed Redis 数据库,则可以通过转到控制面板并单击左侧边栏菜单中的数据库来找到此信息。然后,单击要连接的 Redis 实例的名称并向下滚动到“连接详细信息”部分。在那里,您将找到描述数据库主机和端口的字段。
这是一个相当小的配置,保留了许多 stunnel 的默认设置。该程序有许多选项可供您创建适合您特定需求的隧道。有关更多详细信息,请参阅官方文档。
添加此内容后,保存并关闭文件。
接下来,确保您位于 Ubuntu 用户的主目录中:
- cd
然后创建pids
将保存stunnel.pid
文件的目录:
- mkdir pids
stunnel 进程会stunnel.pid
自动创建文件,因此您无需自己创建文件。但是,您确实需要将pids
目录的所有权更改为nobody用户和nogroup组:
- sudo chown -R nobody:nogroup pids/
然后,重新启动stunnel4
服务,以便 stunnel 读取新的配置文件:
- sudo systemctl restart stunnel4
之后,您可以通过调用netstat
用于显示网络连接的命令行实用程序来测试 stunnel 是否成功创建了隧道。运行以下命令,该命令将netstat
输出通过管道传输到grep
命令中,然后该命令会针对 的每个实例进行搜索stunnel
:
- sudo netstat -plunt | grep stunnel
Output tcp 0 0 127.0.0.1:8000 0.0.0.0:* LISTEN 17868/stunnel
此输出显示 stunnel 正在侦听本地端口上的连接8000
。
您还可以通过显示所有当前正在运行的进程的程序来确认nobody用户已拥有 stunnel 进程的所有权ps
:
- ps aux | grep stunnel
Output nobody 15674 0.0 0.1 121912 3180 ? Ssl 19:28 0:00 /usr/bin/stunnel4 /etc/stunnel/stunnel.conf
. . .
在这里,您可以看到确实没有人接管 stunnel 过程。
Stunnel 现在已完全配置并在您的系统上运行。您已准备好连接到托管 Redis 实例并测试隧道是否按预期工作。
第 3 步 – 通过 TLS 连接到您的托管数据库
既然您已经redis-cli
在服务器上安装并配置了 stunnel,您就可以通过 TLS 连接到托管数据库。
根据在步骤 2 中创建的配置文件中定义的设置,您将使用以下命令连接到托管数据库:
- redis-cli -h localhost -p 8000
此命令包含-h
标志,该标志告诉redis-cli
下一个参数将是要连接的主机。在这种情况下,这是localhost
因为我们要连接到在服务器本地创建的隧道。之后是-p
标志,它位于我们要连接的本地隧道的端口之前,在本例中是 port 8000
。
运行该命令后,您将连接到托管的 Redis 服务器。您的提示将更改以反映您已连接并处于redis-cli
的交互模式:
-
注意:通常,托管数据库配置为要求用户在连接时使用密码进行身份验证。如果您的托管 Redis 实例需要密码,您可以-a
在redis-cli
命令中包含该标志,后跟您的密码:
- redis-cli -h localhost -p 8000 -a password
或者,您可以通过auth
在建立连接后运行命令后跟密码来进行身份验证:
- auth password
如果您使用的是 DigitalOcean 托管数据库,则可以在找到其主机名和端口的同一位置找到 Redis 实例的密码。在您的控制面板中,单击左侧边栏菜单中的数据库。然后,单击您已连接到的 Redis 实例的名称。向下滚动到Connection Details部分,您会在那里找到一个标有password的字段。单击显示按钮以显示密码,然后将其复制并粘贴到这些命令中的任一个中(替换password
)以进行身份验证。
您可以通过ping
从 Redis 的交互模式运行命令来测试隧道是否按预期工作:
- ping
如果连接处于活动状态,它将返回PONG
:
Output PONG
但是,如果 stunnel 没有正确地将流量从您的服务器通过隧道传输到您的 Redis 实例,您可能会在与 Redis 断开连接之前看到如下错误消息:
Output Error: Server closed the connection
如果您收到此错误或类似错误,请仔细检查您是否在stunnel.conf
文件中正确输入了 Redis 实例的主机名和端口。同样,请确保您在redis-cli
命令中输入了正确的端口号。
当托管 Redis 实例重置其打开的连接时,您也可能会收到此错误,当您扩展集群的配置时可能会发生这种情况。在这种情况下,您可能不会与 Redis 断开连接,但您需要重新进行身份验证。
确认隧道正常工作后,继续并断开与 Redis 实例的连接:
- exit
如果您更改了 stunnel 的配置,则需要重新加载或重新启动stunnel4
服务,以便 stunnel 注意到这些更改:
- sudo systemctl reload stunnel4
如果在将来的任何时候您想关闭 TLS 隧道,您也可以使用以下命令systemctl
:
- sudo systemctl stop stunnel4
隧道关闭后,您可以通过再次启动服务来重新打开隧道:
- sudo systemctl start stunnel4
既然您已经成功配置了 stunnel,您就可以开始使用redis-cli
.
结论
Stunnel 是一个方便的工具,用于创建 TLS 隧道和建立到远程服务器的安全连接。这在机器之间安全传输信息至关重要的情况下尤其有用,例如远程数据库。
从这里,您可以开始探索 Redis 并将其与您的下一个应用程序集成。如果您是 Redis 的新手,您可能会发现我们关于如何管理 Redis 数据库的系列文章很有用。