虚拟专用网连接异地机房部署方案

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lvshaorong/article/details/82181522

企业在两地三中心或者异地机房时候,往往要实现多个机房之间的直通,所谓直通就是两个机房设备分别属于不同的网段,双方可以互ping对方机房某台服务器的物理IP地址,不做NAT转换,服务器在收到数据包时也可以看到发送方的真实IP地址。实现这种效果的方式很多,比如拉专线。本文介绍最廉价的方案——通过公网连接的虚拟专用网连接方案。

假设专线或者购买专门的虚拟专用网设备往往意味着不菲的开销,本文主要介绍完全0成本的搭建方案,采用开源的Open微皮恩的实现方式,只需两个机房各有一台能上网的Linux服务器即可,并且只需要开放一个公网端口。

Open微皮恩有tun和tap两种模式可以选择,关于两种方式的区别网上有很多介绍,最主要的就是tun模式传输的是3层数据包,而tap模式比较牛逼可以传输二层的数据帧。tun模式使用比较普遍,搭建方便,比较适合配合公有云搭建。而tap模式搭建比较复杂,需要在服务端主机和客户端主机上新建虚拟网桥,然后桥接物理网卡和tap网卡。对于一些公有云来说不合适。以腾讯云为例,一台云主机只能绑定两块网卡,而且两块网卡各最多能绑定两个IP,不仅限制非常多,而且辅助网卡的流量是全部通过主网卡来流动的,建立网桥非常容易失败。

由于两地机房内的设备是分属于不同网段的,所以我们不需要二层数据帧在两地进行传递,我们只需让Open微皮恩当做一个路由来使用,路由两地的数据包即可。除非你两个机房共用同一个网段,需要在内网传输非IP协议,比如传输ARP请求,DHCP请求等才会用到tap,所以我们还是用搭建更方便更适合公有云的tun模式为好。

网络拓扑图大致如下,VPN服务器架设在A机房,同时做好相关网络的路由,也就是把VPN服务端服务器设置为内网网关,A机房的网段为10.123.1.0/24。然后把VPN客户端架设在B机房,也要做好相关的路由,把VPN服务器当成路由器或者网关。B机房的网段是192.168.31.0/24。同时VPN自己也会有一个网络,用来给加入的各个客户端分配IP,这里用的是10.9.0.1/24

在《Ubutnu16.04搭建Open微皮恩服务端过程记录》这篇文章中,我已经介绍了如何搭建一个虚拟专用网服务端,并介绍了如何生成证书和配置open微皮恩,关于生成证书的部分和之前一模一样,下面主要介绍路由的配置。

tun模式下,该微皮恩是一个点对点的网络,也就是说你的客户端生成的tun网卡只能够和服务端直接通讯,子网掩码为32,服务端也是一样,也就是说,你无法直接设置路由表,把某个客户端当成一个路由地址来配置,如下

tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  
          inet addr:10.9.0.1  P-t-P:10.9.0.2  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:14 errors:0 dropped:0 overruns:0 frame:0
          TX packets:14 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:100 
          RX bytes:1176 (1.1 KB)  TX bytes:1176 (1.1 KB)

此时我如果直接加一条路由,如

route add -net 192.168.31.0 netmask 255.255.255.0 gw 10.9.0.82
SIOCADDRT: Network is unreachable

是会失败的,无论在客户端还是服务端,会直接告诉你目的地不可达。虽然此时你可以从服务端ping通10.9.0.82,也可以从客户端ping通10.9.0.1,但是由于Open微皮恩是3层的点对点通讯,所以你无法将路由的目的地址填写为tun网卡的地址。

上面这种情况,对于客户端来说,它发出的流量会自动被Open微皮恩的服务端给NAT转换成服务端服务器的网卡地址,所以B机房还是可以ping通A机房内的服务器的,这和我们平时所用的翻wall原理类似。但是反过来,由于服务端不知道客户端有什么子网,所以从A机房ping B机房的服务器是不通的。

下面是服务端的iptables配置,可以看到由于POSTROUTING里有MASQUERDE,所以客户端的流量都会NAT成服务端相应网卡的地址,转换后访问A机房的服务器

Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
MASQUERADE  all  --  0.0.0.0/0            0.0.0.0/0 

由于我们的Open微皮恩是当做路由器来用,所以当然要让Open微皮恩知道B机房的网络192.168.31.0/24需要路由给哪个客户端,而且该客户端的地址是什么要告诉服务端才行。好处是Open微皮恩已经给我们解决了这个问题,那就是神奇的iroute配置,而且你在开启open微皮恩之后完全不需要手动改服务器的路由表,路由表的编写和配置都可以在配置文件里完成。

在Open微皮恩的默认情况下,客户端运行Open微皮恩之后,会默认将全部流量都发到Open微皮恩的服务端,所以此时我们需要修改客户端的配置文件,只让我们需要的流量,也就是目标地址为对方机房IP的数据包发送给Open微皮恩。同时我们要让A机房能看到B机房发来数据包的真实源IP,就需要去掉POSTROUTING中的MASQUERADE。

此处我们要解决的第一个问题就是让open微皮恩的服务端知道客户端后面有什么子网,这个要通过客户端连接时提交的客户端证书来判断,需要在服务端实现写好某个客户端后方的子网

我们先建立/etc/openvpn/ccd/文件夹,然后在这个文件夹里通过客户端证书的commen name建立一个配置文件,这里的客户端证书common name就是《Ubutnu16.04搭建Open微皮恩服务端过程记录》文章里建立客户端证书和密钥时执行的命令 ./build-key <密钥名> 中的这个<密钥名>,这里我用的是client1.

所以/etc/openvpn/ccd/client1中的内容就是

iroute 192.168.31.0  255.255.255.0
ifconfig-push 10.9.0.82 10.9.0.81

其中iroute就是告知本客户端后面有哪些网段,可以写多条并列,这样服务端收到数据包之后就知道该路由给谁了。

ifconfig-push 后面跟分配给该客户端的地址,这个地址一般是两个连着的数,子网掩码为30,网段取决于你服务端配置文件中server参数后面的网段。

#ifconfig-push中的每一对IP地址表示虚拟客户端和服务器的IP端点#它们必须从连续的/30子网网段中获取(这里是/30表示xxx.xxx.xxx.xxx/30,即子网掩码位数为30)#以便于与Windows客户端和TAP-Windows驱动兼容。明确地说,每个端点的IP地址对的最后8位字节必须取自下面的集合:[ 1, 2] [ 5, 6] [ 9, 10] [ 13, 14] [ 17, 18][ 21, 22] [ 25, 26] [ 29, 30] [ 33, 34] [ 37, 38][ 41, 42] [ 45, 46] [ 49, 50] [ 53, 54] [ 57, 58][ 61, 62] [ 65, 66] [ 69, 70] [ 73, 74] [ 77, 78][ 81, 82] [ 85, 86] [ 89, 90] [ 93, 94] [ 97, 98][101,102] [105,106] [109,110] [113,114] [117,118][121,122] [125,126] [129,130] [133,134] [137,138][141,142] [145,146] [149,150] [153,154] [157,158][161,162] [165,166] [169,170] [173,174] [177,178][181,182] [185,186] [189,190] [193,194] [197,198][201,202] [205,206] [209,210] [213,214] [217,218][221,222] [225,226] [229,230] [233,234] [237,238][241,242] [245,246] [249,250] [253,254]
---------------------来自 FunySunny 的博客https://blog.csdn.net/caizhengwu/article/details/80066338?utm_source=copy

然后我们可以在服务端配置文件/etc/openvpn/server.conf中加入route参数,可以在启动时自动的在系统路由表中加入这条路由,意味着指向该目的地址的数据包自动路由给Openvpn所在的网卡,省去手动配置的麻烦。如果这里不写也不手动配的话,那么会走默认路由,也就是发到公网上去了。所以iroute配置的路由一定要在server.xml里写到route参数中


;local a.b.c.d


port 1194

# TCP or UDP server?
;proto tcp
proto udp

dev tun


;dev-node MyTap


ca ca.crt
cert server.crt
key server.key  # This file should be kept secret

# Diffie hellman parameters.
# Generate your own with:
#   openssl dhparam -out dh2048.pem 2048
dh dh2048.pem


;topology subnet


server 10.9.0.0 255.255.255.0


ifconfig-pool-persist ipp.txt


;server-bridge 10.8.0.4 255.255.255.0 10.8.0.50 10.8.0.100


;server-bridge


push "route 10.123.1.0 255.255.255.0"
;push "route 192.168.10.0 255.255.255.0"
;push "route 192.168.20.0 255.255.255.0"


client-config-dir /etc/openvpn/ccd
;client-config-dir ccd
;route 192.168.40.128 255.255.255.248
route 192.168.31.0 255.255.255.0

route 10.9.0.0 255.255.255.252



;learn-address ./script


;push "redirect-gateway def1 bypass-dhcp"


;push "dhcp-option DNS 208.67.222.222"
;push "dhcp-option DNS 208.67.220.220"


client-to-client


;duplicate-cn


keepalive 10 120


;tls-auth ta.key 0 # This file is secret


;cipher BF-CBC        # Blowfish (default)
;cipher AES-128-CBC   # AES
;cipher DES-EDE3-CBC  # Triple-DES


comp-lzo


;max-clients 100


user nobody
group nogroup


persist-key
persist-tun


status openvpn-status.log


;log         openvpn.log
;log-append  openvpn.log


verb 3

;mute 20

其中push "route 10.123.1.0 255.255.255.0" 是向客户端下发服务端的网段,让客户端吧这个网段的数据包路由到服务端来,可实际没什么效果,需要客户端配置文件单独再写

client-config-dir /etc/openvpn/ccd 是指定客户端配置文件的目录

route 192.168.31.0 255.255.255.0是在open微皮恩服务端服务器上加入B机房网段的路由,有几个网段就写几行,也就是相当于在服务端所在系统上执行route add操作,加上这个之后,当服务端操作系统(可看做路由器)收到192.168.31.0/32的包之后,路由到tun0网卡上,让Open微皮恩服务端进行路由,加上这一行之后,启动vpn之后看ip route可以看到下面一行

192.168.31.0/24 via 10.9.0.2 dev tun0

route 10.9.0.0 255.255.255.252是和客户端配置文件中ifconfig-push一起,路由客户端后端网络用的

然后使用openvpn --deamon --config /etc/openvpn/server.conf即可启动服务端。

下面再看看客户端的配置文件

client        #这个client不是自定义名称 不能更改
dev tun       #要与前面server.conf中的配置一致。
proto udp              #要与前面server.conf中的配置一致。
remote 11.22.33.44 1194    #将11.22.33.44替换为你VPS的IP,1194为端口,端口与前面的server.conf中配置一致。
resolv-retry infinite
nobind
persist-key
persist-tun

resolv-retry 60
route-nopull
route 10.123.1.0 255.255.255.0 vpn_gateway
route 10.9.0.0   255.255.255.0 vpn_gateway
ping 2
ping-restart 5


ns-cert-type server
#redirect-gateway

#tls-auth ta.key 1
comp-lzo
verb 3
mute 20
route-method exe
route-delay 2
dhcp-option DNS 8.8.8.8
dhcp-option DNS 8.8.4.4


<ca>
-----BEGIN CERTIFICATE-----
省略
-----END CERTIFICATE-----

</ca>
<key>
-----BEGIN PRIVATE KEY-----
省略
-----END PRIVATE KEY-----

</key>
<cert>
   省略
</cert>

这里面比较重要的是这4行

route-nopull  是指不把默认网关设置为open微皮恩,要和#redirect-gateway一起使用,不这样设置就会让所有流量都走openvpn,比较浪费流量
route 10.123.1.0 255.255.255.0 vpn_gateway  在客户端主机的路由表自动加入10.123.1.0/24路由到tap0网卡也就是服务端
route 10.9.0.0   255.255.255.0 vpn_gateway    把目的地址为Open微皮恩网段内的地址,路由到tap0网卡

#redirect-gateway  去掉#号则所有流量都发往Open微皮恩,这是我们不想看到的

此时,启动客户端,服务端就可以ping通客户端主机上的192.168.31.199了,而且可以看到服务端的源IP,如果你把客户端所在网络其他主机的默认网关设置为客户端所在主机,或者是让其他同网段主机把10.9.0.0/24加入到路由表,网关为客户端所在主机,那么服务器的机器就可以平通192.168.31.0/24的所有主机了,现在就实现了A机房可以直通B机房了。

此时客户端因为把10.123.1.0/24数据包路由给了open微皮恩,然后送到服务端主机,所以客户端也可以ping通A机房的所有主机了(当然一开始就是这样),但是我们在服务端看到的地址还是经过NAT后的地址,不是客户端的源地址,因为上面讲的MASQUREADE的缘故,所以我们要删掉,在服务端主机执行下列命令

iptables -t nat -D POSTROUTING 1

同时,你的服务端和客户端都不要忘了开启路由转发功能

/etc/sysctl.conf加入下面一行

net.ipv4.ip_forward = 1

客户端如果接的是路由器,那么也会有被NAT再发到目的端的问题,所以有时候我们也需要去掉客户端的NAT

iptables -t nat -I POSTROUTING -d 10.123.1.0/24 -j RETURN

参考文章:https://blog.csdn.net/caizhengwu/article/details/80066338

https://www.cnblogs.com/rockbes/p/4754290.html

猜你喜欢

转载自blog.csdn.net/lvshaorong/article/details/82181522
今日推荐