如何在 Ubuntu 16.04 上使用 Stunnel 加密 Redis 的流量

介绍

Redis是一个开源的关键值数据存储,使用内存存储模型,可选为持久性写磁盘。它具有交易、 pub/sub 消息模式和自动故障转换等功能。

Redis 不提供任何加密功能,它假定它已部署在一个孤立的私人网络中,只有受信任的方可访问。

在本指南中,我们将展示如何使用一个名为stunnel的安全隧道程序来加密Redis流量。Redis客户端和服务器之间的流量将通过一个专用的SSL加密隧道进行路由。

前提条件

要开始,你应该有一个非根用户,每个机器上都配置了sudo权限。 此外,本指南将假定你有一个基本的防火墙,你可以遵循我们的Ubuntu 16.04初始服务器设置指南(https://andsky.com/tech/tutorials/initial-server-setup-with-ubuntu-16-04)来满足这些要求。

当你准备好继续时,继续下方。

◎什么是Stunnel?

对于基本的加密通信,隧道实用程序易于安装和配置,它允许两台机器之间进行加密转发。客户端连接到一个本地端口,并在将其转发到远程服务器之前隧道将其加密。在服务器侧,隧道在配置的端口上倾听并解密流量,然后将其转发到本地端口(在我们的情况下,Redis服务器倾听的端口)。

使用隧道的一些优点是:

  • Ubuntu 在其默认存储库中维护了隧道的包 * Ubuntu 包含一个 init 脚本,可在启动时自动启动过程 * 配置是直观的和直观的 * 每个目的都使用了一个新的隧道。

一些缺点是:

  • 客户端通过连接到非默认的本地端口连接到远程机器,这起初可能是不直观的。 * 若要连接两个 Redis 服务器进行复制或聚合,每个机器都必须配置两个隧道用于服务器与服务器的通信(一个用于输出和一个用于输入流量)。

考虑到这些特点,让我们开始。

安装 Redis 服务器和客户端包

在我们开始之前,我们应该在一台机器上安装 Redis 服务器和在另一台机器上提供客户端包。

<$>[注] 注: Redis 服务器指示设置了一个测试密钥,将用于稍后测试连接. 如果您已经安装了 Redis 服务器,您可以继续设置此密钥或使用任何其他已知密钥,当我们测试连接时。

安装 Redis 服务器

我們將使用 Chris Lea 的 Redis 伺服器 PPA來安裝最新版本的 Redis. 在使用第三方儲存庫時,總是要小心。

添加 PPA 并在您的第一台机器上安装 Redis 服务器软件,键入:

1[environment third]
2sudo apt-add-repository ppa:chris-lea/redis-server
3sudo apt-get update
4sudo apt-get install redis-server

键入 Enter 以在此过程中接受提示。

安装完成后,测试您可以通过键入本地连接到 Redis 服务:

1[environment third]
2redis-cli ping

如果软件已安装并运行,您应该看到:

1[environment third]
2[secondary_label Redis server output]
3PONG

让我们设置一个我们可以稍后使用的密钥:

1[environment third]
2redis-cli set test 'success'

我们已将 **test ** 键设置为成功值,我们将尝试在配置stunnel后从我们的客户端计算机访问此密钥。

安装 Redis 客户端

另一个Ubuntu 16.04 机器将作为客户端运作,我们所需要的所有软件都可在默认存储库中的redis-tools包中使用:

1[environment second]
2sudo apt-get update
3sudo apt-get install redis-tools

随着远程 Redis 服务器的默认配置和启用防火墙,我们目前无法连接到远程 Redis 实例进行测试。

在每个计算机上安装和启用 stunnel

接下来,您将需要在每个服务器和客户端上安装stunnel。Ubuntu在其默认存储库中包含stunnel4这个实用程序的四个版本,如果您不需要在上一节中安装任何东西,请确保在安装前包括sudo apt-get update命令来更新您的包索引:

1# sudo apt-get update
2sudo apt-get install stunnel4

Ubuntu上的隧道服务使用了一个较旧的SysVinit启动脚本,可以由systemd管理,而不是使用原生systemd方法,要配置该服务在启动时启动,您必须修改 /etc/default/stunnel4文件:

1sudo nano /etc/default/stunnel4

允许服务在启动时启动,将ENABLED选项设置为1:

1[label /etc/default/stunnel4]
2. . .
3ENABLED=1
4. . .

在每个服务器上保存和关闭文件。

接下来,我们将创建一个自签名的SSL证书和密钥,用于加密通信。

在 Redis 服务器上创建自签名的 SSL 证书和密钥

在您的 Redis 服务器上,在/etc/stunnel目录中创建一个自签名的 SSL 证书和密钥,这将用于加密stunnel两个实例之间的连接。

1[environment third]
2sudo openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout /etc/stunnel/redis-server.key -out /etc/stunnel/redis-server.crt

您将被提示获取有关您正在创建的证书的信息,因为这些证书只会被内部使用,所以这些值并不重要,所以请填写任何您想要的信息。

 1[environment third]
 2[secondary_label Redis server output]
 3. . .
 4-----
 5Country Name (2 letter code) [AU]:US
 6State or Province Name (full name) [Some-State]:New York
 7Locality Name (eg, city) []:New York City
 8Organization Name (eg, company) [Internet Widgits Pty Ltd]:DigitalOcean
 9Organizational Unit Name (eg, section) []:Community
10Common Name (e.g. server FQDN or YOUR name) []:redis-server
11Email Address []:[email protected]

通过键入来限制访问生成的 .key 文件:

1[environment third]
2sudo chmod 600 /etc/stunnel/redis-server.key

现在我们有一个SSL证书和密钥,我们可以创建我们的Redis服务器的隧道配置文件。

创建 Redis 服务器站点配置文件

在 Redis 服务器上的 /etc/stunnel’ 目录中打开以 .conf’ 结束的文件,以便开始:

1[environment third]
2sudo nano /etc/stunnel/redis.conf

内部,指定一个位置来写PID文件在主部分. /run目录旨在存储这些类型的文件,所以我们将使用它:

1[environment third]
2[label /etc/stunnel/redis.conf]
3pid = /run/stunnel-redis.pid

接下来,创建一个部分来配置访问 Redis 服务. 您可以将其称为任何您想要的服务(我们将称之为redis-server). 该部分将此配置与您可能需要在以后在该机器上配置的任何其他隧道分开。

我们需要使用certkey指令来指定Redis服务器自己的证书和密钥的位置。

我们还将在这里定义输入数据的隧道。我们希望在Redis服务器的外部IP地址上接受加密流量到默认的Redis端口(端口6379)。然后我们希望连接该流量到默认的Redis端口在 _local_接口上存储解密流量。

1[environment third]
2[label /etc/stunnel/redis.conf]
3pid = /run/stunnel-redis.pid
4
5[redis-server]
6cert = /etc/stunnel/redis-server.crt
7key = /etc/stunnel/redis-server.key
8accept = redis_servers_public_IP:6379
9connect = 127.0.0.1:6379

完成后,保存并关闭文件。

重新启动攻击并配置防火墙

现在在Redis服务器上配置了stunnel,我们可以通过键入重新启动服务:

1[environment third]
2sudo systemctl restart stunnel4.service

如果您检查在您的 Redis 服务器上听取连接的服务,您应该看到在公共接口上的 6379 端口上听隧道

1[environment third]
2sudo netstat -plunt
1[environment third]
2[secondary_label Redis server output]
3Active Internet connections (only servers)
4Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
5tcp 0 0 public_IP:6379 0.0.0.0:*               LISTEN 4292/stunnel4   
6tcp 0 0 127.0.0.1:6379 0.0.0.0:*               LISTEN 2679/redis-server 1
7tcp 0 0 0.0.0.0:22 0.0.0.0:*               LISTEN 1720/sshd       
8tcp6 0 0 :::22                   :::*                    LISTEN 1720/sshd

尽管隧道正在公共界面上听取,但防火墙可能尚未配置为允许流量通过。

要允许所有流量到端口 6379,键入:

1[environment third]
2sudo ufw allow 6379

这将打开您的公共界面上的端口6379的访问权限,其中隧道正在收听。

向客户分发证书

每个 Redis 客户端都需要 Redis 服务器的证书文件的副本.分发.crt 文件的最简单的方法是简单地将文件的内容输出到服务器上,然后将内容复制到连接机器上的相应文件中。

在您的 Redis 服务器上输出.crt 文件的内容,键入:

1[environment third]
2cat /etc/stunnel/redis-server.crt
 1[environment third]
 2[secondary_label Redis server output]
 3-----BEGIN CERTIFICATE-----
 4MIIEGTCCAwGgAwIBAgIJALUdz8P8q8UPMA0GCSqGSIb3DQEBCwUAMIGiMQswCQYD
 5VQQGEwJVUzERMA8GA1UECAwITmV3IFlvcmsxFjAUBgNVBAcMDU5ldyBZb3JrIENp
 6
 7. . .
 8
 9Tq7WJk77tk4nPI8iGv1WuK8xTAm5aOncxP16VoMpsDMV+GB1p3nBkMQ/GKF8pPXU
10fn6BnDWKmeZqAlBM+MGYAfkbZWdBslrWasCJzs+tehTqL0LLJ6d3Gi9biBPb
11-----END CERTIFICATE-----

将显示的证书,包括标记为 BEGIN CERTIFICATE 和 END CERTIFICATE 的行,复制到您的剪辑板上。

在客户端机器上,在 /etc/stunnel 目录中打开具有相同名称的文件:

1[environment second]
2sudo nano /etc/stunnel/redis-server.crt

粘贴您从 Redis 服务器复制的内容. 完成后保存并关闭文件。

创建 Redis 客户端插座配置文件

现在客户端有服务器证书的副本,我们可以配置隧道配置的客户端侧。

在客户端机器上的/etc/stunnel目录中打开一个以.conf结束的文件. 我们将再次将该文件称为redis.conf:

1[environment second]
2sudo nano /etc/stunnel/redis.conf

内部,指定一个 PID 文件,该服务将再次存储其进程 ID:

1[environment second]
2[label /etc/stunnel/redis.conf]
3pid = /run/stunnel-redis.pid

接下来,添加一个部分来配置输出数据的隧道. 您可以随心所欲地命名它(我们将称之为redis-client). 该部分将此配置与您可能需要在以后在该机器上配置的任何其他隧道分开。

我们需要将此部分明确标记为客户端配置,使用客户端指令。设置接受指令,以在本地界面上倾听未使用的端口,以处理来自本地 Redis 客户端的连接(我们将在本例中使用端口 8000)。

然后使用CAfile指向Redis服务器的证书副本,我们还必须将verify设置为4,这使得stunnel只检查证书,而不考虑证书链(因为我们自己签署了我们的证书):

 1[environment second]
 2[label /etc/stunnel/redis.conf]
 3pid = /run/stunnel-redis.pid
 4
 5[redis-client]
 6client = yes
 7accept = 127.0.0.1:8000
 8connect = remote_server_IP_address:6379
 9CAfile = /etc/stunnel/redis-server.crt
10verify = 4

保存并关闭文件,当你完成。

重新启动客户端服务并测试连接

在客户端重新启动隧道服务以实现更改:

1[environment second]
2sudo systemctl restart stunnel4.service

检查客户端的隧道是否正确设置:

1[environment second]
2sudo netstat -plunt
1[environment second]
2[secondary_label Redis client output]
3Active Internet connections (only servers)
4Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
5tcp 0 0 127.0.0.1:8000 0.0.0.0:*               LISTEN 3809/stunnel4   
6tcp 0 0 0.0.0.0:22 0.0.0.0:*               LISTEN 1714/sshd       
7tcp6 0 0 :::22                   :::*                    LISTEN 1714/sshd

正如你所看到的,隧道在本地端口8000上收听连接。

现在,您应该能够通过在本地界面上指向客户端端口 8000 来连接到远程 Redis 实例:

1[environment second]
2redis-cli -p 8000 ping
1[environment second]
2[secondary_label Redis client output]
3PONG

查询我们在本指南开始时设置的测试密钥:

1[environment second]
2redis-cli -p 8000 get test
1[environment second]
2[secondary_label Redis client output]
3"success"

这证实我们能够成功访问远程数据库。

要确认我们无法在不使用隧道的情况下与远程 Redis 服务器进行通信,我们可以尝试直接连接到远程端口:

1[environment second]
2redis-cli -h redis_server_public_IP -p 6379 ping
1[environment second]
2[secondary_label Redis client output]
3Error: Connection reset by peer

正如您所看到的,只有通过隧道进行正确加密,才能在远程的Redis端口接受流量。

扩展上面的多客户端和服务器对服务器通信示例

上面的例子使用了一个简单的例子,一个单一的Redis服务器和一个单一的客户端,但是,这些相同的方法可以应用于更复杂的交互。

将此示例扩展到处理多个客户端是简单的,您需要执行上述以下操作。

  • 在新客户端上安装 Redis 客户端软件和stunnel包 * 允许stunnel软件在启动时启动 * 将服务器的证书文件复制到/etc/stunnel目录 * 将stunnel客户端配置文件复制到新客户端 * 重新启动stunnel服务

要设置安全的服务器-服务器通信(例如,复制或聚合),您需要设置两个并行隧道:

  • 联合国 在新服务器上安装 Redis 服务器包和 stunnel
  • 联合国 启用 stunnel 软件启动启动
  • 为新的 Redis 服务器创建新的证书和密钥文件( 文件使用独有的名称)
  • 联合国 从一个服务器复制到另一个服务器的证书文件到 /etc/ stunnel 目录
  • 联合国 编辑或创建每个服务器(包括已存在的服务器)的 stunnel 配置文件,使其包含:
  • 将外部端口映射到本地Redis的服务器区
  • 将本地端口映射到远程服务器已曝光端口的客户端部分
  • 联合国 打开新 Redis 服务器防火墙中的外部端口
  • 配置每个 Redis 实例,通过调整 Redis 配置文件连接到本地映射端口来访问远程服务器(所需的指令取决于服务器的关系). 详见Redis文件。 .

两个服务器的隧道配置文件看起来像这样:

 1[label stunnel configuration file for server-to-server communication]
 2pid = /run/stunnel-redis.pid
 3
 4[redis-server]
 5cert = /etc/stunnel/this_servers_certificate.crt
 6key = /etc/stunnel/this_servers_key.key
 7accept = this_servers_public_IP:6379
 8connect = 127.0.0.1:6379
 9
10[redis-client]
11client = yes
12accept = 127.0.0.1:arbitrary_local_port
13connect = remote_servers_public_IP:6379
14CAfile = /etc/stunnel/remote_servers_certificate.crt
15verify = 4

如有必要,可以在每个机器上配置多个客户端部分,以将本地端口与远程服务器进行地图化. 在这些情况下,请确保为每个远程服务器选择不同的未使用的本地端口,并使用接受指令。

结论

Redis是一个强大而灵活的工具,对许多部署都非常宝贵. 然而,在不安全的环境中运行Redis是一个巨大的责任,使你的服务器和数据容易受到攻击或被窃取. 若您没有仅由信任方组成的孤立网络, 本指南中概述的方法只是确保Redis当事人之间通信的一种方式. 其他选项包括[用吹管通通 (https://andsky.com/tech/tutorials/how-to-encrypt-traffic-to-redis-with-spiped-on-ubuntu-16-04)或[设置VPN] (https://andsky.com/tech/tutorials/how-to-encrypt-traffic-to-redis-with-peervpn-on-ubuntu-16-04).

Published At
Categories with 技术
comments powered by Disqus