如何使用 Stunnel 和 redis-cli 通过 TLS 连接到托管 Redis 实例

介绍

托管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-toolsstunnel4包:

  • 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/stunnel4
# /etc/default/stunnel
# Julien LEMOINE <[email protected]>
# September 2003

# Change to one to enable stunnel automatic startup
ENABLED=1
. . .

保存并关闭文件。如果您曾经nano编辑过该文件,请按CTRL+XY来进行编辑ENTER

接下来,您需要为 stunnel 创建一个配置文件,它将告诉程序需要将流量路由到哪里。

stunnel.conf/etc/stunnel目录打开一个名为的新文件

  • sudo nano /etc/stunnel/stunnel.conf

将以下内容添加到此文件中:

/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 的调试级别,范围从07在此示例中,我们将其设置为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 address 127.0.0.1,这是一个用于表示localhost的 IPv4 环回地址和 port 8000这意味着 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 实例需要密码,您可以-aredis-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 数据库的系列文章很有用。

觉得文章有用?

点个广告表达一下你的爱意吧 !😁