如何使用Ansible和TINC VPN保护您的服务器基础结构

在本教程中,我们将演示如何使用Ansible,配置管理工具,配置VPN TINC到你的Ubuntu和CentOS服务器之间的安全网络通信。如果您的服务器使用的是共享的网状VPN的TINC提供特别有用...

介绍

在本教程中,我们将演示如何使用Ansible,配置管理工具,建立一个网状VPN与TINC到你的Ubuntu和CentOS服务器之间的安全网络通信。

如果你的服务器使用一个共享的网络,就像一个网状VPN是特别有用的DigitalOcean的数据中心范围内的专用网络的功能,因为它可以使您的服务器好像他们是一个真正的专用网络上隔离的通信。 VPN的身份验证和加密功能提供的额外的安全保护层将保护您的私有服务 - 数据库,Elasticsearch集群和更多 - 的网络通信免受未经授权的访问或攻击。

网格VPN图

在多个服务器之间手动配置和维护VPN是困难和容易出错的,因为多个配置和密钥文件需要在所有VPN成员之间分布。 因此,配置管理工具应该用于任何实际的网格VPN设置,其成员可能在某个时刻更改。 可以使用任何配置管理工具,但本教程使用Ansible,因为它是流行和易于使用。 该Ansible 剧本 ,本教程使用, ansible-TINC ,一直在Ubuntu 14.04和CentOS 7服务器进行测试。

背景读书

你应该能够遵循这个教程,并设置一个网格VPN不知道太多关于Ansible或Tinc,因为包括的Playbook将为你做大部分的工作。 但是,在某些时候,您可能想了解它们的工作方式,以便您了解您正在设置的详细信息。

这TINC VPN教程介绍如何安装和手动配置VPN TINC。 使用Ansible自动化过程使得它更容易管理。

如何安装和配置Ansible提供了一个非常高层次的介绍如何Ansible的作品。 如果你要开始写Ansible Playbook自动化系统管理任务,请查看本教程

先决条件

本地机器

本地机器是你将执行Ansible Playbook的地方。 这可能是您的本地计算机(例如笔记本电脑)或用于管理服务器的其他服务器。 如前面提到的,它需要能够连接到每个远程服务器作为root

您的本地计算机需要安装Ansible 2.0+。 请参阅官方Ansible安装文档 ,如果你需要安装它,因为安装过程中根据您的操作系统或分发而异。

本地机器还需要安装Git的,所以你可以很容易地下载副本ansible-TINC剧本。 同样,因为安装说明取决于你的本地计算机上,请参考官方Git的安装指南

远程服务器

远程服务器是您要配置为使用Tinc VPN的主机。 你应该从至少两个开始。 要使用Ansible Playbook,他们必须:

  • 运行Ubuntu 14.04或CentOS 7
  • 并可通过在本地计算机(其中安装Ansible) root用户, 使用公钥认证

注意:这是不可能利用此时一个不同的远程用户由于与Ansible同步模块的错误 ,它的剧本用途。

如果你还没有为残疾人密码验证root ,你可以通过添加这样做PermitRootLogin without-password到你/etc/ssh/sshd_config文件,然后重新启动SSH。

如果您正在使用DigitalOceanDroplet是同一个数据中心内,你应该启用专用网络上所有的人。 这将允许您使用专用网络接口, eth1 ,对于加密的VPN通信。 提供的Playbook假设每个VPN节点将使用相同的网络设备名称。

下载Ansible-Tinc Playbook

一旦你准备好开始,使用git clone下载剧本的副本。 我们将它克隆到我们的主目录:

cd ~
git clone https://github.com/thisismitch/ansible-tinc

现在切换到新下载的ansible-tinc目录:

cd ansible-tinc

注:本教程的其余部分假定您在ansible-tinc目录,在本地机器上。 所有Ansible命令必须从此目录中执行。 此外,所有的文件引用的除外/etc/hosts ,相对于这条道路,如hosts是指~/ansible-tinc/hosts

接下来,我们将向您展示如何使用Playbook创建网格VPN。 如果您熟悉Ansible,可能需要一些时间浏览Playbook的内容。 从本质上讲,它安装并配置使用TINC网状VPN,而且还增加了便利性条目到每个服务器的/etc/hosts

创建主机清单文件

运行该剧本之前,你必须创建一个hosts包含有关您希望在TINC VPN,包括服务器的信息文件。 我们现在来看一下hosts文件的内容。

〜/ ansible-tinc / hosts示例
[vpn]
node01 vpn_ip=10.0.0.1 ansible_host=192.0.2.55
node02 vpn_ip=10.0.0.2 ansible_host=192.0.2.240
node03 vpn_ip=10.0.0.3 ansible_host=198.51.100.4
node04 vpn_ip=10.0.0.4 ansible_host=198.51.100.36

[removevpn]

第一行, [vpn]指定主机项正下方是“VPN”组的一部分。 此组的成员将在其上配置Tinc mesh VPN。

  • 第一列是您设置主机的库存名称,“node01”在示例的第一行,如何Ansible将引用主机。 此值用于配置TINC连接,以产生/etc/hosts条目。 不要在这里使用连字符,因为Tinc不支持他们在主机名
  • vpn_ip是节点将用于VPN的IP地址。 将此分配给您希望服务器用于其VPN连接的IP地址
  • ansible_host必须设置为你的本地计算机可以(也就是一个真实的IP地址或主机名)到达节点的值

因此,在示例中,我们有四个主机,我们要在网格VPN中配置,如下所示:

网格VPN图示例

一旦你的hosts文件包含所有你想要在你的VPN包括服务器,保存更改。 请确保它不包含重复的条目(主机名, vpn_ip地址或ansible_host值)。

此时,您应该测试Ansible是否可以连接到清单文件中的所有主机:

ansible all -m ping

他们都应该用一个绿色的“SUCCESS”消息回答。 如果任何连接失败,请检查您的主机文件有错误,并确保所有有问题的服务器满足列出的要求的先决条件部分在移动之前。

查看组变量

运行该剧本之前,您可能需要查看的内容/group_vars/all文件:

/ group_vars / all
---

netname: nyc3
physical_ip: "{{ ansible_eth1.ipv4.address }}"

vpn_interface: tun0

vpn_netmask: 255.255.255.0
vpn_subnet_cidr_netmask: 32

的两个最重要的变量是physical_ipvpn_netmask

  • physical_ip指定要TINC绑定到哪个IP地址。 在这里,我们正在利用一个Ansible事实将其设置到的IP地址eth1网络设备。 在DigitalOcean, eth1是专用网络接口,因此专用网络必须启用,除非你宁愿使用公共网络接口eth0 ,由它的值更改为{{ ansible_eth0.ipv4.address }}
  • vpn_netmask指定将被应用到VPN接口的网络掩码。 默认情况下,它被设置为255.255.255.0 ,这意味着每个vpn_ip是一个C类地址可与其他主机在同一子网内只进行通讯。 例如,一个10.0.0.x将无法与通信10.0.1.x除非子网通过改变放大主机vpn_netmask为类似255.255.0.0

注意:VPN的安全优势可以扩展到服务器通过公共互联网,但请记住,通信仍将具有相同的延迟和带宽限制的非VPN连接。

以下是其他设置的说明:

  • netname指定网络名TINC。 它被设置为nyc3默认。
  • vpn_interface是TINC将使用虚拟网络接口的名称。 tun0默认。
  • vpn_subnet_cidr_netmask设置为32,表示一个单主机子网(点对点),因为我们正在配置网状VPN。 不要更改此值。

查看组变量后,您应该已经准备好进行下一步。

部署Tinc VPN

现在已创建了广告资源主机文件并审核了组变量,您可以通过运行Playbook来部署Tinc并在您的服务器上设置VPN。

ansible-tinc目录,运行这个命令来运行剧本:

ansible-playbook site.yml

当Playbook运行时,它应该提供每个被执行的任务的输出。 如果一切配置正确,你应该看到几个okchanged状态,和零failed状态:

node01                     : ok=18   changed=15   unreachable=0    failed=0
node02                     : ok=18   changed=15   unreachable=0    failed=0
node03                     : ok=21   changed=19   unreachable=0    failed=0
node04                     : ok=21   changed=19   unreachable=0    failed=0

如果没有失败的任务,清单文件中的所有主机应该能够通过VPN网络相互通信。

测试VPN

登录到您的第一台主机并ping第二台主机:

ping 10.0.0.2

因为剧本自动创建/etc/hosts指向库存主机名到每个成员的VPN的IP地址条目,你也可以做这样的事情(假设被命名为您的主机之一node02在Ansible hosts文件):

ping node02

无论哪种方式,您都应该看到有效的ping响应:

[secondary_label Output:
PING node02 (10.0.0.2) 56(84) bytes of data.
64 bytes from node02 (10.0.0.2): icmp_seq=1 ttl=64 time=1.42 ms
64 bytes from node02 (10.0.0.2): icmp_seq=2 ttl=64 time=1.03 ms
...

随意测试其他节点之间的VPN连接。

注:TINC使用端口655 如果您的ping测试不工作,请确保每个节点的防火墙允许VPN使用的真实网络设备上的适当流量。

完成测试后,您的网状VPN即可使用!

配置服务和应用程序

现在,您的网格VPN已设置,您需要确保配置您的后端服务和应用程序使用它(在适当的情况下)。 这意味着,应当通过VPN进行通信的任何服务需要使用相应的VPN的IP地址( vpn_ip )代替正常私人IP地址。

例如,假设你正在运行一个与LEMP Nginx的堆叠NODE01node02上一个MySQL数据库。 MySQL应该配置为绑定到VPN的IP地址10.0.0.2 ,PHP应用程序应在连接到数据库10.0.0.2和Nginx的应该听192.0.2.55 (NODE01的公网IP地址)。

对于另一示例,如果NODE01,NODE02node03是节点在Elasticsearch簇,Elasticsearch应配置为使用10.0.0.110.0.0.210.0.0.3作为节点的IP地址。 同样,连接到群集的任何客户端也应使用VPN地址。

防火墙注意事项

您可能需要更新防火墙规则,以允许VPN网络设备上的流量“tun0”或VPN IP地址。

如何添加或删除服务器

添加新服务器

在中列出的所有服务器[vpn]组中的hosts文件将是VPN的一部分。 要添加新的VPN成员,只需将新的服务器添加到[vpn]组,然后重新运行剧本:

ansible-playbook site.yml

删除服务器

要删除VPN成员,将hosts需要的下移除服务器的条目[removevpn]对文件的底部组。

例如,如果我们想要删除node04,hosts文件是这样的:

hosts - 从VPN中删除node04
[vpn]
node01 vpn_ip=10.0.0.1 ansible_host=192.0.2.55
node02 vpn_ip=10.0.0.2 ansible_host=192.0.2.240
node03 vpn_ip=10.0.0.3 ansible_host=198.51.100.4

[removevpn]
node04 vpn_ip=10.0.0.4 ansible_host=198.51.100.36

保存hosts文件。 请注意, vpn_ip是可选的,闲置[removevpn]组成员。

然后重新运行Playbook:

ansible-playbook site.yml

这将停止TINC并删除TINC配置,并从成员主机密钥文件[removevpn]组,从VPN删除它们。

请注意,从VPN删除主机将导致在剩余的VPN成员上的孤立的tinc主机文件和/ etc / hosts条目。 这不应影响任何东西,除非您稍后向VPN添加新服务器,但重用已停用的名称。 删除相应/etc/hosts每个服务器上的条目,如果这是你的一个问题。

结论

您的服务器基础设施现在应该通过网格VPN安全,通过使用Tinc和Ansible! 如果您需要修改剧本,以满足您的特定需求,可随时叉它在GitHub上

祝你好运!