跨地区三地机房互联OpenVpn部署方案

一丶环境介绍

  • 阿里云服务端VPN网关:47.98.63.78
  • IDC客户端VPN网关:192.168.99.5
  • 公司客户端VPN网关:192.168.17.212

思路:阿里云一台有公网ip的主机作为OpenVpn的server端并作为阿里云VPC的VPN网关,IDC和公司内部分别一台主机作为client端并冲到各地区的VPN互联网关。

二丶各节点服务部署

server端Openvpn服务配置

  1. 上传openvpn一键部署脚本至阿里云服务器并执行脚本进行安装
    GitHub地址:https://github.com/Nyr/openvpn-install
    脚本地址:https://gitee.com/wbdevops/openvpn-install/blob/master/openvpn-install.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
~]# sh openvpn-install.sh
Welcome to this OpenVPN "road warrior" installer!

I need to ask you a few questions before starting the setup.
You can leave the default options and just press enter if you are ok with them.

First, provide the IPv4 address of the network interface you want OpenVPN
listening to.
IP address: 47.98.63.78 // 阿里云服务器的公网ip

Which protocol do you want for OpenVPN connections?
1) UDP (recommended)
2) TCP
Protocol [1-2]: 2 // 使用tcp协议

What port do you want OpenVPN listening to?
Port: 11940

Which DNS do you want to use with the VPN?
1) Current system resolvers
2) 1.1.1.1
3) Google
4) OpenDNS
5) Verisign
DNS [1-5]: 1 // 使用系统本地dns

Finally, tell me your name for the client certificate.
Please, use one word only, no special characters.
Client name: gongsi-inside

Okay, that was all I needed. We are ready to set up your OpenVPN server now.
Press any key to continue...


.....中间内容省略

Finished!

Your client configuration is available at: /root/gongsi-inside.ovpn
If you want to add more clients, you simply need to run this script again!

// 出现此提示安装成功,生成的gongsi内网使用的客户端配置文件存放在/root/gongsi-inside.ovpn
  1. 修改openvpn服务端配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
~]# vim /etc/openvpn/server.conf
port 11940
proto tcp
dev tun
sndbuf 0
rcvbuf 0
ca ca.crt
cert server.crt
key server.key
dh dh.pem
auth SHA512
tls-auth ta.key 0
topology subnet
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
client-to-client // vpn客户端直接互联
client-config-dir ccd // 加载客户端单独配置
push "route 192.168.0.0 255.255.255.0" // 向客户端推送一条通往阿里云内网段的路由
push "route 192.168.17.0 255.255.255.0" // 向客户端推送一条通往公司内网段的路由
push "route 192.168.99.0 255.255.255.0" // 向客户端推送一条通往IDC机房内网段的路由
keepalive 10 120
cipher AES-256-CBC
user nobody
group nobody
persist-key
persist-tun
status openvpn-status.log
log-append openvpn.log // 配置server端日志,路径在/etc/openvpn/openvpn.log
verb 3
crl-verify crl.pem
  1. 修创建openvpn的ccd客户端加载目录,并创建IDC机房与公司内网段的配置文件
1
2
3
4
5
6
7
8
9
10
11
12
]# mkdir /etc/openvpn/ccd

// 创建公司内网的vpn配置文件
]# vim /etc/openvpn/ccd/gongsi-inside
ifconfig-push 10.8.0.2 255.255.255.0
iroute 192.168.17.0 255.255.255.0

// 创建IDC机房的vpn配置文件
]# vim /etc/openvpn/ccd/IDC-connent
ifconfig-push 10.8.0.3 255.255.255.0
iroute 192.168.99.0 255.255.255.0

  1. 修改openvpn启动脚本,添加服务启动时自动增加本地至IDC机房与公司内网的路由条目
1
2
3
4
5
6
7
8
]# vim /etc/init.d/openvpn

// 在启动命令行下面添加两条路由条目,这里面的vpn下一跳客户端要与ipp.txt文件中的一致
$openvpn --daemon --writepid $piddir/$bn.pid --cd $work --config $c $script_security
# 自动添加本地服务器至IDC机房的VPN网关路由
sleep 3
route add -net 192.168.99.0/24 gw 10.8.0.3
route add -net 192.168.17.0/24 gw 10.8.0.2
  1. 启动openvpn服务并开启路由转发功能
1
2
3
4
5
6
// 启动服务
]# /etc/init.d/openvpn start

// 开启路由转发功能
]# vim /etc/sysctl.conf
net.ipv4.ip_forward = 1
  1. 添加iptables地址伪装规则,并保存iptables规则
1
2
3
4
5
6
7
8
// 添加地址伪装规则
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -j MASQUERADE
iptables -t nat -A POSTROUTING -s 192.168.17.0/24 -j MASQUERADE
iptables -t nat -A POSTROUTING -s 192.168.99.0/24 -j MASQUERADE

// 保存iptables规则并备份
]# iptables-save
]# iptables-save > /root/scripts/iptables-20200402.bak
  1. 最后生成的路由条目与iptable规则
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// 路由条目
]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.17.0 10.8.0.2 255.255.255.0 UG 0 0 0 tun0
10.8.0.0 0.0.0.0 255.255.255.0 U 0 0 0 tun0
192.168.99.0 10.8.0.3 255.255.255.0 UG 0 0 0 tun0
192.168.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
169.254.0.0 0.0.0.0 255.255.0.0 U 1002 0 0 eth0
0.0.0.0 192.168.0.253 0.0.0.0 UG 0 0 0 eth0

// iptables规则
]# iptables -t nat -nL
Chain PREROUTING (policy ACCEPT)
target prot opt source destination

Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
SNAT all -- 0.0.0.0/0 192.168.0.0/24 to:192.168.0.99
MASQUERADE all -- 0.0.0.0/0 0.0.0.0/0
MASQUERADE all -- 10.8.0.0/24 0.0.0.0/0
MASQUERADE all -- 192.168.17.0/24 0.0.0.0/0
MASQUERADE all -- 192.168.99.0/24 0.0.0.0/0

Chain OUTPUT (policy ACCEPT)
target prot opt source destination
  1. 阿里云控制面板添加内网主机通往IDC与公司内网主机的路由条目,添加OpenVpn所监听端口的安全组
1
2
3
4
5
6
7
控制台 --> 专有网络VPC --> 最左边路由表 --> 管理 --> 添加路由条目
① 到达IDC华为vpn网段 192.168.98.0/24 --> VPNserver id
② 到达IDC内网段 192.168.99.0/24 --> VPNserver id
③ 到达公司内网段 192.168.17.0/24 --> VPNserver id
④ 到达openvpn虚拟网段 10.8.0.0.0/24 --> VPNserver id

//注意:第④条路由条目不添加的话会导致阿里云只有vpnserver这台主机和其他地区的主机互联,阿里云VPC其他主机无法与其他主机互联

公司内网Openvpn客户端配置

  1. 添加epel源地址并下载openvpn服务
1
2
~]# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
~]# yum install -y openvpn
  1. 将OpenVpn阿里云服务端生成的gongsi-inside.ovpn上传至公司内网VPN网关17.226主机的/etc/openvpn/client目录下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
~]# vim /etc/openvpn/client/gongsi-inside.ovpn
// 内容如下
client
dev tun
proto tcp
sndbuf 0
rcvbuf 0
remote 47.98.63.78 11940
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
auth SHA512
cipher AES-256-CBC
route 192.168.17.0 255.255.255.0 net_gateway // 设置内网主机的17.0网段走主机本地网络的路由,不添加vpn服务器推送的17.0网络路由,缺少会导致访问17.0主机的流量走vpn服务器
key-direction 1
verb 3

# 注释这两行,解决windows连接成功后无法使用域名解析
# ignore-unknown-option block-outside-dns
# block-outside-dns

# 如果注释上面两行还不能域名解析就打开下面的注释
# comp-lzo
// --- 证书部分省略 ---
  1. 将openvpn客户端加入到开机自启动
1
2
3
]# vim /etc/rc.local
/usr/sbin/openvpn --daemon --cd /etc/openvpn/client --config gongsi-inside.ovpn --log-append /var/log/gongsi-inside.log
]# chmod 777 /etc/rc.local
  1. 开启客户端的路由转发功能与iptables地址伪装功能
1
2
3
4
5
6
7
8
9
// 开启路由转发为了公司内网其他主机可以通过此主机作为vpn的网关转发流量到阿里云0.0网段与IDC机房99.0网段
]# vim /etc/sysctl.conf
net.ipv4.ip_forward = 1
]# sysctl -p

// 开启地址伪装
]# iptables -t nat -A POSTROUTING -j MASQUERADE
]# iptables-save

  1. 启动VPN网关客户端的服务并查看路由表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 注意此处的客户端配置文件名称
]# /usr/sbin/openvpn --daemon --cd /etc/openvpn/client --config gongsi-inside.ovpn --log-append /var/log/gongsi-inside.log

// 查看VPN网关客户端的路由表
~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.17.1 0.0.0.0 UG 100 0 0 eth0
10.8.0.0 0.0.0.0 255.255.255.0 U 0 0 0 tun0
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
192.168.0.0 10.8.0.1 255.255.255.0 UG 0 0 0 tun0
192.168.17.0 192.168.17.1 255.255.255.0 UG 0 0 0 eth0
192.168.17.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0
192.168.99.0 10.8.0.1 255.255.255.0 UG 0 0 0 tun0

// 其中10.8.0.0/192.168.0.0/192.168.17.0/192.168.99.0路由条目由vpn服务器推送添加
// 此时在本地访问10.0.1可通,访问阿里云内网192.168.0.0网段可通
// 阿里云访问10.8.0.0网段可通,访问公司内网192.168.17.226内网VPN网关可通,无法访问整个192.168.17.0/24整个网段,需要在17.0网关路由器上面添加一条静态路由(或者17.0网段的主机本地添加一条路由条目):访问阿里云192.168.0.0/24,IDC机房192.168.99.0/24的请求将流量转发到VPN网关服务器的192.168.17.226主机即可实现访问整个网段。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@gitlab-jumpserver-jenkins1 openvpn]# iptables -t nat -nL
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

错误解决

问题一:迁移了公司内网Openvpn网关服务器之后,在另外一台服务器启动vpn网关服务,发现公司内网所有服务器无法ping通VPN网关服务器,公司内网也无法访问IDC和阿里云内网;但是阿里云和IDC机房可以访问到公司内网所有服务器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 经过tcpdump抓包和查看内网vpn网关服务器的路由表,发现
[root@Centos7-Test ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.17.1 0.0.0.0 UG 100 0 0 eth0
10.8.0.0 0.0.0.0 255.255.255.0 U 0 0 0 tun0
192.168.0.0 10.8.0.1 255.255.255.0 UG 0 0 0 tun0
192.168.17.0 192.168.17.1 255.255.255.0 UG 0 0 0 eth0 // 注意这一条路由,是由openvpn网关服务器的配置文件route 192.168.17.0 255.255.255.0 net_gateway生成的
192.168.17.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0
192.168.99.0 10.8.0.1 255.255.255.0 UG 0 0 0 tun0


// 错就错在这一条路由条目,删除之后就内网服务器就能ping通vpn网关已经IDC与阿里云的任何服务器了
route del -net 192.168.17.0/24 gw 192.168.17.1