如何在Ubuntu 16.04中加密流量到Redis与Spubed

Redis是一个开源的键值数据存储,使用具有可选磁盘写入的内存存储模型进行持久化。它具有事务,发布/订阅消息模式和自动故障切换等功能。 Redis有大多数语言的客户端...

介绍

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
如果软件已安装并运行,您应该会看到:
PONG
让我们设置一个我们以后可以使用的密钥:
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
Active 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
Active 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
PONG
查询我们在本指南开头设置的测试键:
redis-cli -p 8000 get test
"success"
这确认我们能够成功地到达远程数据库。 为了证实我们无法在不使用的隧道与远程服务器Redis的通信,我们可以尝试直接连接到远程端口:
redis-cli -h redis_server_public_IP -p 6379 ping
Error: 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文档)。
如果需要,可以在每台机器上配置多个客户端单元文件,以将本地端口映射到远程服务器。在这些情况下,请确保在发送单元文件中的源socket规范中选择不同的未使用的本地端口。

结论

Redis是一个强大而灵活的工具,对于许多部署是无价的。但是,在不安全的环境中运行Redis是一个巨大的责任,使您的服务器和数据容易受到攻击或盗窃。如果您没有仅由可信方填充的隔离网络,则通过其他方式确保流量至关重要。本指南中介绍的方法只是确保Redis各方之间通信的一种方法。其他选项包括有安全通道隧道 ,或建立一个VPN