对于每一个数据包,都要用源IP地址去查询SNAT表,用目标IP地址去查询DNAT表。然而对于Linux而言,需要的仅仅是查询conntrack结构,然后取出第一个包查询时记录于此的nat结果。 1.静态NAT
静态NAT就是一个一对一的NAT映射,也就是一个Local IP地址和一个Global IP地址之间的转换。在配置生效的时候,NAT转换规则就会被添加到NAT表中。 1.1.Cisco方式
当在inside方向上添加了一条NAT: ip nat inside source static a b
系统会将a->b的源地址转换加入到inside的SNAT表中,同时将b->a的目标地址转换加入到outside的DNAT表中。
针对后面的所有数据包,不管是从内部发起的,还是从外部发起的,都会根据接口使能的是inside nat还是outside nat来查表匹配。 1.2.Linux方式
Linux基于conntrack,因此即使你使用 iptables -t nat -A POSTROUTING -s a -j SNAT --to-source b
也只针对匹配该策略的第一个数据包,Linux的NAT的转换一方a是作为一个match出现的,因此它严格匹配第一个包的源地址,故反方向的数据包不会匹配,因此Linux的NAT都是单向的。 2.动态NAT
动态NAT不在配置的时候规定转换后的地址,而在第一个有转换需求(由ACL来判断)的数据包到来的时候才确定它要转换成什么地址。因此,配置生效的时候,没有任何NAT规则会被加入到NAT表中。 2.1.Cisco方式
当在inside方向添加了一条动态NAT: ip nat pool NAME ...
ip nat inside source list $acl pool NAME
...
系统不会添加任何NAT规则,只有当某一个包匹配到了acl,要引发NAT的时候,系统会动态(基于pool类型来计算)从pool中选一个要转换成的IP地址,将其添加入inside的SNAT表中,同时针对反方向的目标地址转换规则生成并加入outside的DNAT表中。
因此,Cisco动态的NAT是单向的,因此反向的数据包进入时不会匹配到acl,不会引发NAT规则的生成,也就不会匹配到任何NAT规则。 2.2.Linux方式
再次重申,Linux的nat中,待转换的IP地址是一个match,因此不管是一对一的转换还是一对多的转换,原理都是一样的。Linux并不区分静态转换和动态转换。在内核中,永远都不会出现所谓的NAT映射表,iptables添加的NAT规则不会生成映射,数据包进入匹配nat成功,也不会生成映射,nat结果仅仅存在于conntrack中作为tuple的一部分体现。 3.查询方式
可见,不管方向,不管路由,只要数据包进入了一块带有ip nat enable配置的物理网卡,就会进行NAT匹配以及匹配成功后的操作,不管是SNAT和DNAT都在这里进行。这个实现虽然很豪放,但是却解决了所有问题,平衡点的问题不存在了,数据包在进入真正的路由查询前,NAT就已经完成了,在路由器看来,NAT操作被藏起来了,就好像数据包本来就是那个样子一样。
当然Domainless的NAT也不再和任何其它操作关联,ACL,VPN感兴趣流匹配,policy routing等都和NAT无关。Cisco Domainless的NAT设计和Linux的NAT设备区别更加明显,虽然Linux的NAT也是Domainless的,但是在设计上却和Cisco基于Domain的NAT很像,因为二者的NAT都要和其它的Filter操作联动,对于Linux,NAT行为需要和大量的Netfilter行为联动。 四.总结和想法
通过使用Cisco的NAT,我有一些自己的想法,需要暂时记录下来。 1.和微软的关系,和自由的关系
我配置Cisco的时候,有种使用微软系统的感觉。遇到瓶颈的时候,束手无策!在微软的系统上,我想做单臂NAT,我想配置路由的时候带上source,折腾了好久都未果,配置Cisco的时候,同样的感觉!虽然有时候,高一点的IOS版本确实能解决问题(这是和微软一样的)。总的来讲,使用这些东西让你感觉不自由,能HACK的地方实在太少,HACK操作门槛太高,使用它们时,你要一直提心吊胆,你要么一气呵成,只要是碰到了拦路虎,哪怕多么小的拦路虎,你可能都过不去。
Linux正好是事情的另一面,UNIX处在中间。在Linux上操作,你的任何行为都不会受到阻碍,即使碰到了问题,系统不会阻碍你去编写一个程序或者内核模块,甚至重新订制内核。即使不这么深入,光看一下iproute2以及iptables就够了,本身自带的参数就能让你完成几乎所有的操作,在这个意义上,习惯了Linux的人可能也会苛求Cisco的扩展访问控制列表更加优秀一些,实际上,面对Netfilter的几乎无限的扩展能力,Cisco的扩展访问控制列表的“扩展”体现在哪里呢??
我买手机不是来hack的,我也不写代码安装在手机上,我仅仅是想用它来打电话,发信息,上网,所以我不买Android,由于价值观相差甚远,我不买和微软有任何关联的手机,不管它有多好,买了iOS是因为它和UNIX有关联,事实上,苹果很封闭,但是它的封闭不是技术本身,而是价值取向和设计,事实上,也正是因为它封闭的不是技术,才有了越狱之说,越狱之后,你将面对一个原汁原味的开放的UNIX。开放是金,开放就是一切。 2.功能性技术点和解决方案
如果碰到问题,当然要想办法去解决问题了,此时就有两条路,第一条路就是寻找单独解决该问题的功能性技术点,比如你想在做一个基于ACL的地址映射,如果你用的是Linux BOX,那么这个功能性技术点就是iptables,但是如果你用的是Cisco低端路由器,那么就无法做这件事,文档明确说不支持。此时就是第二条路了,那就是彻底否定最初的方案,说一句:“为何要这么做呢?XX会更好的。我们有整套的解决方案,满足你的所有需求。”。一般的像Cisco,微软,IBM都会提供解决方案,它们的系统上的功能性技术点往往都有短板,单独拿来用很鸡肋,只有和其它的配合才可以。因此,想hack的,千万别基于这些系统,你会烦死的,在这些系统上,这也不行,那也不行,这个不能变通,那个不能变通,用多了,人也就死板了,说话也就不好听了,“技术上的任何问题都是可以解决的”这句话到了使用这些封闭系统的人那里就成了“这是不可能的!!!” 3.人员冲突
一周以来,我跟人冲突好几次,完事后还是证明我的想法是正确的,所以再次让我感到大多数所谓的高级网管员的水平是多么的垃圾,水平垃圾个性还一个个都挺狂妄,这实在让人气愤和悲哀。这些垃圾人员的观点基本分为两类: 1>没有做过的事情就说不可能
因为以前从来没有这么做过,就说不可能,甚至否定我的技术方案。我是作为研发出现的,这就更让对方觉得我根本就不懂网络,没有经验等,第一他们没做过,第二我没网络方面的职称,这就更让他们狂妄无比。 2>想当然的事情就拍脑袋说可以,实际上根本就不可以
我说要把udp服务一对一双向映射出去:
ip nat inside source udp 1.1.1.1 12345 2.2.2.2 12345
在测试的时候,他们非要用ping来测试!这个明明是一个udp的映射,怎么用ping?!然而他们非要用ping,我告诉他们不能做全映射,因为会把不相干的不该转换的地址也转换了,因为他们知道NAT可以通过ACL+pool来做,所以他们就认为这个可以在outside口用ACL匹配地址来做...这帮傻逼!我要做目标地址转换,还得是双向的,也就是说不管数据流从那边发起都是可以的!那帮人连NAT转换项什么时候安装进系统的都不知道!
这些人还好意思说自己是网络工程师啊!看看我们的那些NA/NP/IE/NE/SE们,无一例外的就是靠背题的,好多证书都拿到手了,却连网络的基本原理都TMD不懂!再看看那些真正的CCIE,比如Petr Lapukhov, 4xCCIE/CCDE in CCIE R&S,IP Services: Petr Lapukhov's career in IT begain in 1988 with a focus on computer programming, and progressed into networking with his first exposure to Novell NetWare in 1991. Initially involved with Kazan State University's campus network support and UNIX system administration, he went through the path of becoming a networking consultant, taking part in many network deployment projects. Petr currently has over 12 years of experience working in the Cisco networking field, and is the only person in the world to have obtained four CCIEs in under two years, passing each on his first attempt. Petr is an exceptional case in that he has been working with all of the technologies covered in his four CCIE tracks (R&S, Security, SP, and Voice) on a daily basis for many years. When not actively teaching classes, developing self-paced products, studying for the CCDE Practical & the CCIE Storage Lab Exam, and completing his PhD in Applied Mathematics.
看看人家的经历,从编程开始,逐步深入,从计算机体系结构,TCP/IP栈,到UNIX,最终,Cisco只是大师将这一切附着的一个平台而已,如果他不是在Cisco上工作,而是加入IBM的阵营,或者去开发Linux内核,你能说人家不是圈子里的人吗?记住,别把编程的人看作不懂网络的。