Linux的NAT如何处理ICMP这类带外信息

清远鸡,不好吃。
        关于Linux的nf_conntrack的详细细节,我不再赘述,由于我之前写的文章几乎没有编排目录,我也只能通过谷歌baidu搜索几篇相关列如下,以后我也会注意自己文章的目录编排工作,不然自己都找不到了:
Linux的ip_conntrack半景
终于搞定Linux的NAT即时生效问题
Linux系统如何平滑生效NAT
我和ip_conntrack不得不说的一些事
......关于conntrack的资料不多,因此我写了很多,只是没有目录存档,可以直接baidu,google这方面的,类似OpenVPN中文资料一样去搜索。
        如果看明白了以上这些,我想在谈起nf_conntrack就可以畅所欲言了。同时如果真的懂了nf_conntrack,这篇文章也就不用看了。然而对于懂了nf_conntrack 70%的人群来讲,可能真的要看看本文。
        我假设你已经知道一个五元组信息是怎么在Linux系统中被conntrack的。接下来的问题是,如果一个五元组流被NAT,突然来了一个不属于这个五元组但是却控制该五元组流的数据包(典型的是它引发的ICMP),怎么可以顺利完成NAT?!
        也许你已经知道了FTP协议中会在应用层携带IP地址以及TCP端口信息,这个对于NAT来讲是一大挑战(详情请参看FTP helper代码,这个真没什么文档-当然除了我的),但是我在此不谈这个,我说的是更通用的,而且比这个简单!
        最简单的例子,请看下面的示例:
Source(1.1.1.1)--NAT(Masquerade 2.2.2.254)--Destination(2.2.2.2)
1.Source访问Distination的1234端口,经由NAT时其Source被转换成2.2.2.254;
2.NAT设备会记录一个conntrack项目:CONN1:[(original/1.1.1.1:123-2.2.2.2-1234),(reply/2.2.2.2:1234-2.2.2.254:123)]
2.Source访问Destination不存在的端口1234时,Distination会回复ICMP Port unreachable信息往Source返回;
3.ICMP信息到达NAT设备时,问题出现了,conntrack并没有发现任何ICMP信息与其关联,它怎么知道这个ICMP信息跟第2步中的CONN1相关呢??

????有解吗?
VMWare可能没解,它可能真的无解!但是对于Linux,作为一个通用平台,确实有解,它怎么做到的呢?因为人处在外地,时间有限,请自行完成实验并抓包以便深入理解这个事实!
        我直接给出答案!这个答案非常简单:
        Linux的Netfilter conntrack模块将每一个L4协议作为了一个对象,并且特殊对待了ICMP(它是TCP/IP的唯一控制协议嘛!),只要是收到了ICMP协议,就会解析它的详细内容。虽然,虽然从ICMP的IP协议头本身无法对应到已经创建的tuple,但是conntrack解析的不是ICMP的协议头,而是它的内容!
        在此,我不得不通告一个事实,那就是ICMP几乎总是会把“引起问题的原始数据包”作为ICMP的载荷附着在数据当中,以ICMP TTL exceeded为例,一个数据包将会是以下的结构:
src|dst|...[content:origIP数据报]
其中src是发出ICMP的设备的IP,dst一般就是原始数据包的发起方的IP,Linux的NAT逻辑解析的是content的内容,即引发这个ICMP消息的数据包,如果是一个TCP数据段由于TTL到期引发了ICMP,那么content就是这个TCP数据段本身。conntrack解析这个,就知道该怎么转换IP地址了。
        我已经乏力于贴代码了,这不是一个传道的好方法,同时也不宜于自己做备忘。有同事来问题问题,我只是告诉他:
“当你不知道一个逻辑怎么执行的时候,如果这个问题让你自己来做,假若它不是现成的东西让你来理解,而是产品经理要求你实现的一个功能,你会怎么办?你没有现成的东西,你只能自己想!哈哈,其实你也会自然而然想到这个跟Linux内核实现的一样的办法,从而表明这不是什么神奇的东西”。
        事实上,我真的就在2013年的时候没有参考conntrack的前提下实现了一个几乎一样的逻辑,这是人之常情。大家为什么总是纠结于现有的实现呢?
        现在总结一下:
问:Linux实现的NAT后面是否可以收到ICMP unreachable消息呢?
答:可以!因为在查找conntrack表之前就已经特殊处理了ICMP消息的内容从而创建了必要的conntrack项目。
问:Linux实现的NAT后面是否可以traceroute呢?
答:可以!因为traceroute依赖于ICMP TTL exceeded消息,而这个被conntrack特殊处理可以对应上引发这个的数据流从而完成转换。

我现在在最后提出一个问题:
请实现一个vmnat程序,替换VMWare中自带的vmnat,必须支持ICMP TTL exceeded的路由并让GuestOS里面的traceroute可以收到正确的信息,该怎么办??
        这个非常简单,你知道该怎么做了吗?如果不知道,请联系我:marywangran@126.com
        这篇文章,为我接下来的“链路拥塞以及队列整形”的探测不使用VMWare提供了理由,为什么不用VMWare,因为它的NAT不支持traceroute,而它的Bridge自配地址也过不了公司的验证,阻碍啊阻碍。以往之不鉴,来者可追!座椅爆炸...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值