波斯码BOSSMA Information Technology

使用OpenVPN连通管理多个阿里云VPC网络

发布时间:2018年12月2日 / 分类:Architecture, SERVER / 816 次浏览 / 评论

这篇文章比较长,将从需求、思路、原理、架构、实施步骤、细节分析、高可用等几个方面来讲述OpenVPN的使用,如果看到很熟悉的内容或者不感兴趣的部分,请您跳过。

需求

公司网络环境更换,导致原来连接阿里云的VPN现在只能建立一个连接,网管解决不了,所以只好换别的VPN解决方案。阿里云自身有提供相关产品,既支持VPN网关连接,也支持单点SSL连接,还有高可用支持,唯一的缺点就是小贵,对于我这种平常简单管理使用有点不值。因为和谐上网的需要,之前也了解过有哪些免费VPN服务器可用,这次首先就想到了OpenVPN。

这里有三个环境:公司内部网络、阿里云测试环境、阿里云生产环境。测试环境和生产环境都基于阿里云VPC,都是私网,其中的机器都不能互相访问。

测试和生产环境可以用来部署OpenVPN的机器都是Windows操作系统。

需要在公司多人同时连接测试环境和生产环境,并能够访问其中的所有机器。

测试环境和生产环境目前不需要互通,以后可能有这方面的需求。

测试环境和生产环境不需要主动访问公司网络,以后也不会有这方面的需求。

思路

在生产环境部署OpenVPN Server,在测试环境和公司内部部署OpenVPN Client。

利用OpenVPN的client to client能力,使VPN节点之间互相可以访问,并能够路由请求到节点所在私网的其它机器,从而实现物理隔离的私网之间的互通;然后再使用防火墙(阿里云安全组)精细控制不同私网之间的访问权限,比如以后测试环境和生产环境的互通控制需求。

原理

因为使用OpenVPN的桥接模式没有成功,而且路由模式访问控制更加灵活,所以这里介绍的是OpenVPN的路由模式。

先简单看一张图,因为网上介绍的大部分都是在Linux上安装配置的,Windows上的Tun/Tap驱动如何实现的不是很清楚,但是应用到OpenVPN原理上应该差不多。其中用户态和核心态可以这样理解:用户态就是应用程序,核心态就是操作系统。

OpenVPN是IP层的VPN,节点安装后会在本机创建一个虚拟网卡;OpenVPN Server可以将访问OpenVPN其它节点所在私网的路由推送到OpenVPN Client,这些路由的接口对应到当前机器的虚拟网卡;所有使用VPN网络的应用将发送数据到这些虚拟网卡;OpenVPN会读取虚拟网卡的数据,封装后通过真实网卡发送到其它节点,以及从真实网卡接收从其它节点发送的数据,解析后发到虚拟网卡,然后数据再被使用VPN网络通信的具体应用获取到。

部署架构

在开始安装之前,先来看下整体的部署架构。

 

三个物理网络的网段分别为(注意这些网络不能有重复的,否则会有冲突无法正常连接):

公司内网:192.168.0.0/24

阿里云测试环境:172.31.200.0/24

阿里云生产环境:172.31.201.0/24

VPN网络的网段为:10.250.250.0/24

黑色的实线是实际的网络连接,三个环境分属不同的私网,他们和互联网都通过网关相连。

蓝色的虚线是VPN网络,VPN网络由OpenVPN的Server和Client节点组成,Server同时充当VPN网络的网关。

参与到VPN网络的三台机器都是私网内部的机器,非私网的网关服务器,需要给OpenVPN Server所在的机器绑定一个阿里云的弹性公网IP,因为客户端要跨越互联网来连接它。

如果VPN节点部署在网关服务器,很多路由就不用单独配置了,不过阿里云上无法实现,部署过程中会提到这些路由。

部署步骤

1、安装OpenVPN

国家将OpenVPN的网站和谐了,但是我们这里不是用于非法目的,所以需要自己想办法搞一个安装包,我这里版本是:2.4.6。

安装服务器端和客户端的基本上是一样的,需要注意服务器端要用来生成证书和密钥,所以安装服务器的时候把EasyRSA这个选项勾上。

2、创建证书和密钥

OpenVPN节点之间的通信需要认证和加密。

通过Windows自带的命令行管理工具进入easy-rsa目录,默认是在C:\Program Files\OpenVPN\easy-rsa

然后执行如下命令初始化环境:

然后生成CA根证书:build-ca,注意Common Name不要和后边其它密钥的重复。

然后创建迪菲·赫尔曼密钥:build-dh,这个是用在协商VPN数据加密密钥时用到的。

然后创建ta证书:openvpn –genkey –secret keys/ta.key,这个是用来防御DoS、UDP淹没等恶意攻击。

然后生成服务器端证书:build-key-server server,注意Common Name不能重复,这里还需要设置一个证书密码,随便取就行。

然后生成两个客户端 证书:build-key testclientbuild-key comclient,两个证书分别为测试环境和公司环境,Common Name不能重复,证书密码随便取。

这些证书或者密钥文件会生成到easy-rsa/keys目录下。


如果关闭了这个窗口,下次再生成证书的时候需要先执行下vars命令,加载变量到当前运行环境。

建议将ca.key文件放到一个离线的机器上,需要生成客户端证书的时候再复制过来,防止文件被窃取导致安全问题。

关于创建证书这块网上教程比较多,我这里没有截图,不明白的可以参考这个:https://www.cnblogs.com/airoot/p/7201227.html

3、配置并启动Server节点

server的配置文件需要放到安装目录的cnofigs目录下,包括:ca.crt、dh2048.pem、server.crt、server.key、ta.key、server.ovpn。

除了server.ovpn,其它文件都从easy-rsa/keys拷贝就可以了。

server.ovpn可以从 OpenVPN安装目录/sample-config 拷贝一个,然后根据需要进行修改,这里提供下这里的配置:

在ccd文件夹中新建名为testclient的文件,为testclient指定OpenVPN内部路由配置,也就是从OpenVPN Server到testclient节点的路由,文件内容:

现在就可以启动OpenVPN Server了。

启动OpenVPN GUI,在任务栏中右键点击Connect,连接成功后会有提示,并分配一个VPN的IP,这个IP应该是VPN网段的第一个IP,这里是10.250.250.1。

4、配置并启动阿里云测试环境Client节点

client的配置文件也是放到本机OpenVPN安装目录下configs中,包括:ca.crt、testclient.crt、testclient.key、ta.key、testclient.ovpn。

除了testclient.ovpn外,其它四个文件都是在OpenVPN Server生成的,拷贝过来就可以了。这里看下testclient.ovpn的配置:

启动OpenVPN GUI,在任务栏中右键点击Connect,连接成功后会有提示,并分配一个VPN的IP。

5、配置并启动公司Client节点

公司Client节点和阿里云测试环境Client节点是差不多的,区别就是证书文件不同,公司Client节点的使用comclient.crt、comclient.key,替换相关文件就可以了。comclient.ovpn可以复制testclient.ovpn,然后修改其中的cert和key的名字。

启动OpenVPN GUI,在任务栏中右键点击Connect,连接成功后会有提示,并分配一个VPN的IP。

VPN节点之间现在可以相互访问和连接了,可以试试ping一下。但是对于各个节点子网的访问还要继续配置下。

6、开放子网机器给VPN网段

阿里云的ECS服务器都会归属于某个安全组,安全组可以设置数据按照端口和协议进出的规则。默认情况下,安全组的入方向是全部被拒绝的,如果要从VPN网段访问这些机器,需要增加一个入方向的规则。这个规则在测试环境和生产环境都需要添加。

7、添加VPN网段路由

这时候会发现从客户端还是访问不了Server节点所在子网的其它机器,这是因为虽然数据可以到达这些机器,但是响应的数据无法回复给客户端,因为这些机器通过路由找不到客户端;所以生产环境这里还要做两个配置:

(1)在阿里云生产环境网关路由表中增加对VPN网段的路由,将VPN网段路由到OpenVPN Server所在机器。

(2)在OpenVPN Server上启动路由服务,也就是Windows服务:Routing and Remote Access

如果没有这个服务,请首先安装Windows组件:路由和远程访问,安装后应该就有了,注意不要配置NAT。

现在应该可以从客户端节点访问到Server节点所在子网的其它机器了。


阿里云测试环境也要做相同的配置:添加到VPN网段的路由,启动OpenVPN所在服务器的路由服务,这里就不啰嗦了。

这两个配置完成以后,就可以从公司网络连接阿里云测试和生产环境的所有机器了。


但是不要高兴的太早,这时候访问测试环境和生产环境的互通还是不行的,为什么呢?还是路由的问题,OpenVPN Server所在子网的机器找不到去测试环境网段的路由;所以在阿里云生产环境VPC路由中还需要增加路由条目,和上边类似:

目标网段换成172.31.200.0/24,下一跳还是OpenVPN Server所在的服务器。

这样就可以实现测试环境和生产环境的互访了。

8、控制测试环境和生产环境的互访权限

测试环境和生产环境的互通是比较危险的,因为如果部署的时候搞错配置,到时候数据可能乱掉。但是有时候一些公共的查询服务没必要搞两份,比如天气服务只在生产环境搞一份就行了,测试环境要使用也访问这个。这个问题一般可以通过防火墙解决,在阿里云上有一个安全组的概念,可以用来干这件事。比如这样配置:

这里完全禁止了测试环境访问生产环境,上边的端口范围可以根据自己的需要调整。阿里云入方向其实默认是全部禁止的,需要自己开放端口和协议。可以自己试试看看效果。

到这里安装配置基本上就完成了,感觉还是很繁琐的,中间的事比较多,希望读者能够顺利完成。但是从另一个方面也说明这个方案实现网络访问控制很灵活,可以配置的东西比较多。

细节分析

如果你很想搞清楚在VPN网络中数据是怎么流转的,以及上边的这些配置到底是怎么发挥作用的,这里写了一个流程,希望能够帮助到你。

以公司某台电脑C1: 192.168.0.220使用远程桌面访问生产环境某台服务器S1: 172.31.201.110为例:

1、C1安装OpenVPN后本机会创建一个虚拟网卡,这时候虚拟网卡还没有连接;

2、将OpenVPN Client连接到Server节点后,会分配到一个VPN地址(比如10.250.250.4),以及创建到生产环境的路由信息,这些信息是Server节点push过来的;

3、C1现在要访问S1了,通过本机路由信息得知需要走10.250.250.4对应的虚拟网卡接口;

4、C1的远程桌面客户端发送S1的连接请求,请求访问操作系统网络调用,最终封装为一个IP报文,通过虚拟网卡发送;

5、C1的OpenVPN此时会读取到通过虚拟网卡发送的数据,然后在IP报文的外层再包裹IP头和UDP协议,指示要前往生产环境时的真实网络IP信息,然后提交到C1的真实网卡;

6、C1的真实网卡会将数据通过本地网关发到互联网,最终发到生产环境OpenVPN 所在服务器V1,V1的真实网卡会根据UDP协议关联到当前节点的OpenVPN程序进行数据接收;

7、V1的OpenVPN取出内层的IP报文,发现目标地址172.31.201.110为局域网内部,通过局域网网关获取目标服务器Mac地址,直接走真实网卡,然后就到达了S1;

8、S1收到建立远程桌面的请求后,要给对方回个消息,这时候要知道数据发向哪里,它会发一个ARP广播,寻找10.250.250.4的物理地址;

9、生产环境的局域网中没有10.250.250.4,但是生产环境的网关知道,对于10.250.250.4请发送到OpenVPN 所在服务器V1;

10、V1服务器启动了路由服务,也就是V1是个路由器,会继续发现到10.250.250.4需要走本地虚拟网卡10.250.250.1,并获取虚拟网卡的Mac地址;

11、然后数据到达V1,通过V1的虚拟网卡进行发送,V1上的OpenVPN获取到响应数据,将这些数据再次封装,通过真实网卡、网关和互联网发送到公司内部的C1服务器;

12、C1的真实网卡会根据UDP协议关联到当前节点的OpenVPN程序进行数据接收,OpenVPN取出内层的IP报文,根据本地路由查找发现是给虚拟网卡的,然后写数据到虚拟网卡;

13、然后C1上的远程桌面客户端会从虚拟网卡中读取到S1发送给自己的数据。

这样就完成了一次数据的交互,后续的数据交互都是按照这个流程去走,中间过程还是比较复杂的,而且我省略了很多底层机制,重点描述了OpenVPN对数据的处理过程。

高可用

OpenVPN官网上有一个负载均衡/故障转移的策略:

原文:https://openvpn.net/community-resources/implementing-a-load-balancing-failover-configuration/

方法是部署多个OpenVPN Server,然后客户端的配置文件可以配置多个Server地址,客户端连接的时候可以随机从这些Server中选择,然后进行连接,如果Server连接不上了,则尝试连接别的Server。这个方案中证书密钥那一套共用就可以了,但是VPN网络的网段要区分开,比如一个使用172.31.202.0/24、另一个就使用172.31.203.0/24。

从网上搜索到的都是这个方案,但是这个方案只能保证OpenVPN Server的高可用。

如果是两个互通的私网,OpenVPN Client不可用时也就不能互通了。一个解决方案是Client也部署多个,分别连接到不同的Server,这样就有多个VPN网络可用了。但是要保证所有Client端和Server端的私网路由都指向同一个VPN网络的节点服务器,因为不能同时设置同一网段的路由到多个不同的VPN网络节点服务器,这还是有点难度的。

这时可以写一个测试环境驻守程序监控与生产环境的通信状态,如果连不上了,则说明当前的连接可能出现问题了,此时可以调用修改路由条目的API,将到其它私网的路由线路切换到别的OpenVPN Client节点服务器,同时还要通知所有要访问本网络的其它私网都修改下路由条目,以使大家都在同一个VPN网段内。这个分布式协调比较困难,如果可用性要求不是很高,出问题时通知人来处理会简单很多。

在阿里云上还有变通的方案,OpenVPN不是部署多套,而是在检测到节点服务器异常时,通过阿里云API迁移部署到正常的服务器,还使用原来的服务器IP(弹性IP),以及OpenVPN配置,这样路由规则不需要改变。如果不是在阿里云上,使用vip+keepalived,再加一些触发机制是不是也能实现?如果使用桥接模式是不是很容易就能解决这个问题了呢?这些方案因为成本较高,我没有测试,有兴趣或者需要的可以试试。

后记

写这篇文章主要是为了总结使用OpenVPN的技术经验,很多知识也是边写边查,因为涉及到的网络知识特别多,很多也没有提及或者展开,能力确实有限,可能有些描述错误之处,欢迎给我反馈。

 

本博客所有文章如无特别注明均为原创。
复制或转载请以超链接形式注明转自波斯码,原文地址《使用OpenVPN连通管理多个阿里云VPC网络

0

关键字:

建议订阅本站,及时阅读最新文章!
【上一篇】

发表评论