历时两周,呕心沥血.
中间用了5天在解决为什么显示VPN建立了,但是ping的时候没有加密,而且子网直接与对方公网进行信息传输的问题。
最后终于在咨询老师后得以解决该问题~
在网上看到好多VPN配置方案,都没有遇到过博主这种问题,主要大家都没有讲VPN配置前需要做哪些网络配置。所以为了后面的大家不再遇到网络配置的这类坑,特地在这里写了一份超详细的傻瓜式教程,大家只要按照我写的一步一步执行,绝对没有问题哒~
切记不要跳过任何步骤哦,每一个步骤都是非常重要的!
- 配置虚拟机&虚拟网卡(这个不详述了,网上教程很多,方法也很多,大家配好网卡的时候要记得检查是否可以连上网,如果可以的话一般都配的没问题。然后也要记得查看下ifconfig,确保网卡和网关IP地址对应)
系统A 外网网关(ens192) IP地址:10.1.1.1,内网网关(ens160) IP地址:172.16.0.1
系统B 外网网关(ens192)IP地址:10.1.1.2,内网网关(ens160) IP地址:172.17.0.1
路由器路由地址 10.0.0.1
2. 配置路由表(重要)
删除内网网卡的路由配置(以系统B为例),如图:
删除路由命令:
$sudo route del -net 172.16.0.0/16 gw 0.0.0.0
下图所示两条路由配置必须保留,不然会影响IPSec连接和联网:
如果添加其他内网相关的静态路由,会提供一种非加密的路由传输方式,导致发送的报文未被加密。
(注:如果是ssh远程访问虚拟机,千万不要删掉第一条,不然会直接断开远程访问入口,导致无法访问虚拟机)
这个方法只是暂时性地修改了路由配置,只是方便实验时做修改,开机重启后还会还原到原来的路由配置,永久配置静态路由的方法(以A为例):
$sudo vim /etc/rc.local
在中括号前写入:
route del -net 172.16.0.0 netmask 255.255.0.0 gw 0.0.0.0
重启以后,就永久写入啦~
3. NAT地址转换(重要!),就是我开头说的那个问题的解决方案。
由于路由配置只能保证报文转发时可以顺利把报文转发到目的IP地址,而无法将转出报文的目的地址从内网IP修改外网IP,将会导致在报文传送过程中IPsec无法通过识别通信双方的IP地址识别需要加密的报文信息。所以NAT地址转换在这里非常重要。
请在操作前关闭ufw防火墙
A&B
$sudo ufw disable
先清空iptables原有规则:
A&B
$sudo iptables -F
$sudo iptables -t nat -F
下面是转换命令:
A
$sudo iptables -t nat -A POSTROUTING -s 172.16.0.0/16 -j SNAT --to-source 10.1.1.1
#发送报文时,将内网源IP地址修改为外网IP地址
$sudo iptables -t nat -A OUTPUT -d 172.17.0.0/16 -j DNAT –to-source 10.1.1.2
#发送报文时,将目的内网IP地址修改为对方的外网IP地址
B
$sudo iptables -t nat -A POSTROUTING -s 172.17.0.0/16 -j SNAT --to-source 10.1.1.2
#发送报文时,将内网源IP地址修改为外网IP地址
$sudo iptables -t nat -A OUTPUT -d 172.16.0.0/16 -j DNAT –to-source 10.1.1.1
#发送报文时,将目的内网IP地址修改为对方的外网IP地址
查看配置结果:
$sudo iptables -t nat -L -n #查看配置结果
这个方法也只是暂时性地修改了iptables的规则,永久配置iptables方法如下(在上面的命令执行完以后,该方法只针对Ubuntu系统):
A&B
$sudo chmod 777 /etc/iptables.rules #修改文件权限为可写入
$sudo iptables-save > /etc/iptables.rules #保存iptables设置
$sudo iptables-restore < /etc/iptables.rules #重新加载iptables.rules文件
4. 在网址为https://github.com/hwdsl2/setup-ipsec-vpn/blob/master/README-zh.md 的网站上下载ipsec VPN。
三种下载方式可选:
a. 使用脚本随机生成的 VPN 登录凭证 (完成后会在屏幕上显示):
$sudo wget https://git.io/vpnsetup -O vpnsetup.sh && sudo sh vpnsetup.sh
b. 编辑脚本并提供你自己的 VPN 登录凭证:
$sudo wget https://git.io/vpnsetup -O vpnsetup.sh
$nano -w vpnsetup.sh[替换为你自己的值: YOUR_IPSEC_PSK, YOUR_USERNAME 和 YOUR_PASSWORD]
$sudo sh vpnsetup.sh
c. 将你自己的 VPN 登录凭证定义为环境变量:
# 所有变量值必须用 '单引号' 括起来
# *不要* 在值中使用这些字符: \ " '
$sudo wget https://git.io/vpnsetup -O vpnsetup.sh && sudo \
$VPN_IPSEC_PSK='你的IPsec预共享密钥' \
$VPN_USER='你的VPN用户名' \
$VPN_PASSWORD='你的VPN密码' sh vpnsetup.sh
5. 配置 ipsec.conf 文件
A
$sudo vim /etc/ipsec.conf
version 2.0 #这一行请大家不要删掉
config setup
protostack=netkey
interfaces=%defaultroute #IPsec使用的虚接口和实接口
uniqueids=no
conn host-host #pc==网关---网关==pc
left=10.1.1.1 #本机网关IP地址
right=10.1.1.2 #目的主机网关IP地址
authby=secret #认证方式:secret(共享密钥)
auto=add #自动执行ipsec auto --add
conn net-net #pc==内网==外网网关---外网网关==内网==pc
left=10.1.1.1 #本机外网网关IP地址
leftsubnet=172.16.0.0/16 #本机内网网段地址
right=10.1.1.2 #目的主机外网网关IP地址
rightsubnet=172.17.0.0/16 #目的主机内网网段IP地址
autby=secret #认证方式:secret(共享密钥)
auto=add #自动执行 ipsec auto –add
B
$sudo vim /etc/ipsec.conf
config setup
protostack=netkey
interfaces=%defaultroute #IPsec使用的虚接口和实接口
uniqueids=no
conn host-host #pc==网关---网关==pc
left=10.1.1.2 #本机网关IP地址
right=10.1.1.1 #目的主机网关IP地址
authby=secret #认证方式:secret(共享密钥)
auto=add #自动执行ipsec auto --add
conn net-net #pc==内网==外网网关---外网网关==内网==pc
left=10.1.1.2 #本机外网网关IP地址
leftsubnet=172.17.0.0/16 #本机内网网段地址
right=10.1.1.1 #目的主机外网网关IP地址
rightsubnet=172.16.0.0/16 #目的主机内网网段IP地址
autby=secret #认证方式:secret(共享密钥)
auto=add #自动执行 ipsec auto –add
6. 配置ipsec.secrets文件
注:要求PSK设置在16比特以上(因为默认调用sha256函数,要求加密密钥在16比特以上)
A&B
$sudo vim /etc/ipsec.secrets
%any %any : PSK “12345678901234567890”(密码只要A、B相同即可, 冒号后面一定要打空格)
7. 启动ipsec VPN
A&B
$sudo ipsec restart
$sudo ipsec aut –add host-host #添加host-host连接模式
$sudo ipsec auto --up host-host #选择一种连接模式,启动它
配置成功:
A
B
8. 检查ipsec是否启动成功
A/B
$sudo setkey -D #查看SAD条目
$sudo ipsec status #查看ipsec状态
$sudo ipsec verify #查看ipsec运行状态
9. 使用tcpdump&&wireshark抓包
A
$ping 172.17.0.1
B
$tcpdump -nvvs 256 -i ens192 host 10.1.1.1
-n 不把网络地址转换成名字
-vv 使tcpdump输出详细的报文信息
-s 指定报文的大小
-i 指定捕获VPN网关数据包所经过的物理网卡
截获如下报文信息,证明VPN配置成功:
当我们在启动ipsec某一模式,比如host-host的同时,使用wireshark截包,会截获本次ipsec通讯所使用的加密算法、hash函数等:
10. 遇到问题
- 验证阶段,ping对方主机时,显示传输中的ICMP报文未被加密:
未进行NAT地址转换,导致目的地址为内网地址,而非外网地址,导致IPsec无法识别而无法对报文进行加密。
解决方案详见教程步骤2.
- ip冲突:
在实验过程中,我发现主机A的内网网关IP存在IP冲突,导致B可以直接ping通A。
可用如下命令(暂时)修改IP地址:
$sudo ifconfig ens160 172.18.0.1 netmask 255.255.0.0
- net-net中配置了子网以后反而无法截获到加密数据包:
当我打开连接net-net时,我发现在我通过A的内网ping B的内网时,我所截获的10.1.1.1与10.1.1.2之间是未加密的。
而我启动host-host时,发现10.1.1.1和10.1.1.2之间传送的报文反而是加密的。而两者之间只是相差了子网的设置。
经检查,发现我原来配置的路由表中画红线的这条会导致内网IP直接与对端内网IP地址(相当于我提供了一条不用加密的路径吧),所以需要把这条删去。
其实完全可以把其它的三条删去,只留下第一条保持系统可以连上路由器的网关就行。