基于linux系统(Ubuntu)的IPSec VPN隧道搭建实验——包括路由配置和NAT转发设置教程,超完整!!!

历时两周,呕心沥血.

中间用了5天在解决为什么显示VPN建立了,但是ping的时候没有加密,而且子网直接与对方公网进行信息传输的问题。

最后终于在咨询老师后得以解决该问题~

在网上看到好多VPN配置方案,都没有遇到过博主这种问题,主要大家都没有讲VPN配置前需要做哪些网络配置。所以为了后面的大家不再遇到网络配置的这类坑,特地在这里写了一份超详细的傻瓜式教程,大家只要按照我写的一步一步执行,绝对没有问题哒~  

切记不要跳过任何步骤哦,每一个步骤都是非常重要的!

 

  1. 配置虚拟机&虚拟网卡(这个不详述了,网上教程很多,方法也很多,大家配好网卡的时候要记得检查是否可以连上网,如果可以的话一般都配的没问题。然后也要记得查看下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

下面是转换命令:

$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地址

$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 文件

$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

 

$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地址(相当于我提供了一条不用加密的路径吧),所以需要把这条删去。

   其实完全可以把其它的三条删去,只留下第一条保持系统可以连上路由器的网关就行。

 

如有疑问,欢迎留言~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章