介绍
Redis是一个开源的键值数据存储,使用具有可选磁盘写入的内存存储模型进行持久化。它具有事务,发布/订阅消息模式和自动故障转移等功能。Redis的客户端用大多数语言编写,推荐 他们的网站 。 Redis不提供自己的任何加密功能。它的操作假设它已经部署到一个孤立的专用网络,只有信任方才能访问。如果您的环境不匹配该假设,您将必须单独加密Redis流量加密。 在本指南中,我们将演示如何使用一个被称为管道安全程序加密Redis的交通spiped
。 Redis客户端和服务器之间的流量将通过专用加密隧道进行路由,类似于专用SSH隧道。我们将使用两个Ubuntu 16.04服务器来演示。
先决条件
要开始,你应该有一个非root用户sudo
在每个机器的配置权限。 此外,本指南假设您有一个基本的防火墙。 您可以按照我们
的Ubuntu 16.04服务器初始设置指南 ,以满足这些要求。 当您准备好继续,请按照下面。
什么是spiped?
该spiped
实用程序是安装简单,配置(常规网络端口,Unix套接字或)两个网络socket之间的安全通信。 它可以用于配置两个远程服务器之间的加密通信。 客户端连接到本地端口和
spiped
把它封装在加密转发到远程服务器之前。 在服务器端,
spiped
配置的端口上侦听,并转发到本地端口之前解密的流量(在我们的情况下,Redis的服务器监听的端口)。 使用
spiped
的一些优点:
- Ubuntu维护包
spiped
在其默认库。 - 该Redis的项目目前建议使用
spiped
加密流量。 - 配置简单直观。
- 每个用途都使用新的管道。这在某些情况下可能是一个缺点,但它提供了对访问的粒度控制。
- 客户端通过附加到非默认本地端口连接到远程机器,这可能是不直观的。
- 如果连接两个Redis服务器进行复制或群集,则必须在每台计算机上配置两个隧道以进行服务器到服务器通信(一个用于出站,一个用于入站流量)。
- 没有包含init脚本,因此必须创建一个脚本,以便在引导时自动创建必要的连接。
安装Redis服务器和客户端软件包
在我们开始之前,我们应该在一台机器上安装Redis服务器,另一台机器上安装客户端软件包。如果您已经配置了一个或两个配置,请随时跳过。 注:Redis的服务器指令集将用于以后测试连接测试关键。如果您已经安装了Redis服务器,可以在测试连接时继续设置此密钥或使用任何其他已知密钥。安装Redis服务器
我们将使用 Chris Lea的Redis的服务器的PPA来安装的Redis的一个上的最新版本。使用第三方存储库时务必小心。在这种情况下,Chris Lea是一个值得信赖的包装商,为几个流行的开源项目保持高质量,最新的包。 添加PPA并通过键入以下命令在第一台计算机上安装Redis服务器软件:sudo apt-add-repository ppa:chris-lea/redis-server
sudo apt-get update
sudo apt-get install redis-server
类型
输入在此过程中接受的提示。 安装完成后,请测试您是否可以通过键入以下内容连接到Redis服务:
redis-cli ping
如果软件已安装并运行,您应该会看到:
Redis server outputPONG
让我们设置一个我们以后可以使用的密钥:
redis-cli set test 'success'
我们已经设定
测试关键值
success
。 我们会尽量配置之后,从我们的客户机访问这些关键
spiped
。
安装Redis客户端
其他Ubuntu 16.04机器将作为客户端。我们所需要的软件是可用的redis-tools
包中的默认存储库:
sudo apt-get update
sudo apt-get install redis-tools
使用远程Redis服务器的默认配置和防火墙活动,我们当前无法连接到远程Redis实例进行测试。
在每台计算机上安装spiped
接下来,您将需要安装spiped
在每个服务器和客户端。 如果你并不需要上一节中安装任何软件,确保包括
sudo apt-get update
命令安装之前刷新包索引:
sudo apt-get install spiped
现在,我们已经安装了必要的软件,我们可以生成一个安全密钥
spiped
可以使用我们的两台计算机之间的流量进行加密。
在Redis服务器上生成加密密钥
接下来,创建一个spiped
内配置目录
/etc
你Redis的服务器上存储,我们将生成加密的密钥:
sudo mkdir /etc/spiped
通过键入以下内容生成安全密钥:
sudo dd if=/dev/urandom of=/etc/spiped/redis.key bs=32 count=1
通过调整权限限制对生成的密钥文件的访问:
sudo chmod 600 /etc/spiped/redis.key
现在,我们有Redis的服务器上可用的关键,我们可以设置
spiped
使用systemd单元文件在服务器上。
为Redis服务器创建systemd单元文件
该spiped
效用是很简单的,它不具有用于读取一个配置文件支持。因为每个管道必须手动配置,所以Ubuntu软件包不带有init脚本,以在引导时自动启动管道。 为了解决这些问题,我们将创建一个简单的systemd单元文件。在打开一个新的单元文件
/etc/systemd/system
目录开始:
sudo nano /etc/systemd/system/spiped-receive.service
在内部,建立一个
[Unit]
部分中描述的单位,建立的顺序,使本机启动网络可用后:
/etc/systemd/system/spiped-receive.service
[Unit]
Description=spiped receive for Redis
Wants=network-online.target
After=network-online.target
接下来,打开一个
[Service]
部分定义实际的命令来运行。 我们将使用带有下列选项
spiped
:
-F
:在前台运行。 systemd init系统被设计为在可能时管理在前台运行的服务。在前台运行简化了所需的配置。-d
:从源socket解密流量。 这告诉spiped
加密的方向,它知道从源和目标加密解密的流量交通。-s
:定义源socket。 IP地址必须在方括号中,后跟冒号,然后是端口。对于Redis服务器,应将其设置为公共IP地址和Redis端口。-t
:目标socket。这是解密后流量将转发到的地方。 Redis默认侦听本地主机上的6379端口,这是我们必须使用的。-k
:指定要使用的密钥文件。这应该指向我们之前生成的加密密钥。
ExecStart
指令,这是我们需要在本节唯一的项目:
/etc/systemd/system/spiped-receive.service
[Unit]
Description=spiped receive for Redis
Wants=network-online.target
After=network-online.target
[Service]
ExecStart=/usr/bin/spiped -F -d -s [redis_server_public_IP]:6379 -t [127.0.0.1]:6379 -k /etc/spiped/redis.key
最后,我们将包括一个
[Install]
节告诉systemd若启用时自动启动:
/etc/systemd/system/spiped-receive.service
[Unit]
Description=spiped receive for Redis
Wants=network-online.target
After=network-online.target
[Service]
ExecStart=/usr/bin/spiped -F -d -s [redis_server_public_IP]:6379 -t [127.0.0.1]:6379 -k /etc/spiped/redis.key
[Install]
WantedBy=multi-user.target
完成后,保存并关闭文件。
启动加密服务并调整Redis服务器上的防火墙
启动并启用新的spiped
通过键入:
sudo systemctl start spiped-receive.service
sudo systemctl enable spiped-receive.service
如果您检查聆听您的Redis服务器上的连接服务,你应该看到
spiped
公共接口上的6379端口监听。您还应该看到Redis正在本地接口上侦听同一个端口:
sudo netstat -plunt
Redis server outputActive Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 public_IP:6379 0.0.0.0:* LISTEN 4292/spiped
tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 2679/redis-server 1
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1720/sshd
tcp6 0 0 :::22 :::* LISTEN 1720/sshd
虽然
spiped
是公共接口上侦听,防火墙可能没有配置为允许。 要允许所有流量到端口6379,请键入:
sudo ufw allow 6379
这将打开访问端口6379的公共接口,其中上
spiped
监听。 该
spiped
端口只接受加密的流量。
将加密密钥传输到客户端
要将加密密钥传输到客户端,我们需要在两个服务器之间建立安全连接。我们将使用ssh
,因为这使我们能够利用我们现有的配置。 如果使用基于密钥的身份验证,则需要将SSH密钥转发到Redis服务器以建立连接。这对于基于密码的系统不是必需的。
基于密钥的身份验证的额外步骤
断开与Redis服务器的连接:exit
现在,在本地计算机上,确保SSH代理正在运行,并且您的私钥已添加到它:
eval `ssh-agent`
ssh-add
现在,重新连接到您的Redis服务器并添加
-A
标志来转发你的钥匙:
ssh -A sammy@redis_server_public_IP
现在,您可以继续执行以下步骤。
传输密钥
因为我们的密钥文件要求地方我们将从Redis的服务器到客户端连接sudo
特权访问。我们现在可以传输文件,确保在命令结尾处包含冒号:
sudo -E scp /etc/spiped/redis.key sammy@redis_client_public_IP:
scp
写入客户机上用户的主目录。 传送密钥后,创建
/etc/spiped
在客户机上的目录:
sudo mkdir /etc/spiped
将加密密钥移动到新目录中:
sudo mv ~/redis.key /etc/spiped
锁定权限以限制访问:
sudo chmod 600 /etc/spiped/redis.key
现在,在客户端对服务器的加密密钥的副本,我们可以配置的客户端
spiped
配置。
为Redis客户端创建systemd单元文件
我们需要创建一个systemd单元文件spiped
,就如同我们做了Redis的服务器上的客户端。 键入以下命令以打开新的systemd单元文件:
sudo nano /etc/systemd/system/spiped-send.service
在内部,打开
[Unit]
部分描述服务,并建立它依赖于网络的可用性:
/etc/systemd/system/spiped-send.service
[Unit]
Description=spiped sending for Redis
Wants=network-online.target
After=network-online.target
接下来,打开一个
[Service]
节执行
spiped
过程。这里使用的选项与Redis服务器上使用的选项非常相似,但有以下区别:
-e
:指定输入源socket的流量将需要被加密。这将建立源和目标套接字之间的关系。-s
:定义源socket,就像以前一样。然而,在这种情况下,源是本地接口上本地Redis客户端可以连接到的任意可用端口。-t
:定义目标socket,就像以前一样。对于客户端,这将是远程Redis服务器的公共IP地址和打开的端口。
ExecStart
再次指令:
/etc/systemd/system/spiped-send.service
[Unit]
Description=spiped sending for Redis
Wants=network-online.target
After=network-online.target
[Service]
ExecStart=/usr/bin/spiped -F -e -s [127.0.0.1]:8000 -t [redis_server_public_IP]:6379 -k /etc/spiped/redis.key
最后,包括
[Install]
部分定义时,如果允许该单位将启动:
/etc/systemd/system/spiped-send.service
[Unit]
Description=spiped sending for Redis
Wants=network-online.target
After=network-online.target
[Service]
ExecStart=/usr/bin/spiped -F -e -s [127.0.0.1]:8000 -t [redis_server_public_IP]:6379 -k /etc/spiped/redis.key
[Install]
WantedBy=multi-user.target
完成后,保存并关闭文件。
在客户端上启动spiped服务并测试连接
现在,我们就可以开始我们的spiped
在客户机上服务,并使其在开机时自动启动:
sudo systemctl start spiped-send.service
sudo systemctl enable spiped-send.service
检查客户端上的隧道是否已正确设置:
sudo netstat -plunt
Redis client outputActive Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:8000 0.0.0.0:* LISTEN 3264/spiped
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1705/sshd
tcp6 0 0 :::22 :::* LISTEN 1705/sshd
正如你所看到的,
spiped
监听本地端口8000连接上。 现在,您应该能够通过将客户端指向本地接口上的端口8000来连接到远程Redis实例:
redis-cli -p 8000 ping
Redis client outputPONG
查询我们在本指南开头设置的测试键:
redis-cli -p 8000 get test
Redis client output"success"
这确认我们能够成功地到达远程数据库。 为了证实我们
无法在不使用的隧道与远程服务器Redis的通信,我们可以尝试直接连接到远程端口:
redis-cli -h redis_server_public_IP -p 6379 ping
Redis client outputError: Protocol error, got "\xac" as reply type byte
如您所见,如果通过隧道对其进行了正确加密,则只在远程Redis端口上接受流量。
扩展多客户端和服务器到服务器通信的上述示例
我们上面列举的例子使用了一个简单的例子,单个Redis服务器和单个客户端。然而,这些相同的方法可以应用于更复杂的相互作用。 扩展此示例以处理多个客户端是直接的。您需要执行以上列出的以下操作。- 安装Redis的客户端软件和
spiped
新的客户端软件包 - 将加密密钥传输到新客户端
- 副本
spiped
systemd单元文件到新的客户机 - 启动
spiped
服务,并使其在系统启动时启动
- 在新服务器上,安装Redis的服务器软件包及
spiped
- 为新的Redis服务器生成新的加密密钥(为文件使用唯一的名称)
- 从一台服务器复制加密密钥,其他进入
/etc/spiped
目录 - 创建
spiped
每个服务器(包括现有的服务器)上的systemd单元文件,以便每个服务器都有服务每个角色的文件:- 将外部端口映射到本地Redis的接收单元文件
- 发送单元文件将本地端口映射到远程服务器的公开端口
- 在新的Redis服务器上的防火墙中打开外部端口
- 配置每个Redis实例以连接到本地映射的端口,通过调整Redis配置文件来访问远程服务器(所需的指令取决于服务器的关系,有关更多详细信息,请参阅Redis文档)。