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

介绍

Redis是一个开源键值数据存储,使用内存存储模型和可选的磁盘写入来实现持久性。它具有事务,发布/订阅消息传递模式以及其他功能之间的自动故障转移功能。Redis的客户使用大多数语言编写,并在其网站上提供推荐的客户。

Redis不提供自己的任何加密功能。它的运作假设它已部署到隔离的专用网络,只能由可信方访问。如果您的环境与该假设不匹配,则必须单独将Redis流量包装在加密中。

在本指南中,我们将演示如何使用名为spiped的安全管道程序加密Redis流量。Redis客户端和服务器之间的流量将通过专用加密隧道进行路由,类似于专用SSH隧道。我们将使用两台Ubuntu 16.04服务器进行演示。

课程准备

首先,您应该拥有一sudo台在每台计算机上都配置了权限的非root用户。没有服务器的同学可以在这里购买,不过我个人更推荐您使用免费的腾讯云开发者实验室进行试验,学会安装后再购买服务器。此外,本指南将假设您已准备好基本防火墙。如果您使用的是腾讯云的CVM服务器,您可以直接在腾讯云控制台中的安全组进行设置。

当您准备好继续时,请按照下面的步骤操作。

什么是spiped?

spiped实用程序易于安装和配置,以便在两个网络套接字(常规网络端口或Unix套接字)之间进行安全通信。它可用于配置两个远程服务器之间的加密通信。客户端连接到本地端口并将其用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

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

安装完成后,通过键入以下内容测试您是否可以在本地连接到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服务器上生成加密密钥

接下来,在Redis服务器上的/etc中创建一个spiped配置目录,以存储我们将为加密生成的密钥:

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服务器上有密钥,我们可以使用systemd单元文件在服务器上进行spiped设置。

为Redis服务器创建systemd单元文件

spiped实用程序非常简单,不支持读取配置文件。由于必须手动配置每个管道,因此Ubuntu软件包不附带init脚本以在引导时自动启动管道。

要解决这些问题,我们将创建一个简单的systemd单元文件。在/etc/systemd/system目录中打开一个新的单元文件以开始:

sudo nano /etc/systemd/system/spiped-receive.service

在内部,创建一个[Unit]部分来描述单元并建立排序,以便在网络可用后启动该单元:

[Unit]
Description=spiped receive for Redis
Wants=network-online.target
After=network-online.target

接下来,打开一个[Service]部分以定义要运行的实际命令。我们将用spiped来使用以下选项:

  • -F:在前台运行。systemd init系统旨在尽可能管理在前台运行的服务。在前台运行简化了所需的配置。
  • -d:解密来自源套接字的流量。这告诉了spiped关于加密的方向,以便它知道解密来自源的流量并加密来自目标的流量。
  • -s:这定义了源套接字。IP地址必须在方括号中,后跟冒号,然后是端口。对于Redis服务器,应将其设置为公共IP地址和Redis端口。
  • -t:目标套接字。这是解密后转发流量的地方。默认情况下,Redis会侦听本地主机上的端口6379,因此这是我们必须使用的。
  • -k:指定要使用的密钥文件。这应该指向我们之前生成的加密密钥。

所有这些选项都将放在一个ExecStart指令中,这是我们在本节中需要的唯一项目:

[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如果启用,那么何时自动启动该单元:

[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

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

启动Spiped服务并在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

这将打开对spiped正在侦听的公共接口上的端口6379的访问。该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单元文件

我们需要在客户端的spiped创建一个systemd单元文件,就像我们在Redis服务器上一样。

键入以下内容打开新的systemd单元文件:

sudo nano /etc/systemd/system/spiped-send.service

在里面,打开一个[Unit]部分来描述服务并确定它取决于网络可用性:e

[Unit]
Description=spiped sending for Redis
Wants=network-online.target
After=network-online.target

接下来,打开一个[Service]部分来执行该spiped过程。此处使用的选项与Redis服务器上使用的选项非常相似,但有以下区别:

  • -e:指定进入源套接字的流量需要加密。这将建立源套接字和目标套接字之间的关系。
  • -s:定义源套接字,就像之前一样。但是,在这种情况下,源是本地接口上的任意可用端口,本地Redis客户端可以连接到该端口。
  • -t:定义目标套接字,就像之前一样。对于客户端,这将是远程Redis服务器的公共IP地址和打开的端口。

这些将再次使用ExecStart指令来设置:

[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]部分来定义启用单元的时间:

[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
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软件包
  • 将加密密钥传输到新客户端
  • spipedsystemd单元文件复制到新客户端计算机
  • 启动该spiped服务并使其在开启时启动

要设置安全的服务器到服务器通信(例如,用于复制或群集),您需要设置两个并行隧道:

  • 在新服务器上,安装Redis服务器软件包和 spiped
  • 为新的Redis服务器生成新的加密密钥(为该文件使用一个唯一名称)
  • 将加密密钥从一个服务器复制到另一个服务器的/etc/spiped目录中
  • 在每个服务器(包括现有服务器)上创建spipedsystemd单元文件,以便每个服务器都有一个服务于每个角色的文件:
    • 将外部端口映射到本地Redis的接收单元文件
    • 将本地端口映射到远程服务器的公开端口的发送单元文件
  • 在新的Redis服务器上打开防火墙中的外部端口
  • 通过调整Redis配置文件,将每个Redis实例配置为连接到本地映射的端口以访问远程服务器(所需的指令取决于服务器的关系。有关更多详细信息,请参阅Redis文档)。

如有必要,可以在每台计算机上配置多个客户端单元文件,以将本地端口映射到远程服务器。在这些情况下,请确保在发送单元文件中的源套接字规范中选择其他未使用的本地端口。

结论

Redis是一个功能强大且灵活的工具,对许多部署都非常有用。但是,在不安全的环境中运行Redis需要承担巨大的责任,它有可能使您的服务器和数据容易受到攻击或盗窃。如果您没有仅由受信任方填充的隔离网络,则必须通过其他方式保护流量。本指南中概述的方法只是确保Redis各方之间通信的一种方法。其他选项包括使用stunnel进行隧道连接或设置VPN。

更多Ubuntu教程请前往腾讯云+社区学习更多知识。


参考文献:《How To Encrypt Traffic to Redis with Spiped on Ubuntu 16.04》

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏北京马哥教育

批量管理自动化运维100台小规模服务器

---- 目录 1.脚本背景介绍 2.脚本技术需求分析 2.1 SSH免登陆认证 2.2 Expect实现key分发 2.2 PSSH家族命...

2.2K15
来自专栏LIN_ZONE

thinkphp5中使用phpmailer实现发送邮件功能(转载)

一、开启SMTP服务(使用php发送邮件需要用到SMTP服务,这里以163邮箱的SMTP服务为例)。

1561
来自专栏腾讯云安全的专栏

phpmyadmin安全配置小技巧

3429
来自专栏耕耘实录

SSH免密远程登录的配置与实现

操作系统:CentOS Linux release 7.4.1708 (Core)

1292
来自专栏云知识学习

Tomcat开启SSL 8443端口的方法

TOMCAT_HOME:/usr/local/tomcat7,安装方法参考:windows和linux 下将tomcat注册为服务

60311
来自专栏云计算教程系列

如何在服务器上安装OpenLDAP

轻量级目录访问协议(LDAP)是一种标准协议,旨在通过网络管理和访问分层目录信息。目录服务在开发内部网和与互联网程序共享用户、系统、网络、服务和应用的过程中占据...

3322
来自专栏FreeBuf

Redis未授权访问漏洞的重现与利用

前言: 最近配置openvas的时候安装了redis,听说曾经曝出过一个未授权访问漏洞,便找了一下相关资料想自己动手复现一下漏洞的利用过程,当然所有的攻击性操作...

29810
来自专栏Java帮帮-微信公众号-技术文章全总结

Centos6.5安装配置nginx

出现如下代码: nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is...

1123
来自专栏Debian社区

Debian Linux下安装配置 Pure-ftpd

PureFTPd 是一款专注于程序健壮和软件安全的免费FTP服务器软件(基于BSD License)。其可以在多种类Unix操作系统中编译运行,包括Linux、...

1942
来自专栏Samego开发资源

shell脚本加密 | shc

3803

扫码关注云+社区

领取腾讯云代金券