多机房情况下,有时候需要将跨机房内网打通,现在还是使用ipsec的多。而且相对也比较成熟。IPsec全称ip Security,由两类协议组成,分别为AH协议(Authentication Header)和ESP协议(Encapsulated Security Payload),由于AH协议无法提供数据加密,所有数据在传输时以明文传输,且AH由于提供数据来源确认,所以无法穿越NAT,所以这两种协议中ESP协议应用更广泛一些。VPN只是IPSec的一种应用方式。刚好有空余的机器就简单实验一下。

协议 数据来源确认 数据加密 数据完整性确认 其他
AH AH常用摘要算法(单向Hash函数)MD5和SHA1
ESP ESP通常使用DES、3DES、AES等加密算法实现数据加密,使用MD5或SHA1来实现数据完整性

搭建

实验环境

|Region|Public IP|Private IP|Gateway| |—|—|—| |CD-Host-A|118.24.48.193|172.27.0.12|172.27.0.1| |CD-Host-B|118.24.49.251|172.27.0.4|172.27.0.1| |GZ-Host-A|193.112.154.165|172.16.0.10|172.16.0.1| |GZ-Host-B|193.112.143.226|172.16.0.16|172.16.0.1|

版本信息: 规划:其中CD-A和GZ-A这两台机器作为vpn服务器。 版本:Linux Libreswan 3.20 (netkey) on 3.10.0-514.26.2.el7.x86_64 OS:CentOS Linux release 7.2.1511 (Core)

安装初始化(主机CD-A)

1
yum install -y openswan

系统参数调整

1
2
3
4
5
6
7
8
cat /etc/sysctl.conf #修改参数如下
net.ipv4.ip_forward = 1
net.ipv4.conf.default.rp_filter = 0
sysctl -p #执行命令让参数生效
setenforce 0 #关闭selinux
iptables -nvL #确认端口开放UDP 500 4500
#关闭ipmp重定向(是否需要)
#sysctl -a | egrep "ipv4.*(accept|send)_redirects" | awk -F "=" '{print$1"= 0"}' >> /etc/sysctl.conf

主配置如下

1
2
3
4
5
6
7
8
#cat /etc/ipsec.conf
#version 2
config setup
	protostack=netkey
	dumpdir=/var/run/pluto/
	nat_traversal=yes
	virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12,%v4:25.0.0.0/8,%v4:100.64.0.0/10,%v6:fd00::/8,%v6:fe80::/10
include /etc/ipsec.d/*.conf

配置key认证

1
echo 0.0.0.0   0.0.0.0 : PSK "arvon.top" > /etc/ipsec.d/cn.secrets#引号内为key字段

**关于配置:**可以通过命令man ipsec.conf获得帮助 填写连接的配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
#cat /etc/ipsec.d/cn.conf
conn cn-test
	ike=3des-sha1
	authby=secret
	phase2=esp
	phase2alg=3des-sha1
	compress=no
	pfs=yes
	type=tunnel
	left=172.27.0.12
	leftid=118.24.48.193
	leftsubnet=172.27.0.0/24
	leftnexthop=%defaultroute
	right=193.112.154.165
	rightid=193.112.154.165
	rightsubnet=172.16.0.0/24
	rightnexthop=%defaultroute
	auto=add

启动ipsec **Tips:**修改连接配置auto=start,这样就不用每次重启ipsec后手动起连接了

1
2
systemctl start ipsec
ipsec auto --up cn-test

安装初始化(主机GZ-A)

**注意:**配置基本可以从CD-A照搬过来,不过由于我这里的环境是云端不同子网,所以连接的配置还需要做一些修改如下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
#cat /etc/ipsec.d/cn.conf
conn cn-test
	ike=3des-sha1
	authby=secret
	phase2=esp
	phase2alg=3des-sha1
	compress=no
	pfs=yes
	type=tunnel
	left=118.24.48.193
	leftid=118.24.48.193
	leftsubnet=172.27.0.0/24
	leftnexthop=%defaultroute
	right=172.16.0.10
	rightid=193.112.154.165
	rightsubnet=172.16.0.0/24
	rightnexthop=%defaultroute
	auto=add

此时,两台IPsec server已经联通了,不过是CD-B和GZ-B无法和对端网络联通,并没有达到实验目的,很明显现在主要问题是路由

问题

Step0: 方便排错

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
route -n #查看路由
ip rule ls #查看路由优先级
ip route get 172.27.0.4 #获取IP地址使用的路由
route add -net 10.0.60.0 netmask 255.255.255.0 gw 10.0.50.1 #添加路由
route del -net 172.16.0.0 netmask 255.255.255.0 eth0 #删除路由需要写完整
#systemctl start firewalld
iptables -t nat -F #清除防火墙nat规则
iptables -t nat -nvL #查看防火墙nat规则
tcpdump -n -i eth0 dst 172.27.0.12 #抓取eth0网卡上目标IP为12的包
tcpdump -n -i eth0 src 172.27.0.12 #抓取eth0网卡上源IP为12的包

Step1:以CD-A为例,当前路由如下

1
2
3
4
5
6
[root@VM_0_12_centos ipsec.d]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         172.27.0.1      0.0.0.0         UG    0      0        0 eth0
169.254.0.0     0.0.0.0         255.255.0.0     U     1002   0        0 eth0
172.27.0.0      0.0.0.0         255.255.240.0   U     0      0        0 eth0

Step2: 在内网其他机器添加到VPN的路由

1
2
3
4
#在CD-B添加到CD-A的路由
route add -net 172.16.0.0 netmask 255.255.255.0 gw 172.27.0.12
#在GZ-B添加到GZ-A的路由
route add -net 172.27.0.0 netmask 255.255.255.0 gw 172.16.0.10

Step3:在vpn网关机器上进行SNAT

1
2
3
iptables -t nat -A POSTROUTING -s 172.27.0.0/24 -d 172.16.0.0/24 -j SNAT --to 118.24.48.193
#iptables -t nat -A POSTROUTING -s 172.27.0.0/24 -d 172.16.0.0/24 -j RETURN
#iptables -t nat -A POSTROUTING -s 172.27.0.0/24 -o eth0 -j MASQUERADE

**最后说一下:**比较容易踩坑的是使用公有云,由于外网网卡并不是直接与内网实例关联的,说以需要其他的途径才可以实现,一般对应服务商都有解决方案,而且关于ipsec连接配置也跟这个有关,具体还需要看一下实际情况。

参考链接

openswan github ipsec vpn 唐霜的vpn教程 ucloud教程