赞
踩
本文会从NAT的简介入手,详解NAT技术本身,通过本文,你可以清楚了理解NAT,SNAT, DNAT, PAT, NAPT, Full NAT的定义,它个之间的区别与联系。最后会详细给出如何将一台多网卡的Linux主机配置成一台NAT路由器。
如果你已经清楚了NAT的定义,可以直接跳转到这里看如何通过NAT table配置一台Linux主机成一台软路由
NAT是Network Address Translation的简写,指网络地址转换技术,即将一个IP地址转换成另外一个IP地址的技术。 当在内部网络的一些主机本来已经分配到了本地IP地址(即私有IP地址),但又需要和因特网上的主机通信时(按照IP协议与路由协议,路由器只会转发公有IP地址主机发出来报文),可通过NAT技术来完成。
公网IP地址的稀缺性,导致无法给每一个需要上网的主机都分配一个公网IP地址,所以就引入了NAT技术,让多个主机可以共用一个公网IP地址去访问外网,提供了这样的功能的设备被称为NAT路由器,NAT路由器可以将路由器管理下的私有网络里的每个主机的的IP报文的目标IP和源IP地址。除了去市场上购买这样的NAT路由器之外,一台多网口的Linux主机也可以完成这样的功能。
如上图所示,我们有一台主机"Linux Router",这台主机通过公网IP地址1.1.1.1连接到公网,它的另外一个网卡连接到内部私有网络192.168.1.0/24。我们都已经知道192.168.1.0/24 是有一个私有网段,这个网段下的所有IP地址都是私有IP地址,路由器是不会转发私有IP地址的数据包的,所以任何公网上的主机都无法访问我们私网里的主机 (所以使用私用IP地址,也是给我们的主机提供了网络安全保护的)。
为了使私网里的主机能和外网的主机进行通信,NAT路由器(Linux router主机)将这些私网内主机的私有IP地址转换成它自己的公网IP(即1.1.1.1)。这里外网上的主机是与Linux router的公网IP地址进行数据通信的,所以它需要知道哪些报文是给它自己的,而且哪些报文是给它下面的私有网络下的其它主机的。Linux router这台主机,通过维护一个所有通过它的TCP/IP连接的数据库来完成这个区分。我们称这个功能为连接跟踪,Linux主机通过在内存里创建并维护了一个TCP/UDP连接的状态表来实现这个连接跟踪功能。这所有连接的状态信息被保存在/proc/net/ip_conntrack目录下,这个状态表主要包括:IP地址,端口号,协议类型,连接状态和超时状态。如下:
tcp 6 262872 ESTABLISHED src=2.2.2.2 dst=1.1.1.1 sport=80 dport=65000 [UNREPLIED] src=192.168.1.2 dst=2.2.2.2 sport=65000 dport=80 use=1
udp 17 174 src=1.1.1.1 dst=1.1.1.11 sport=40997 dport=161 src=1.1.1.11 dst=1.1.1.1 sport=161 dport=40997 [ASSURED] use=1
通过连接跟踪功能,Linux router知道当一个响应报文(用于响应192.168.1.2发起的请求)到达 1.1.1.1时,这个报文需要被转发给192.168.1.2这台笔记本电脑,所以它会把响应报文的目标IP地址从1.1.1.1改写成192.168.1.2,然后再转发给192.168.1.2。注意:基于连接跟踪功能的防火墙被称为有状态防火墙。
NAT功能按场景可以分成以下几类:
SNAT(Source Network Address Translation)是源IP地址转换的缩写。因为在SNAT里,只有源IP地址会被转换。NAT设备会把NAT设备带着的所有设备发送的IP报文的源IP地址都会被转换成NAT设备的出口设备的IP地址。只有在需要访问外网时,数据包的源IP地址才会被转换,但要注意的是从外网上某个公网服务器发起的请求的IP报文不会被转换源IP地址,也不会转发到私网里的任何服务器(意味着所有的访问连接,都需要私网里的某个主机来主动发起)。这为私网里的服务器提供了访问保护,同时也节省了很多公网IP地址。SNAT分成静态SNAT和动态SNAT二类,静态SNAT是指一个或者多个NAT后面的主机的IP地址都会被转换成同一个公网的IP地址,动态SNAT是指一个或者多个NAT后面的主机的IP地址会被转换成一系列的公网的IP地址。在动态NAT下,NAT路由器为每一个连接会从公网IP池里选择一个IP地址,所以同一个主机的多个连接是很有可能会被转换成不同的公网源IP地址的。通常,动态SNAT,iptables会在每个连接初始化时,为这个连接选择使用得最小的公网IP地址。如果IP池里有多个IP都从来没有被用到过,那么iptables会随机选择其中一个。IP伪装Masquerade(MASQ)工作在静态SNAT模式下,如果你无法指定一个IP的话(比如说公网接口是自动获取IP的),那么IP伪装功能可以自动的使用NAT路由器的接外网的网卡的IP地址。
注意:SNAT是被iptables在linux内核2.4中由Netfilter引入的,而IP伪装则被iptables保留下来,以支持如PPP接口这一类动态配置
IP地址的接口,它用IP伪装MASQ去代替先找到动态分配的IP再做SNAT这样的过程。
为了支持SNAT或者Masquerade,NAT路由器必须支持连接跟踪功能,这样它才可以知道当前连接的数据是由私网里的哪个服务器发起的,它才能知道如何做SNAT并转发数据。
下图显示SNAT, MASQ和连接跟踪是怎么工作的:
在这个图里,
192.168.1.3这个主机,主动发起一个到2.2.2.2的连接。这个连接请求的数据包被送到Linux router,此时这个请求数据包的源IP地址是192.168.1.3,目标IP地址是2.2.2.2.
如果此时我们给192.168.1.3这个IP配置了SNAT或 Masqueraded,Linux router会把请求报文的IP头里的源IP address从192.168.1.3改成1.1.1.1,然后按照路由协议把包发往2.2.2.2。同时保存这个连接信息到/proc/net/ip_conntrack.
当收到2.2.2.2的响应报文时,到达Linux router的响应报文的源IP是2.2.2.2目标IP是1.1.1.1。这里Linux router在/proc/net/ip_conntrack里查找连接信息,然后就会找到上一步建立的那条连接。
Linux router会将响应报文的IP头里的目标IP地址从1.1.1.1改成192.168.1.3,然后按照路由规则发送这个IP报文到192.168.1.3主机。
注意:使用SNAT或IP伪装Masquerade时,只有192.168.1.3可以发起到2.2.2.2的连接,
然而2.2.2.2不能发起到192.168.1.3的连接。因为192.168.1.3是一个私网IP地址。
DNAT(Destination Network Address Translations)将一个公网IP地址转换成一个私网IP地址。DNAT的功能和SNAT是相反的,所以如果你同时使用了SNAT去把私网IP地址转换成公网IP地址和DNAT把把同一个公网IP地址转换成同一个私网IP地址,那就就形成了full NAT。DNAT 通常用于以下场景,你在NAT后面有多台服务器,你根据端口或者协议的不同,把同一个公网的IP地址映射到不同的私网IP地址,比如HTTP请求转到HTTP服务器,FTP请求转到FTP服务器。所以这个DNAT也称为端口转发。如下图所示:
正常情况下,2.2.2.2这台主机是不能主动发起与192.168.1.3主机的连接的,因为192.168.1.3是一个私网IP地址,公网上的路由器是不会转发目标的地址为私网地址的IP报文的。但2.2.2.2主机可以发起与1.1.1.1主机的连接请示。
此时,如果我们在1.1.1.1主机上配置了DNAT规则,并且请求报文命令DNAT规则的话,Linux router会把这个请求报文的IP头中的目标IP地址从1.1.1.1改为192.168.1.3,然后将这个报文转发给192.168.1.3,然后记录当前连接到它的连接跟踪数据库里。
当192.168.1.3发回响应报文时,Linux router会查询它的连接跟踪数据库,并发现这个响应报文是属于由2.2.2.2发起的到1.1.1.1的连接的
Linux router 会把这个响应报文的IP头中的源IP地址从192.168.1.3改为1.1.1.1。然后报报文发送给2.2.2.2。
注意:如果只配置了DNAT,但没有配置SNAT,那么 2.2.2.2可以通过将目标地址设置为1.1.1.1,从而和
192.168.1.3建立连接。但192.168.1.3不能主动发起连接到2.2.2.2。
题外话:很多家用的SOHO路由器把它们提供的DNAT功能叫做DMZ。事实上,把DNAT叫做DMZ是不完全正确的。DMZ是Demilitarized Zone的缩写,意思是你的网络中,不设置任何过滤规则的区域。DMZ本质上是一个公有IP的集合,使用这些公有网络IP的服务器,是允许任何连接的(允许所有进出二个方向的连接与通信)。事实上家用的SOHO路由器是给局域网做了一个IP伪装Masquerade,所以它们把可以接收所有目标IP为路由器的WAN口的公网IP的那个私有服务器为DMZ。
Full NAT是完全将一个IP地址映入到另外一个IP地址。在配置了full NAT的情况下,位于NAT后面的一个私有IP地址的服务器(比如: 192.168.1.3)在公网上会被完全看成NAT路由器提供的公网IP地址(比如1.1.1.1)。这意味着,192.168.1.3发出的请求报文,在公网上的主机看来,完全等同于从1.1.1.1 (SNAT)收到报文。.所有从公网其它主机发往1.1.1.1的报文,NAT路由器都会把目标IP地址改成192.168.1.3后转发给192.168.1.3主机,即使这个报文不属于任何一个由192.168.1.3主机发起的连接 (DNAT)。
换句话说,full NAT = SNAT+DNAT。Linux router从公网收到一个不属于任何私网主机发起的连接的IP报文会被转到给到192.168.1.3,所以192.168.1.3这个主机并不因为它的私有IP地址而受到任何连接限制与安全保护。
注意:在上一章的DNAT的例子里,1.1.1.1可以是NAT路由器的公网IP地址,也可以是它能收到目标地址为1.1.1.1的报文就可以(其它路由
器会把目标为1.1.1.1的报文转发给NAT路由器)。如果1.1.1.1是NAT路由器的公网IP地址(如上一章图所示), 我产就无法从公网上访问
NAT路由器(比如:我们就无法SSH登录到NAT路由器),因为NAT路由器会把所有发给1.1.1.1的报文都转发给192.168.1.3。
PAT是Port Address Translation的缩写,意思是端口地址转换,也被叫做NAPT,是Network Address and Port Translation的缩写,表示地址和端口转换。PAT不仅仅隔离隐藏了IP地址,也隔离隐藏了特定服务器的端口号。比如,公司的web服务器部署在NAT路由器后面,web服务器的IP地址是192.168.1.100。然后NAT路由器只有一个公网的IP地址,我们在DNS服务器中,把http://www.ourcompanyname.com这个地址的IP地址配置成了1.1.1.1。如果我们要从公网上访问这个web服务器,NAT路由器需要把收到的所有发给1.1.1.1的目标端口号为80的IP报文的目标IP地址改成192.168.1.100。还有,公司同时还有个内网专用的内网web服务器192.168.1.200,它也运行在80端口上(我们知道按协议web服务器应该运行在80端口)。当在办公室时,我们可以通过地址http://192.168.1.200访问内网web服务器。但如果我们希望在外网也可以访问内网的web服务器,那么我们就需要通过PAT来实现这个功能,我们可以任意选择一个NAT路由器上没有在使用的端口号(比如2143端口),然后把发往1.1.1.1的2143端口的所有IP报文的目标地址和端口修改成192.168.1.200和80端口。
通过这个配置,在外网:
如果公司的内网web服务器需要主动访问外网的话,NAT服务器就不需要重写源IP地址为192.168.1.200的IP报文的端口,只需要配置SNAT或者Masquerade就可以了。
未完待续
未完待续
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。