iptables之五iptables之nat
一、NAT引入
我们此前说过,把iptables扮演成为网络防火墙也无非就是找一台iptables启用起来的服务器主机,它一定是位于我们的本地网络所有数据报文与非本地网络主机之间进行通信时必经的网络接口上或者叫网络上。
因此对于内网主机来讲,都要把这个主机的内网接口当做网关,而这个主机它有一个外网接口能够与互联网上(或外部网络)的其它主机通信。
我们知道,一旦我们把这台主机上的核心转发功能打开,它其实就扮演一个路由器或网关设备的角色。但这个路由设备有一个不好或不完善的地方在于它没有路由表它的默认路由表只有根本的几个,就是它自己本地的直连网络,即每一个网络接口所在的网络它可以到达。所以如果说本地内网的一台主机与另外一个网络中的主机通信时,如果是非本地网络的就要将报文发送给路由器了,路由器只能够知道如果对方请求的目标地址是另外一个接口所连接的另外一个主机的话是没有任何问题的。但是如果说路由器也不知道那个接口在哪就只能经过默认路由向外转发就可以了。但现在有一个问题,它通过默认路由转发出去了,假如说这个主机它所拥有的是一个互联网上的公网地址,对于这个内网中的来讲,想象一个基本问题,如果说互联网上有一个基本主机,比如test域的Web服务器(www.test.com)收到这个请求报文了,那接下来就应该予以响应了。
它收到这个请求报文后,这个请求报文的源地址应该是内网中的客户端IP,而它请求的目标地址是这个外网服务器的地址,假如称为SIP(Server IP),而源地址是CIP。很显然,当这个客户端发出请求走到路由器的时候,请求报文源地址是CIP,目标地址是SIP。路由器收到之后发现打开了核心转发,于是查找本地的默认路由的路由表,它也能转发出去,如果没有默认路由路由表就转发不出去了。如果有默认路由路由表,于是它有可能也会交给下一跳等等转发,中间可能经过n个路由设备,最终送达到了这台服务器,服务器一看目标地址是自己,于是接收下来请求、处理请求、构建响应报文。在它响应时,源地址成了目标地址,目标地址成了源地址了,所以此时源地址是SIP,目标地址是CIP,CIP如果是一个私有地址的话,而私网地址是不可能在互联网上被路由的,互联网上的任何一个路由器的路由表都不会添加私网地址的,也就意味着如果说本地主机的一个通信目标是一个私有地址段中的地址,那结果是它只在本地中找私有地址网段,而不会通过互联网的公网路由器发送的或者说公网上的路由器压根就识别不了这样的网络,即便识别这样的网络它也只认为这是本地的。
因此,这个报文无路如何能送给通过公网连接起来的这台主机吗?显然是不可能的,那接下来会带来什么结果呢?请求报文能送出但响应报文回不来,并不是服务器端不响应,服务器端只要有源地址都会响应的,但是响应时由于目标地址是一个私网地址,我们公网上的路由器设备是不会对私网地址在互联网上进行路由的,所以你的响应报文将无法通过公网路由会送到客户端地址。
如上图,我们可以想象成左边为一个本地网络,右边作为公网服务器来讲,它也有可能是一个局域网络。我们说过,互联网就是把各个局域网络连接起来的一个大网络而已,是一个连接各局域网的网络,所以我们把它叫做局域网的互联网(Internet)也是这个道理。
各位还需要想的一个问题是,路由器在网络和网络之间进行连接时必须要用的一个基本设备,网络和网络之间进行连接时要层层执行路由转发的。那这些路由有的是公网路由,它里边所添加的只是能识别互联网上公网的网络所可达路径的路由器,或者我们运营商所提供的路由,我们可以理解为就是这样一个路由。但是还有一类路由设备是我们的私网路由,它只是在我们的局域网内部、公司内部或组织内部自己构建时让多个网络可以彼此之间互相联通的。如上图:本地网络中左侧有个小网络是192.168.0,右侧有一个172.16.0,那很显然它们两个不在同一个网络当中,所以这个时候我们要让它们两个网络中通信就需要在自己的私网当中架设一个路由设备,让这两个网络之间的主机能够互相通信,中间它有可能经过多条路由设备,但不管怎么讲,在两个路由设备上面所配置的就是私网地址的路由信息。所以我们说,它们无论怎么路由都无法穿越我们本地的这么一个局域网网络。按照我们TCP/IP的规范,它们是不可以也不可能在公网路由器上被配置的路由条目,因此若本地网络中的主机发送的是私有地址请求的话那它只可能在本地局域网内所有的私网路由所能送达的位置,是不可能能够通过公网路由能够送出去的。
但是要考虑这一点,如果它的源地址是私网地址,当目标地址是公网地址,另外我们在互联网上路由时,是根据你所请求的目标地址进行报文转发的,所以说这个时候我们请求的报文就会送到公网路由器上,最终经过层层转发有可能送达到服务器了。那服务器收到以后,那就要响应了,一响应,他发现这个一个私网地址,私网地址的路由不会被公网路由器识别,那这时候怎么办呢?因此它很有可能发现自己本地也有私网,因此把这个响应吧报文通过本地的内网中的路由器设备送给内网中的真正刚好对应的一台主机,但这时候这个主机是不会接收的因为没有请求哪来的响应呢?甚至有可能没有进程发出请求也没有任何一个请求监听在这个端口上,所以大体上可能是这么一种情况。
所以我们说这就是我们互联网所面临的一个通信现状,那为什么会有私网地址呢?如果我们不期望在互联网上通信,只是在公司内部也期望能够基于TCP/IP协议规范完成本地通信的话,那就需要用到同样一个IP地址我们无需向IANA去购买地址或地址块,所以不需要付费,这就使得任何一家组织都可以使用这样的地址仍然能够构建其基于TCP/IP网络通信的网络。所以私网地址的存在是非常有用的,但是万一这些私网地址都需要访问互联网怎么办?如果现在局域网内的一台服务器它拥有公网地址然后它是可以访问互联网的,但是内网中的这些客户端主机没有公网地址,它们没法访问互联网,现在我们期望或需要这些内网中的主机都能访问互联网该如何操作?
那就要两种方式,访问互联网看我们的实际需要,可以在哪一层需要跟互联网中的主机在哪一层在哪个协议段或者在哪个层次完成通信,于是让内网中的主机访问互联网其实我们就有了两种方式(保证内网主机在必要时去访问互联网的机制):
- nat
- proxy
NAT
nat:Network Address Translatin,网络地址转换
nat是在网络层以及传输层实现的;更多的它操纵的是网络层的内容。
虽然说nat也可以实现所谓让那些私网地址的客户端经过地址转换以后访问互联网上的主机,不过,nat早期所实现的主要目的不是为了让你访问互联网,而是为了隐藏本地网络中的主机的。所以nat最初出现的目的是为了安全性的。
proxy:代理
代理通常是在应用层实现的;通常它代理对于某一特定应用的请求。
nat的工作模型:
既然叫网络地址转换,其实它就是实现地址重写的,说白了就是将地址改为非原来的、非原有的地址,而nat技术(不需描述其细节,了解即可)目前常见的来讲,有两种类型:
- SNAT:只修改请求报文的源地址(只是相对于请求报文一方来说的,如果我们要考虑到响应的话,其实SNAT必然对应着DNAT,DNAT必然对应着SNAT);
- DNAT:只修改请求报文的目标地址;
还有一种叫PAT(Port Address Transaction),事实上,SNAT或DNAT是可以与此同时,同时实现PAT即该端口功能的。
SNAT:
当客户端发出请求时,到达目标服务器主机,在此之前,它要先经由网关向外发送,如果不经由网关的话是没有用的。这个网关在这里我们通常把它称为叫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。
而对于iptables来讲,要想实现SNAT功能,只需要在NAT表上添加一条规则即可。但是作为源地址转换,应该在iptables上的nat表上的哪个链上做呢?试想一种场景,当请求报文刚刚到达时,这叫PREROUTING,但是刚刚到达时我们不知道它到底是访问本机呢还是通过本地转发呢,如果对方访问的是本机没必要做地址转换,因此只有经由本机转发确定时才能做地址转换。到本机的就没必要做地址转换了,因为彼此之间能够直接通信。因此需要在POSTROUTING链上做,只有我们确定了它要转发而且也确定了它要通过哪一块网卡出去 ,我们将其转换成那个网卡地址,比如有三块网卡,他通过第二块网卡转发所以我们应该转换为第二块网卡的地址。所以我们也只有路由完成之后马上离开本机已经确定了从哪个网卡出去我们才应该知道才能确切的了解应该转发为哪一个地址的,因此源地址转发要在POSTROUTING上实现,这是我们SNAT实现的位置。
DNAT:
那什么是目标地址转换?为什么要用到目标地址转换呢?
仍然是那种认证场景,我们公网上有很多主机,假设说内网中有一台主机,这台主机它提供了Web服务或其它服务,反正是它是提供能够让别人请求了的服务了的。但是由于SIP是一个私网地址,那么来自于互联网上的任何主机的请求就不能送达给SIP了,它也跟就收不到。那于是,我们就对外宣称,我们在FIP上有这么一个服务,仍然以Web服务为例,于是我们就在FIP上说我监听了80端口提供了Web服务,所以客户端的CIP访问时它的目标访问应该是FIP,因此通过路由器转发IP地址是公网地址没问题,层层转发送给了 FIP,但是FIP未提供这个服务,只是宣称说它有,于是就来访问了,到这以后我们本机上假设压根就没有任何一个进程监听在80上,那这时候怎么办呢?
我们可以把来自于外网主机的所有请求都将其统统转给内网中的Server主机即可,那当请求处于公网路由器时,其源地址是CIP目标地址是FIP,于是NAT Server做完地址转换后就扔到内网中了,转发后的结果中源地址是CIP目标地址是SIP,所以我们只改变了目标地址再请求返回。因此,SIP收到请求后发现这的确是访问自己的,那接下来它处理完后需要响应,响应的时候发现CIP压根就不是本地网络中的地址,那就要交给自己所指向的网关即GIP。GIP发现需要到互联网上响应给外网中的CIP主机的,但是我们又说过其实CIP主机访问的是FIP,CIP压根就没访问SIP,NAT Server必须要知道这种情况,那它还要将这个响应报文通过查找表后将这个地址改回去,那响应时源地址是SIP目标地址是CIP,但如果就这样发送过去了,CIP可能会觉得莫名其妙,因为它访问的是FIP不是SIP,那它能够拒收的。因此我们不能任由这种情况发生,NAT Server在这个报文扔回CIP之前要做地址转换,目标地址仍然为CIP源地址为FIP,我们发现此处改的是源地址,所以我们说任何一个目标地址转换都必然对应一个源地址转换。只不过后一段是由Server自动查找NAT会话表完成的。这种就叫做目标地址转换,而目标地址转换就是我们的服务器谎称或宣称自己拥有某个服务但是事实上并没有,它将其转给内网中的主机由内网中的主机进行响应了。像这种就叫做目标地址转换,目标地址转换的主要作用在于把内网中的主机映射进公网中能够让公网上的客户端来访问的。
所以这是一种我们在Windows Server通常称为叫服务器发布的技术,将内网中的一个私有地址的服务器能发布到外网中去或者称为叫映射到外网中去从而让外网主机跟内网主机可以访问了。那通过这种技术还有一个好处,如果用户此时请求的是FIP的22号端口,看我们的需求决定它是否需要向SIP端发送。刚才我们说过我们只是把SIP所在的主机作为一个Web服务器向外转发的,也就意味着只有来自互联网上请求FIP的80端口时,我们才转给内网中的SIP所在的这个主机,如果对方请求的22端口我们是否需要转发呢?假如说我们仅仅是把SIP的主机作为Web服务发布的话,22号端口不需要转发,也就意味着如果客户端请求的是FIP的22号端口,那对方结果仍然是送给当前服务器及网关自身响应了。所以我们想公网发布时,很有可能只发布内网主机的单个应用或者是有限个应用。
PNAT:
那说到这,我们是否可以这样做呢?比如我们请求80时转给SIP1,请求22时我们转给SIP2,都是请求FIP的只不过有的请求的是80转给第一个主机了有的请求的是22转给第二个主机了有的请求的是23转给第三个主机了。那我们可以把内网中的多个主机通过单个FIP分别都映射到外网中去但是它们提供的是不同的服务,所以一个IP可以对应于让n个主机提供n个不同的应用。所以DNAT能实现这种效果的,那现在我们要考虑两种特殊情形了,第一种特殊情形指的是如果说用户请求时我们告诉别人我们这里是Web服务,而互联网上Web服务默认都是请求80端口的,但是内网中的这个主机SIP1它没有监听80端口,而是监听在8080上,怎么办?客户端请求时一定请求的都是80,我们能不能将地址转换刚才转换的是目标地址,从FIP转换成为了SIP,但对方请求的目标端口是80呢?如果不动的话,扔回里边去后目标端口仍然是80,而我们内网也没有监听80怎么办呢?端口还可以做映射,你请求的是80,与此同时把目标地址改为SIP的同时,把目标端口从80改为8080。那问题是,当响应时,源地址是SIP源端口是8080,那对方请求的是FIP的80,那于是我们在真正构建响应报文响应时,其实除了源地址需要转发之外,源端口也得转发,源端口还得从8080换回80。这种就叫做端口转换或端口映射。这是第一种特殊情形。
第二种特殊请形,假设都是80,这是没问题的,当客户端到达FIP的 80端口时,请求的就是,内网中有两个主机SIP1、SIP2,它们两个都监听在80端口上都提供了Web服务,此时NAT是转换成SIP1还是SIP2呢?都可以,这取决于你在iptables上所设置的DNAT规则。如果我们设置的是SIP1,于是,对FIP80端口的请求都转给SIP1了,如果要设置SIP2,一样的。那可否将两个都设置上呢?这带来的结果是,如果我们请求FIP的时候,内网有两台主机,明确告诉你,我都可以转发至内网中去,SIP1也可,SIP2也可,那两个都行就意味着两个都不行。于是我们不可能说一下发给两个主机的,只能发给其中一个,这是必然的,那发给谁呢?那就需要从二者中挑一个,那怎么挑呢?轮着来,第一次给第一个,第二次给第二个,第三次给第一个,第四次给第二个…;或者随机,来一个请求我随机从里边挑一个等等。不管是哪一种,像轮询的这种就把来自互联网上的100个请求将其平均的分散给两个主机了,每一个主机可能只承载一半请求。这其实就叫做负载均衡,而iptables早些时候的确是能够实现负载均衡的效果的,不过现在iptables的DNAT中的负载均衡功能被舍去了。为什么要舍去呢?因为现在在内核中有一个更强大的机制叫ipvs,这是内核中直接自带的机制,能够实现基于10种方式来挑选后端的一个主机,不光是随机或者轮流,所以他实现的功能非常强大,而这些就是所谓的lvs。
所以说,lvs在出现之前,iptables自己要在DNAT上附带负载均衡功能,但由于有了lvs后,iptables的负载均衡功能就显得弱爆了,于是就用不上了,后来就被舍弃了。
说到这,大家想象一下,DNAT应该发生在什么位置呢?NAT只有PREROUTING、OUTROUTING和POSTROUTING,那DNAT应该发生在什么位置呢?应该在PREROUTING,因为路由转发以后一看它访问的是FIP,是本地地址就进INPUT了,一进INPUT就到本地内部去了,再转发就来不及了,所以应该在刚进入本机在路由发生之前就应该转好。本来访问的是FIP,在路由发生之前我改成SIP,于是一路由发现这是本地内网中的主机,于是转发了,通过FORWARD就走了。不过,在学完lvs后,你就会发现这并不是绝对的,我们也有其它方式实现,不过对于iptables而言,这必然也必须要发生在PREROUTING。
其实我们也可以仅做端口转换,而不转换目标地址,各位还需要注意的是,但客户端的请求经过路由层层发送到达FIP时,FIP这个主机假如说就是本机来接收的,那目标地址就不用变了,但如果本地主机不是在80端口上提供服务而是在8080端口提供服务,但你请求的就是80怎么办呢?此处只需要转换端口即可,怎么转呢?此前曾经讲过一个TAEGET叫REDIRECT即端口重定向,就是实现这个功能的,目标地址可以不用变你请求的是80但本机并没有在80上提供任何服务,于是给你转换成8080。只不过在这种场景中,通常不是由外而内而是由内而外的去实现。由内而外指的是通常当内网中的主机访问互联网时,内网主机访问Web服务,我们经过代理而不是用NAT。假如说主机访问的通常都是80,那通过代理服务器悄悄的改为代理服务器监听的端口就能实现了。
代理
那什么是代理,什么是转换呢?
以离婚官司为例,如果是NAT,离婚我们要去法院办理,法院假如说在20里之外的县城,那现在的问题是,如果你要到20里之外的县城去,我们怎么去呢?假如你自己没车怎么办?就有两种方式。第一种方式就是叫车,它将我们在到县城,但是打官司还是我们自己打的。但如果本人不想出庭,找一个代理律师,让那个人代理出庭,那个人负责所以事情,不光是走到县城。
由于NAT非常底层,所以不管你的目的是什么,它都可以将你载过去,你自己负责任何一个任务,不管是打离婚官司还是逛庙会还是每一块画布。但是代理通常是帮你去实现某一种特定应用的,对方只是代理离婚的而不代理逛庙会或者买画布。所以代理在应用层,因此应用层它一定是某一种特定应用,而我们平时所说的Web上网代理,它通常只能代理像http、https、ftp等这些基本的场景的应用层协议,再多,比如你想实现一些更为复杂的其它应用,代理服务器将无法帮你完成,像smtp,一般来讲,如果你不是smtp代理而是web代理这是做不了的。所以代理必须是某一种确定代理,你想代理打离婚那就叫离婚律师,想代理经济纠纷,那就要找经济纠纷律师…
如果我们用TCP/IP协议栈的七层模型描述一下,就以内网客户端访问互联网为例:
TCP/IP协议栈一共有七层,而NAT服务器工作在网络层和传输层,所以说这个过程如下:
如果基于NAT的方式工作,其工作流程大致为,Client请求很显然要构建一个TCP/IP报文,自上而下要流出这个协议栈,通过我们的物理设备送给Gateway,如果这是NAT的话,于是它要拆第一层,接着拆网络层,我们要把网络层当中的源地址改为Gateway自己的外网地址刚才叫FIP,于是拆完并封装起来之后它就又发出去了,到此就送给Server端了。这是这么一个位置。所以我们说Gateway只是处理到第三层,必要时最多到第四层而已,如果要做端口映射,意味着还需要改端口,一般NAT很少改端口。这就是所谓的NAT的工作模式。如下图:
而对于Proxy的工作模式,Proxy其实是代理某一种特定应用,比如只代理http协议,那看到http协议中请求的是什么,就需要将内容拆完,不然的话怎么能看到里边http首部呢?
所以请求如:Client请求在本地生成,经过物理设备、物理连接送达给Gateway,Gateway为了理解到底请求的是哪一种协议,是否要让我们代理,那于是一直拆到应用层,看应用层请求的是什么,甚至于既然我们能够看到应用层请求是什么了,我们就知道访问的是不是一个非法网站的,那么就可以在此处做ACL,定义哪些网站不允许访问、几点几分不允许访问等一些高级的特性。如果允许访问了,那么就又重新封装一个请求送给Server端,所以说在这种情况下,Proxy工作在第七层即应用层。不过此时还需考虑一个更为复杂的情形,对于Server来说,请求者是Gateway还是Client呢?是Gateway,不然的话为什么叫代理呢?就像你打了一个官司一样,你不会出场而是律师代理出场的,是代办人帮你出场的,所以在Server看来请求者是Gateway。所以Server响应给Gateway,但Gateway没有请求,所以此时Gateway的代理进程还需要重新封装成响应报文响应给Client。
但Gateway到底请求了没有呢?刚刚说过,是Gateway自己去请求的,这不是NAT,这是代理,所以真正的请求发出者Gateway自己这里有一个服务进程,因为它到应用层了,应用层要在用户空间,我们说下四层要在内核,上三层在用户空间,这三层对于TCP/IP协议栈来讲其实就是一个应用层,是由应用程序来实现的,应用程序就是工作为一个进程。这个进程它有两个作用,第一,他作为一个服务器端,第二,它又是客户端,服务器端就是Client请求时,他作为服务器,只不过它不提供服务,它到外边将你所请求的内容请求过来并取回来再请求给你,它是这样一个过程,这叫做代理。
所以对于代理而言,它对整个过程的参与深度就要比NAT深入的多得多的多了。
nat实现方式演示
与上次一样,启动三台主机,CentOS 7有两个接口,Remote Host为本地内网主机,LocalNet Host为外网中的主机:
本地内网主机IP为192.168.20.2,Gateway的内网地址是192.168.20.1,Gateway的外网地址是192.168.241.6,LocalNet Host的IP为192.168.241.7。
配置网络环境:
LocalNet Host:
CentOS 7:
将LocalNet Host的主机网关指向192.168.20.1:
使用LocalNet Host ping外网网关:
对于CentOS 7,查看核心转发功能是否打开:
Remote Host:
演示SNAT:
期望内网主机访问外网主机时能够基于源地址转换的方式进行;
先让外网主机提供一个WEB服务:
在内网请求一下:
此时无法请求到,因为LocalNet这台主机的请求能够送达给Gateway,Gateway能送给Server,但是Server收到以后发现这是一个非本网络的主机,而Server的网关主机指向192.168.241.2,所以它没办法回应给Gateway,不可能回应给Client的。所以请求报文能出去,响应报文无法回来。
在Remote Host上通过抓包分析一下:
于是在内网主机上去请求:
在外网主机上可看到:
在外网主机添加一条路由:
再次抓包:
内网主机:
外网主机可看到:
查看外网主机日志:
删除外网主机刚才添加的路由:
测试发现又无法访问了,这是下一步骤的用于测试的基础前提。
在CentOS7上添加 一条iptables规则,所有来自于192.168.20网络中的主机地址的请求统统将源地址改为172.16.100.9:
测试:
内网主机:
刚才没有添加NAT规则是访问不到的,现在可以访问是因为用户请求时把源地址从192.168.20.2转换为了Gateway的172.16.100.9,100.9与100.12是在同一个网络中的,它们可以直接通信的,在Remote Host验证:
CentOS 7:
此时,我们内网这个主机做任何访问都可以跟192.168.241.6所能够到达的外网主机通信了。如:192.168.10.2的所有报文的源地址都转换为了192.168.241.6,而192.168.241.6是可以与192.168.241.10直接通信的,因此就可以使用yum命令从192.168.241.10仓库下载安装程序了。
DNAT:
接下来将这个过程反转一下,在CentOS7上把规则清空:
此时Local主机是Server,Remote Host反而是Client,意味着在local主机上要启动一个WEB服务器:
此时计划让外网主机主机能访问刚才内网主机192.168.20.2上所提供的WEB服务,假如说192.168.20.2是一个私网主机而192.168.241.0网络是互联网上的网络,那不可能直接请求192.168.20.2作为目标地址的,因此此时用的地址是192.168.241.6这个网关上的公网地址。因此需要在互联网上声称说我们在192.168.241.6上有WEB服务但其实我们没有,但又需要让别人能访问到,因此需要添加DNAT规则:
在外网中请求192.168.241.6的WEB服务:
在内网主机查看WEB访问日志:
现在对192.168.241.6的SSH服务的请求也转给192.168.20.2:
此时本机也有SSH服务,但是要转发给内网,到底谁生效呢?转发内网的生效,因为进来之后无论本机有没有监听22号端口我们已经将其目标地址改过了,就不会交给本机了,所以本机即便监听了22号端口也没有用。
在Windows端使用ssh客户端测试:
接下来演示端口映射的效果:
假设内网主机压根就不监听在我们所期望的监听的端口上,但是外网访问时却依然可以请求这个端口。
在内网将WEB服务改为监听在8080端口:
在外网请求时,此时无法请求:
映射:
外网请求:
SNAT的MASQUERADE:
再回到SNAT上,再想一个问题,有时候在互联网上访问的时候,我们可能会遇到这种现状,我们互联网地址有一个外网地址,但是是ADSL拨号的。SNAT是用来代理内网主机或者用来能够承载内网主机访问互联网的,但是我们的外网的地址,如刚才使用的—to-source指明为192.168.241.6,但是192.168.241.6是一个既定地址,如果在互联网上将来我们将来上网时用到的是ADSL拨号的IP地址是经常发生改变的,这时候怎么办呢?
那此时有一个专门的TARTGET叫MASQUERADE(地址伪装),它能够自动找一个适合的外网地址作为源地址转换时自动使用的源地址(自动转换为的源地址)。
演示如下:
仍然是代理内网地址,让内网主机访问Remote Host。刚才做了SNAT,所以是可以访问的,但是假如说我们外网192.168.241.6的地址是经常发生变化的,我们没办法使用--to-source确定到某个地址上,可以做如下操作:
测试:
虽然我们没有给它改为源地址,它也一样能够找到一个合适的源地址对其进行转换的,而这种机制就叫做MASQUERADE。
总结
FullNAT:全地址转换
请求时源地址与目标地址都转换,响应时源地址和目标地址都转换。
fullnat只有在lvs或lvs的某些特殊情形下才会用到,在讲到lvs的负载均衡集群时会讲到fullnat为什么会用到以及如何使用。