介绍
Redis是一个开源的关键值数据存储,使用内存存储模型,可选为持久性写磁盘。它具有交易、 pub/sub 消息模式和自动故障转换等功能。
Redis 不提供任何加密功能,它假定它已部署在一个孤立的私人网络中,只有受信任的方可访问。
在本指南中,我们将展示如何使用一个名为spiped
的安全管道程序来加密Redis流量。Redis客户端和服务器之间的流量将通过一个专用的加密隧道进行路由,类似于一个专用的SSH隧道。
前提条件
要开始,你应该有一个非根用户,每个机器上都配置了sudo
权限。 此外,本指南将假定你有一个基本的防火墙,你可以遵循我们的Ubuntu 16.04初始服务器设置指南(https://andsky.com/tech/tutorials/initial-server-setup-with-ubuntu-16-04)来满足这些要求。
当你准备好继续时,继续下方。
什么是 Spiped?
" spiped " 工具很容易安装和配置,以便两个网络套接字(普通网络端口或Unix套接字)之间的安全通信。 它可用于配置两个远程服务器之间的加密通信. 客户端连接到一个本地端口,并在将其转发到远程服务器之前用加密方式将它包裹起来。 在服务器方面,`接通'先在配置的端口上收听并解密流量,然后转发到本地端口(就我们而言,是Redis服务器所收听的端口).
使用spiped
的一些优点是:
- Ubuntu 在其默认存储库中维护了
spiped
的包。 * Redis 项目目前建议使用spiped
来加密流量。 * 配置简单而直观。
一些缺点是:
- 客户端通过连接到非默认的本地端口连接到远程机器,这起初可能是不直观的。 * 若要连接两个 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 ** 键设置为成功
值,在配置spiped
后,我们将尝试从我们的客户端计算机访问此密钥。
安装 Redis 客户端
另一个Ubuntu 16.04 机器将作为客户端运作,我们所需要的所有软件都可在默认存储库中的redis-tools
包中使用:
1[environment second]
2sudo apt-get update
3sudo apt-get install redis-tools
随着远程 Redis 服务器的默认配置和启用防火墙,我们目前无法连接到远程 Redis 实例进行测试。
安装 Spiped 在每个计算机上
接下来,您需要在每个服务器和客户端上安装spiped
。如果您不需要在上一节中安装任何东西,请确保在安装前包括sudo apt-get update
命令来更新您的包索引:
1sudo apt-get install spiped
现在我们已经安装了必要的软件,我们可以生成一个安全的密钥,SPIPED可以用来加密我们两台机器之间的流量。
在 Redis 服务器上生成加密密钥
接下来,在您的 Redis 服务器上创建一个spiped
配置目录,以存储我们将生成加密的密钥:
1[environment third]
2sudo mkdir /etc/spiped
通过键入生成安全密钥:
1[environment third]
2sudo dd if=/dev/urandom of=/etc/spiped/redis.key bs=32 count=1
通过调整权限来限制访问生成的密钥文件:
1[environment third]
2sudo chmod 600 /etc/spiped/redis.key
现在我们在Redis服务器上有钥匙,我们可以使用系统d单元文件在服务器上设置spiped
。
为 Redis 服务器创建一个 systemd 单元文件
该spiped
实用程序非常简单,它没有支持读取配置文件. 因为每个管道必须手动配置,Ubuntu包不带 init 脚本来自动启动管道。
要解决这些问题,我们将创建一个简单的 systemd 单元文件. 在 /etc/systemd/system
目录中打开一个新的单元文件来开始:
1[environment third]
2sudo nano /etc/systemd/system/spiped-receive.service
内部,创建一个[单位]
部分来描述该单位并建立排序,以便该单位在可用后启动网络:
1[environment third]
2[label /etc/systemd/system/spiped-receive.service]
3[Unit]
4Description=spiped receive for Redis
5Wants=network-online.target
6After=network-online.target
接下来,打开一个[服务]
部分来定义要运行的实际命令. 我们将使用以下选项与spiped
:
*`-F':在前地跑出。 系统输入系统旨在尽可能管理在前地运行的服务。 在前地运行简化了所需的配置.
- 联合国
-d': 解密源套接字的流量 。 这告诉了
接通'加密的方向,以便它知道从源头解密流量,从目标口解密流量。 - 联合国
-s': 此定义了源套接字 。 IP地址必须放在方括号内,然后是结号,然后是端口。 对于 Redis 服务器,应该设置到公共IP地址和 Redis 端口. *
-t': 目标插座。 这是解密后传输流量的地方. Redis默认会听本地主机上6379的端口,所以这就是我们必须使用的. - 联合国 `-k':指定要使用的密钥文件。 这应该指向我们之前生成的加密密钥. .
所有这些选项都将在一个单一的ExecStart
指令中进行,这是我们在本节中唯一需要的项目:
1[environment third]
2[label /etc/systemd/system/spiped-receive.service]
3[Unit]
4Description=spiped receive for Redis
5Wants=network-online.target
6After=network-online.target
7
8[Service]
9ExecStart=/usr/bin/spiped -F -d -s [redis_server_public_IP]:6379 -t [127.0.0.1]:6379 -k /etc/spiped/redis.key
最后,我们将包括一个[安装]
部分,以告诉系统d在启用时何时自动启动设备:
1[environment third]
2[label /etc/systemd/system/spiped-receive.service]
3[Unit]
4Description=spiped receive for Redis
5Wants=network-online.target
6After=network-online.target
7
8[Service]
9ExecStart=/usr/bin/spiped -F -d -s [redis_server_public_IP]:6379 -t [127.0.0.1]:6379 -k /etc/spiped/redis.key
10
11[Install]
12WantedBy=multi-user.target
完成后,保存并关闭文件。
启动 Spiped 服务并调整 Redis 服务器上的防火墙
启动并启用新的spiped
单元,键入:
1[environment third]
2sudo systemctl start spiped-receive.service
3sudo systemctl enable spiped-receive.service
如果您检查在您的 Redis 服务器上听取连接的服务,您应该看到在公共接口上的 6379 端口上听spiped
。
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/spiped
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
虽然spiped
在公共界面上收听,但防火墙可能尚未配置为允许流量通过。
要允许所有流量到端口 6379,键入:
1[environment third]
2sudo ufw allow 6379
这将打开您的公共界面上的端口6379的访问权限,其中spiped
正在收听。
将加密密钥传输给客户端
为了将加密密钥传输给客户端,我们需要在我们的两个服务器之间建立安全连接,我们将使用ssh
,因为这使我们能够利用我们现有的配置。
如果您正在使用基于密钥的身份验证,则需要将 SSH 密钥传送到 Redis 服务器以建立连接。
为基于密钥的身份验证的额外步骤
从您的 Redis 服务器中断连接:
1[environment third]
2exit
现在,在本地机器上,请确保一个SSH代理正在运行,并且已添加您的私钥:
1[environment local]
2eval `ssh-agent`
3ssh-add
现在,重新连接到您的 Redis 服务器,并添加-A
旗帜来传输您的密钥:
1[environment local]
2ssh -A sammy@redis_server_public_IP
您现在可以继续下面的步骤。
转移钥匙
我们将从 Redis 服务器连接到客户端,因为我们的密钥文件需要本地sudo
权限来访问,我们现在可以传输该文件,确保在下面的命令末尾包含 colon:
1[environment third]
2sudo -E scp /etc/spiped/redis.key sammy@redis_client_public_IP:
scp
写入客户端机上的用户主目录。
转移密钥后,在客户端机器上创建/etc/spiped
目录:
1[environment second]
2sudo mkdir /etc/spiped
将加密密钥移动到新目录:
1[environment second]
2sudo mv ~/redis.key /etc/spiped
关闭限制访问权限:
1[environment second]
2sudo chmod 600 /etc/spiped/redis.key
现在客户端有服务器加密密钥的副本,我们可以配置spiped
配置的客户端侧。
为 Redis 客户端创建一个 systemd 单元文件
我们需要在客户端上创建一个spiped
的 systemd 单元文件,就像我们在 Redis 服务器上一样。
通过键入打开一个新的 systemd 单元文件:
1[environment second]
2sudo nano /etc/systemd/system/spiped-send.service
在内部,打开一个[单位]
部分来描述服务,并确定它取决于网络可用性:
1[environment second]
2[label /etc/systemd/system/spiped-send.service]
3[Unit]
4Description=spiped sending for Redis
5Wants=network-online.target
6After=network-online.target
接下来,打开一个[服务]
部分来执行spiped
过程. 这里使用的选项与Redis服务器使用的选项非常相似,有以下差异:
-e
: 指定需要加密输入源接口的流量,从而建立源和目标接口之间的关系。 *-s
: 定义源接口,就像以前一样. 在这种情况下,源是本地接口上可用的任意端口,本地Redis客户端可以连接到它。
这些将使用ExecStart
指令再次设置:
1[environment second]
2[label /etc/systemd/system/spiped-send.service]
3[Unit]
4Description=spiped sending for Redis
5Wants=network-online.target
6After=network-online.target
7
8[Service]
9ExecStart=/usr/bin/spiped -F -e -s [127.0.0.1]:8000 -t [redis_server_public_IP]:6379 -k /etc/spiped/redis.key
最后,包括一个[安装]
部分,以定义如果启用,该单元将何时启动:
1[environment second]
2[label /etc/systemd/system/spiped-send.service]
3[Unit]
4Description=spiped sending for Redis
5Wants=network-online.target
6After=network-online.target
7
8[Service]
9ExecStart=/usr/bin/spiped -F -e -s [127.0.0.1]:8000 -t [redis_server_public_IP]:6379 -k /etc/spiped/redis.key
10
11[Install]
12WantedBy=multi-user.target
完成后,保存并关闭文件。
在客户端启动 Spiped 服务并测试连接
现在,我们可以在客户端启动我们的spiped
服务,并允许它在启动时自动启动:
1[environment second]
2sudo systemctl start spiped-send.service
3sudo systemctl enable spiped-send.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 3264/spiped
6tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1705/sshd
7tcp6 0 0 :::22 :::* LISTEN 1705/sshd
正如你所看到的,spiped
在本地端口 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: Protocol error, got "\xac" as reply type byte
正如您所看到的,只有通过隧道进行正确加密,才能在远程的Redis端口接受流量。
扩展上面的多客户端和服务器对服务器通信示例
上面的例子使用了一个简单的例子,一个单一的Redis服务器和一个单一的客户端,但是,这些相同的方法可以应用于更复杂的交互。
将此示例扩展到处理多个客户端是简单的,您需要执行上述以下操作。
- 将 Redis 客户端软件和
spiped
包安装在新客户端上 * 将加密密钥传输到新客户端 * 将spiped
systemd 单元文件复制到新客户端 * 启动spiped
服务并允许它在启动时启动
要设置安全的服务器-服务器通信(例如,复制或聚合),您需要设置两个并行隧道:
- 联合国 在新服务器上安装 Redis 服务器包并
spiped
- 生成新 Redis 服务器的新加密密钥( 文件使用独有的名称)
- 联合国 将加密密钥从一个服务器复制到另一个服务器的
/etc/ spiped
目录 - 在每个服务器(包括现有的服务器)上创建一个
分管
系统化单元文件,使每个服务器有一个服务于每个角色的文件:
- 接收单位将外部端口映射到当地的Redis
- 将本地端口映射到远程服务器已曝光端口的发送单位文件
- 联合国 打开新 Redis 服务器防火墙中的外部端口
- 配置每个 Redis 实例,通过调整 Redis 配置文件连接到本地映射端口来访问远程服务器(所需的指令取决于服务器的关系). 详见Redis文件。 .
如有必要,可以在每个机器上配置多个客户端单元文件,以将本地端口绘制到远程服务器上. 在这些情况下,请确保在发送单元文件中的源插槽规格中选择不同的未使用本地端口。
结论
Redis是一个强大而灵活的工具,对许多部署都非常宝贵. 然而,在不安全的环境中运行Redis是一个巨大的责任,使你的服务器和数据容易受到攻击或被窃取. 若您没有仅由信任方组成的孤立网络, 本指南中概述的方法只是确保Redis当事人之间通信的一种方式. 其他选项包括[通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通通.