当客户端发出请求时,到达目标服务器主机,在此之前,它要先经由网关向外发送,如果不经由网关的话是没有用的。这个网关在这里我们通常把它称为叫NAT Server,但事实上,它并不是监听在任何一个套接字上提供某个Service的这么一个Server,它只是一个在内核空间能够根据用户请求与我们自己所添加的规则把用户请求报文的源地址或目标地址修改为另外一个地址的内核中的规则而已。当然我们通常把它称为NAT Server,因为它的确实现了地址转化这么一个功能。
对于我们的防火墙来讲,假设能够让CIP作为网关的IP地址称为GIP(Gateway IP),而它能够与外部主机通信的假设称为FIP,此处只是随便取个名,不然GIP就没法叫了。
于是正常情况下,如果我们这台主机的是一个路由器设备的话,当CIP的请求送达时,如果CIP请求的报文的目标是SIP,那请求报文到达我们的路由设备时,其源地址为CIP,目标地址为SIP。我们的路由器收到以后,查看核心转发为允许又发现自己是能够找到SIP的,也有可能自己是通过默认网关也可能这是自己直连的一个网络,我们不用考虑这么多,反正这个报文转出来了。在这个过程当中,它转发出来后源地址是CIP,目标地址依然是SIP。大家发现,这种我们称为路由,因为我们没有去改动请求报文的IP首部中的任何信息,这种我们称为路由功能,我们仅仅是根据对方所请求的目标地址给它做转发而已。
那什么样才叫nat呢?当客户端发出请求时送给了Server,那一样的道理,报文刚刚到达此处时,其源地址时CIP,目标地址是SIP。但是由于这里是一个NAT Server,并且Nat Server发现这个请求者刚好在本地能有某一规则所匹配到我们需要修改源地址,因此,这个报文被NAT Server扔上网络后,其源地址转换成了NAT Server上用于与外部主机通信专门定义好的说明的要转换为的地址,即FIP,目标地址为SIP。所以像这种就叫做SNAT,即源地址转换,修改了请求报文中的源地址。
而各位想象一下,当其响应报文做回送的时候,考虑一下,源地址是SIP,目标地址是FIP,因为在SIP看来请求者是FIP,问题是FIP并没有任何进程基于客户端访问SIP,那怎么办呢?再转换,转换是目标地址,因为此时目标地址是FIP,源地址是SIP,那这个时候我们FIP并没有访问SIP,真正访问的是CIP,那因此我们的NAT Server收到以后是不能够将这个报文接下来由自己的内部的进程来处理的,因为自己也没有任何进程在处理这个报文,于是它要将其转换回源地址依然是SIP不变,但目标地址是CIP,这是响应报文,大家发现响应报文改的是目标地址,所以我们说任何一个源地址转换都必然对应着一个目标地址转换,只不过我们所谓的源地址转换主要指的是请求报文转的是什么地址,而响应地址的转换是由NAT Server自行来实现。但NAT Server怎么知道谁请求了谁啊?假如说我们内网有n个客户端,当SIP响应报文进来,我们的NAT Server怎么知道我们要将其转换为哪一个内网主机呢?因此我们必须得追踪此前的每一个请求,要知道到底是哪一个请求跟我们彼此之间产生了关联。所以其内部必须有一张NAT表,你也可以想象成这是一个连接追踪模板,只不过它是NAT的追踪模板,里面明确记录了哪一个客户端向哪一个Server发送了什么请求报文,而且更重要的是,我们还加了一个标记号码,什么意思呢?大家知道现在的网络为了能够加速,它通常一次可能会发出去多个请求报文,我们响应报文如果先先后后到达了,我们应该要知道到底哪个报文是先哪个报文是后的,那有可能还需要加上报文发送次序的。
因此,需要一个NAT表,那也就意味着,只要我们的NAT Server能够实现NAT功能,一方面它要有完全地址转换定义转换为什么地址,其次,它还得有一个连接追踪表,用于实现当响应报文到达时,我们通过查表知道之前哪一个客户端主机发出了请求,我们还需要将其目标地址修改为那个请求发出者的地址。这就是NAT。
不过,NAT技术很多时候比我们想象的要复杂很多,我们此处没必要了解这些东西的,将来要用到复杂场景中的NAT,再去了解也为时不晚。这些基础知识是我们简单去了解NAT工作模式的一个根本的东西,那由此应该明白什么叫做能代理内网主机上网了。很显然,内网主机都有一个私网地址,它们的网关都指向了GIP,那FIP假如是一个公网地址,所有的内网主机访问互联网或非本地网络时,我们都把它们的请求报文的源地址改为FIP,因此互联网上的任何一个主机收到报文响应的时候响应给FIP了,而FIP是一个公网地址,是能够被路由到目标到达的,只不过FIP收到后发现自己并没有请求,那于是它得改回某一个CIP即可。那这样有什么好处呢?我们说过,NAT最初设计的主要目标是为了网络安全性,能够想明白的是我们把内网中的所有主机在互联网上都隐藏起来了,为什么要隐藏起来呢?因为是私有地址,我们私有地址在互联网上是不可以被当做目标地址使用的,所以任何一个请求送给这个私有地址,我们让所有的内网客户端全送到私有地址来,谁可以在互联网上直接访问它?那我们可以访问FIP吗?FIP不是私网中内网主机的地址,如果不是内网主机自己发送请求我们给出响应,也就是说NAT表中并没有这么一个连接追踪到的条目的话,任何一个请求到达时,我们是不可能随意向内网中的CIP进行转发的。所以就达到了隐藏内网主机的目的。早期是为了安全性,但是“无心插柳柳成荫”,虽然早期是为了安全,但是今天由于IPv4地址耗尽了,所以带来的结果是反而是现在能让更多的内网主机访问互联网了,用于这样一个目的,所以我们说,这不是它设计的原生目的,但的的确确解决了我们现在所面临的地址短缺、地址紧俏的这么一种情况,的确在一定程度上解决了我们很大的问题 。这是SNAT。