回味了一下相关NAT的知识,发现还是这篇关于NAT的文章,讲解最为人性,精辟,通俗易懂!

现在进入正文

nat翻译成中文就是网络地址转换,顾名思义也就是把一个IP地址转换成另一个IP地址,有人问为什么转换,我们就来看看。

数据包中的IP头部包含源IP地址,也就是发出这个包的源节点的IP地址,和目的IP地址,也就是这个包最终会被谁收到。

举个例子,有一伙犯罪团伙,有三名成员,毒蛇,老虎,老狼,为了作案方便,他们都办了×××,毒蛇成了毛虫,老虎成了小白,老狼则办了一张绵羊的×××。他们在窝点内部,直接用各自的真名来通话,作案的时候,他们对其他人来说,就是毛虫,小白和绵羊,别人称呼他们也是这三个名字。

实际中,如果想隐藏自己的真实身份,那么可以人为的把源IP地址改成一个其他的IP地址,对方接受到之后,以为消息就是从这个IP发了的,那么他回应的时候也使用这个地址作为回应消息的目的地址。目的地址处的nat设备,一旦收到这个消息,就把消息中的目的地址替换成发信人的真实ip地址,然后转交给发信人。

nat的出现其实最初是为了解决IP地址不够用的问题的,我们知道,IP地址中有一类私有地址,也就是大家谁都可以用的地址,就类似比如冬冬,娜娜这种名字,大家谁都可以用,但是你如果去办×××,就不会让你用这个名字。IP地址就2的32次方那么多个,如果再有多余的节点要分配地址,就不够用了。那么就提出用nat类解决。也就是,如果犯罪团伙中有10名匪徒,但是匪头只成功地办了5张×××,那么每次只能有5个人拿着×××出去作案。剩下5个人只能在窝里呆着。如果剩下的5个人想作案,那么只能等到出去的5个人回来交班。一旦有外界要和匪帮联系,统统用假名字,匪头根据×××假名字和真名字的对应,然后点匪(点名),让对应的匪徒出去和外界交涉。但是有一天匪头一想,这样太浪费了,得找个机制,让所有人都出动,他冥思苦想之后,出来一种办法:让多个人都用同一个×××,但是给他们再区分一下,比如绵羊:80和绵羊:8000就不是一个人,找绵羊80的,匪头就告诉A匪,找绵羊8000的,匪头就告诉B匪。这样,终于全部出动了。这样匪头就可以只用一个×××,让全体成员出动,呵呵。

咱们还是别在这匪徒作案了,一会警察来抓我了呵呵。我们回到现实。目前企业申请一个IP,需要付钱给网通电信这样的垄断霸王,因为负担不起给企业中每个办公室的每台pc都配一个公网IP,也就是internet上每个人都能找到你的IP,通常企业都只申请一个IP,就像刚才说的,那么企业内部如果有多个人想和外界联系,他们用的源IP地址怎么办,那么刚才说过,大家都用这个IP做源IP地址,是个集体户,那么刚才也说了,得有个区分机制,不能集体了就全部集体,那么用什么来做这个区分符号呢?冥思苦想,是否可以更改IP头部结构,就像vlan id一样,加入一个东西来区分?可以,但是全世界所有机器上运行的IP协议程序都要改,不行。对了,tcp不是有端口号的么?而且和外界联系的时候,除了IP这一层,一定有一个传输层内容,比如tcp或者udp,而他们都有个端口号,也就是说除了源和目的IP地址,还要有源和目的tcp/udp端口号,我们就用这个已经存在在数据包中的端口号为第二区分符。

nat一共有4种具体实现,刚才说的那种,10个人,5个×××,5个人干活,5个人永远呆在窝里处理内务那种,叫做静态nat,也就是一个对一个,如果有100个×××,10个匪徒,那么这个匪头比较历害,10个匪徒都能出去作案。 第二种情况,也是刚才那种情况,10个人,5个×××,但是大家都可以用,谁先抢来,谁就拿着出去作案,回来之后放到桌子上,没轮到的再去抢,抢着了就出去,抢不着还呆着,这样也就是同时只能有5名匪徒出去作案,但是全局意义上,每个匪徒都有机会出去。这叫做动态nat。第三种,10个匪徒,1个×××,大家都用这一个×××,但是可以同时出去作案,因为他们还有二级区分符:端口号。这种叫做PAT,端口地址转换,或者复用的nat转换。第四种,动态nat+PAT,也就是10个人,5个×××,其中前4张×××用动态nat,大家来抢,谁先抢着是谁的,但是剩下一张,就给没抢到的用pat方式共享,当然效果没有一对一来的爽了。

我们来看看具体实现机制。

看ppt:一个路由器,两个接口,一个接外网,也就是isp接过来的,一个接内网,也就是和内网交换机连接。比如我现在就是内网的10。1。1。1这台机器,我现在打算访问www.sina.com.cn,大家说第一步是做什么?对,是先进行dns解析,由于我机器上配置的dns,比如是202。102。134。68,我的机器判断,这个dns服务器地址和本机地址不同在一个IP子网,那么他准备先把这个包发给网关,然后让网关来转发到这个dns服务器上,所以我的机器会先发arp请求我设置的网关10。1。1。254的mac地址,请求到之后,机器立即组包,包的目的ip就是dns服务器的地址202。102。134。68,源地址就是本机IP地址:10。1。1。1,有了这个还不够,IP只是定义了发信人和收信人的目的地,但是数据包到达之后提交给哪个上层应用来处理,必须利用tcp或者udp层的端口号来区别,所以IP头部之上,我机器附加了一层udp层,因为dns查询数据包标准情况下使用udp来传输,比如我随即选了一个我的源端口号,udp5555,那么目的端口号,必须设定为dns标准端口,也就是说对方一收到这个数据包就知道这个包是给dns程序使用的,需要提交给dns程序进行处理,所以目的udp端口设定为:udp53,就是53号端口是dns程序的,传输层头结束之后就是上三层的内容了,属于应用特定的内容,随应用不同而不同,我们就不必深究了。包组好了,下一步就是通过交换机发给网关了,这个步骤交换机会做,我们也不管。话说网关收到之后,提交给路由器中的程序进行处理,如果此时,路由器上没有配置nat,那么路由器直接查找路由表,发现这个地址应该从连接isp的接口发送出去,做转发处理,路由转发前面的课程已经说过,大家应该知道,如果包被直接转发出去,那么包将携带这10。1。1。1的源IP地址而出去。然后isp根据包的目的IP地址来路由该包,最终这个dns查询包会被正确传送到dns服务器。然后服务器应答的时候,以10。1。1。1作为目的IP地址,同样的过程,包发给dns服务器上配置的网关,此时问题发生了,那个网关是不会知道10。1。1。1这个地址怎么走的,因为10网段的地址被internet地址分配机构定义为私用地址,就像要去广播电台寻人启事,我用要找的人的小名可以么?当然不行!一个道理!比如现寻找名为冬冬的小朋友,这样电台虽然可以这样广播,但是电台会么?不会,电台必须让你说出大名,也就是×××上的名字。所以以目的地址10。1。1。1的包,是进制被传送到internet上做路由的,因为大家都不会用这个地址暴露在internet上,你就算路由出去,又有什么用?没用!我说一个有趣的例子,我曾经用adsl拨号上网的时候,获得的地址和网关都是公网地址,但是我ping 192。168。1。3,竟然通了,所以说不要人为私有地址是不可internet路由的,这个理解是错误,正确说法是一般情况下禁止在internet上路由私有地址(mpls之类的特殊技术可以路由私有地址),刚才那个例子,就是典型的isp路由器上配置没有过滤掉这些私有地址造成的,过了一段时间之后,再ping就不通了。

好拉回话题来,刚才说了,私有地址禁止在公网出现,那么10。1。1。1最终怎么查询到dns的?答案就是nat。我们看看配置了nat的路由器怎么处理这个包。10。1。1。1发出的dns查询包被路由器收到之后,路由器首先检查nat配置,这里我们用静态nat为例。静态nat需要手动提前配置好,比如我们这里配置成:211。64。208。2-----10。1。1。1,入端口为内网口,出端口为外网口,注意,端口很重要,nat必须依托于端口!也就是说,路由器收到包之后先根据目的IP做路由查找,找出这个包将要发送到哪个端口,如果那个端口上配置有nat,那么这个包还必须经过nat处理,nat处理的时候,路由器会查看源IP而不是目的IP,由于我们配置了211。64。208。2-----10。1。1。1,所以路由器一看源IP地址是10。1。1。1,就把10。1。1。1替换成211。64。208。2,然后通过那个端口转发出去,那么经过nat转换的包,源地址变成了211。64。208。2,这样dns回应的时候用这个地址作为目的IP地址,就可以被发送到本地路由器接收了。接受到的包,和发送包时候顺序恰好相反,路由器一看该端口上配置有nat,那么对接受到的包,现作nat检查,因为211。64。208。2-----10。1。1。1,所以他把包的目的(注意,不是源)地址逆向替换,也就是将211。64。208。2替换成10。1。1。1,然后再做路由查找,找到出接口,也就是内网接口,然后发送给10。1。1。1,结束。

以上讲了静态nat,动态nat和静态差不多,就是谁先谁用的原则。

下面讲讲pat,也就是利用传输层端口来区分同IP地址的不同数据流。

同样是上面的例子,如果此时我只买了一个公网地址,也就是211。64。208。1,那么只能大家公用了。我们来看看流程。同样,10。1。1。1这个节点发出dns查询包,源地址10。1。1。1,目的地址为dns服务器地址202。102。134。68,然后目的端口号udp53,源端口号udp5555。我们知道,路由器,一般情况下,他是不关心IP层之上的内容的,就像刚才静态nat的例子,没有涉及到传输层的内容,但是在pat中,必须检查。接着说,路由器收到这个包之后,首先根据目的IP做路由查找,找到将要发送出去的出口,为外网口,然后因为做了pat在内网口和外网口之间,那么路由器就要将这个包pat一下,具体动作是:将源IP10。1。1。1替换成211。64。208。1,然后再将源端口号,如果这个端口号已经被其他人占用,那么就替换成随即选择的,如果还没有被占用,那么保持不变,看ppt中的图示。大家可以看到10。1。1。2已经占用了211。64。208。1的8790端口,那么虽然10。1。1。1发出包的源端口是8790,但是路由器收到之后,就不能用8790,得随即选择一个,这里他选择了211。64。208。1:8000端口,然后将这个事件记录到pat表中。经过这样处理的包,最终被发送出去,在isp中路由,最终路由到目的:dns服务器,然后dns服务器回应包,利用211。64。208。1作为目的IP,源IP还是dns服务器地址,目的端口,就是收到包时候的端口号:udp8000,原端口,就是udp53。然后这个回应包被本地路由器收到,他一看是从配置了pat的接口上进来的,那么他先反pat处理,参照pat表,将目的IP变为10。1。1。1,然后目的端口变为8790,然后做路由查找,找到10。1。1。1对应的出接口,也就是内网接口,然后发送给10。1。1。1,结束。

至此,nat和pat讲完了,至于动态nat+pat,完全是程序做了一些修改而已,原理刚才也说了,具体过程就不多讲述了。

最后强调一点:nat不仅仅可以私有地址到公网地址的转换,任何两个IP之间都可以转换,什么地址都行。不要形成思维定势。