一、背景
在ipsec VPN的验证过程中发现公网网口会有内网数据数据包的现象,需要进一步分析为什么内网数据包会在公网网口。
二、验证网络拓扑和数据分析
1、网络拓扑如下,并部署对应的ipsec vpn (strongswan)

VM1上VPN策略为:

2、从VM1的NS中ping VM2的NS,模拟两个内网通过ipsec vpn互通

1)此时在VM1和VM2的eth1公网网口抓包发现,数据包除了公网的ESP报文外,也有以解封装的内网报文,且内网报文都是收方向的报文
VM1的eth1抓包:

VM2的eth1抓包:

理论上公网接口应该只有ESP的公网报文才对,不应该有内网报文,进一步查看netfilter的日志看看怎么回事
2)Netfilter的日志
VM1的netfilter日志:

VM2的netfilter日志:

通过netfilter日志分析发现,ESP公网数据包在经过PREROUTING和INPUT链之后,数据包解封装,之后的原始内网数据包确实又经过了PREROUTING和FORWARD进行转发,难道这个ESP数据包在解包后又回到了公网网卡,理论上不应该,要进一步查看ipsec VPN的原理和机制。
三、IPsec VPN的网络原理分析
1、IPSEC 和 XFRM
IPsec协议帮助IP层建立安全可信的数据包传输通道。当前已经有了如StrongSwan、OpenSwan等比较成熟的解决方案,而它们都使用了Linux内核中的XFRM框架进行报文接收发送。
由此可见IPSEC实现的基础是内核的XFRM,XFRM框架接受IPSEC报文的流程如下:

从整体上看,IPsec报文的接收是一个迂回的过程,IP层接收时,根据报文的protocol字段,如果它是IPsec类型(AH、ESP),则会进入XFRM框架进行接收,在此过程里,比较重要的过程是xfrm_state 1ookup(),该函数查找SA,如果找到之后,再根据不同的协议和模式进入不同的处理过程,最终,将原始报文的信息获取出来,重入ip_local_deliver().然后,还需经历XFRM Policy的过滤,最后再上送到应用层。
这里的流程是ESP报文在解包后送到应用层的过程,而该示例中的数据包是需要进一步转发,需要看看XFRM和Netfilter有什么关联性。
2、XFRM和Netfilter

从Netfilter的框架图中可以看到ESP数据包在经过INPUT链后,会进行decode的解包,此时解包之后会clone原始数据包发送到接收网卡,这里是公网网卡,从而把原始数据包再一次经过netfilter并做路由,因此可以看到公网收方向不仅有ESP的公网报文也有原始内网报文。
实际从图中看到XFRM的decode之后有两条路线,一条是直接到netfilter,一条是clone到网卡,因为tcpdump抓包是在网卡数据包进入netfilter之前,而抓包又抓到了原始内网报文,因此应该走的是clone到网卡的路线。