博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
NAT的特殊处理
阅读量:2226 次
发布时间:2019-05-09

本文共 12657 字,大约阅读时间需要 42 分钟。

在全球IPv4地址愈发匮乏的大背景下,NAT技术应运而生,并且随着时间的推移,这项技术运用的越来越广泛。在实际应用中,NAT大体可以分成EasyIP、PAT、NOPAT、静态NAT和NAT Server几种用法。

NAT技术的原理并不复杂,如所示,三个带有内部地址的数据报文到达NAT设备,其中报文1和报文2来自同一个内部地址但有不同的源端口号,报文1和报文3来自不同的内部地址但具有相同的源端口号。通过NAT映射,三个数据报的源IP地址都被转换到同一个外部地址,但每个数据报都被赋予了不同的源端口号,因而仍保留了报文之间的区别。当各报文的回应报文到达时,NAT设备仍能够根据回应报文的目的IP地址和目的端口号来区别该报文应转发到的内部主机。

                                                                                                       图1 源地址转换原理图

NAT设备通过建立五元组(源地址、源端口号、协议类型、目的地址、目的端口号)表项为依据进行地址分配和报文过滤。即,对于来自相同源地址和源端口号的报文,若其目的地址和目的端口号不同,通过映射后,相同的源地址和源端口号将被转换为不同的外部地址和端口号,并且NAT设备只允许这些目的地址对应的外部网络的主机才可以通过该转换后的地址和端口来访问这些内部网络的主机。

原理虽然简单,但是在实际应用中还是会碰到各种的问题,比如ICMP报文没有端口号,设备如何进行NAT映射?分片报文中没有四层信息,设备又如何进行NAT映射?本文将以H3C公司SecPath F1000-E设备为例,对NAT的特殊处理进行深入的解析。

1      地址统一管理

首先我们在设备上配置一个PAT方式的NAT转换,一个NOPAT方式的NAT转换,再配置两个NAT Server:  

#                                                                               nat address-group 3 218.197.70.10 218.197.70.19                                 nat address-group 13 61.154.70.20 61.154.70.29                                         #                                                                              interface GigabitEthernet0/3                                                    port link-mode routenat outbound 3001 address-group 13 no-pat                                     nat outbound 3000 address-group 3                                              nat server protocol tcp global 218.197.70.20 www inside 192.168.200.2 www       nat server protocol udp global 218.197.70.21 tftp inside 192.168.200.2 tftp    ip address 218.197.70.1 255.255.255.0                                         #
           
       
                                               

当我们查看路由表的时候可以看到NAT地址池的地址以及NAT Server的公网地址全部被加入其中。

display ip routing-table Routing Tables: Public Destinations : 31 Routes : 31 Destination/Mask Proto Pre Cost NextHop Interface 0.0.0.0/0 Static 60 0 162.105.12.1 GE0/0 61.154.70.20/32 Static 1 0 0.0.0.0 NULL0 61.154.70.21/32 Static 1 0 0.0.0.0 NULL0 61.154.70.22/32 Static 1 0 0.0.0.0 NULL0 61.154.70.23/32 Static 1 0 0.0.0.0 NULL0 61.154.70.24/32 Static 1 0 0.0.0.0 NULL0 61.154.70.25/32 Static 1 0 0.0.0.0 NULL0 61.154.70.26/32 Static 1 0 0.0.0.0 NULL0 61.154.70.27/32 Static 1 0 0.0.0.0 NULL0 61.154.70.28/32 Static 1 0 0.0.0.0 NULL0 61.154.70.29/32 Static 1 0 0.0.0.0 NULL0 127.0.0.0/8 Direct 0 0 127.0.0.1 InLoop0 127.0.0.1/32 Direct 0 0 127.0.0.1 InLoop0 162.105.12.0/24 Direct 0 0 162.105.12.211 GE0/0 162.105.12.211/32 Direct 0 0 127.0.0.1 InLoop0 192.168.200.0/24 Direct 0 0 192.168.200.1 GE0/2 192.168.200.1/32 Direct 0 0 127.0.0.1 InLoop0 218.197.70.0/24 Direct 0 0 218.197.70.1 GE0/3 218.197.70.1/32 Direct 0 0 127.0.0.1 InLoop0 218.197.70.10/32 Static 1 0 0.0.0.0 NULL0 218.197.70.11/32 Static 1 0 0.0.0.0 NULL0 218.197.70.12/32 Static 1 0 0.0.0.0 NULL0 218.197.70.13/32 Static 1 0 0.0.0.0 NULL0 218.197.70.14/32 Static 1 0 0.0.0.0 NULL0 218.197.70.15/32 Static 1 0 0.0.0.0 NULL0 218.197.70.16/32 Static 1 0 0.0.0.0 NULL0 218.197.70.17/32 Static 1 0 0.0.0.0 NULL0 218.197.70.18/32 Static 1 0 0.0.0.0 NULL0 218.197.70.19/32 Static 1 0 0.0.0.0 NULL0 218.197.70.20/32 Static 1 0 0.0.0.0 NULL0 218.197.70.21/32 Static 1 0 0.0.0.0 NULL0
       

如图2所示,从内网来的报文经过NAT转换,到达外网中的目的地,目的主机向NAT转换后的地址回应报文;当报文到达与NAT出接口直连的设备时,这个设备并不知道这个经过转换的公网地址所对应的MAC,此时便会发送ARP请求。

                                                                                                   图2 NAT设备的ARP响应

NAT使用的公网地址,包括了被引用的地址池的地址、NAT Server的公网地址和被引用的静态配置的公网地址。这些地址全部会进入地址管理模块进行统一地址管理,并由地址管理模块通知路由管理模块将这些IP地址加入路由表。当外部设备向这些地址发起ARP请求,设备便会将ARP请求送到地址管理模块检查ARP报文的合法性,地址管理发现ARP所请求的IP地址为NAT地址池地址,则通知NAT模块判断是否需要回应ARP,NAT模块会检查ARP所请求的IP地址是否是收到ARP接口下配置的NAT的地址,如果是则通知ARP模块进行ARP应答。

由于有了地址统一管理,与接口不在同一网段的地址池的地址被加入的本地路由表,并且可以有选择的将其引入动态路由协议,通过OSPF或者BGP将其发布出去,简化了组网中其他设备的配置。

2      地址池的优先级

双机热备对于防火墙来说是一个必不可少的功能,两台防火墙上的NAT配置也需要完全相同,这样就会出现一个问题:如果两个防火墙分别将两条不同的流映射到相同的公网地址,并且端口也相同的话,势必会造成表项的混乱,所以我们引入了地址池优先级的概念。

在双机热备的环境中,如果地址池被配置为高优先级,在进行端口映射的时候端口取值范围为1024~35000;如果地址池被配置为低优先级,其端口取值范围为35001~65535。这样主备两台防火墙虽然使用相同的NAT地址池中的地址,但是由于地址池的优先级不同,所以就不会出现NAT转换后公网IP和公网端口完全相同的情况了。

地址池优先级只有在双机热备的环境中才有意义,如果是单机环境,高优先级的地址池的端口取值范围就是1024~65535,而低优先级地址池的端口取值范围依旧是35001~65535。

3      PING操作的NAT映射

H3C ComwareV5平台为了保证内网的安全性,采用了五元组匹配NAT映射表项,但是ICMP报文没有类似于TCP和UDP报文的端口信息,既要对ICMP的请求报文进行NAT映射,又要确保网络的安全性,只允许合法的ICMP响应报文进入内网,就必须对其进行特殊的处理。

                                                                                                        图3 NAT简单组网图

图3是一个最简单的NAT组网图,内网使用192.168.200.0/24的私网地址,外网是218.197.70.0/24的公网地址,而在设备连接外网的接口上我们启用了NAT。我们从内网的PC1去PING外网的PC2是可以成功的,而我们在设备上看到了这样的一个表项:

Initiator:                                                                       Source IP/Port : 192.168.200.2/2048                                             Dest IP/Port   : 218.197.70.2/1024                                             VPN-Instance/VLAN ID/VLL ID:                                                 Responder:                                                                       Source IP/Port : 218.197.70.2/0                                                Dest IP/Port   : 218.197.70.12/1036                                            VPN-Instance/VLAN ID/VLL ID:                                                 Pro: ICMP(1)    App: unknown           State: ICMP-CLOSED                      Start time: 2011-05-28 11:44:35  TTL: 23s                                      Root                     Zone(in): Private                                                              Zone(out): Public                                     Received packet(s)(Init): 4 packet(s) 240 byte(s)                              Received packet(s)(Reply): 4 packet(s) 240 byte(s)
              

既然ICMP报文没有端口信息,那么表项中的端口信息又是从何而来的呢?我们不妨通过对报文的分析找到答案。

                                                                                                     图4 内网ICMP请求报文

从内网抓到的ICMP请求报文可以看出TYPE+CODE字段的值是0x0800,而Identifier字段的值是0x0400,这两个值转换成十进制的数值,正好是2048和1024。与发起方的源端口数值和目的端口数值一致。那么我们再看一下内网抓到的ICMP响应报文是否可以与响应方的源端口和目的端口对应。

                                                                                                     图5 内网ICMP响应报文

在响应报文中TYPE+CODE字段为0x0000,十进制也是0,这与表项中响应方的源端口相同;但是问题出现在响应方的目的端口,在报文中Identifier字段的值是0x0400,十进制为1024,而表项中的目的端口却为1036,这又是为什么呢?原来Windows系统发出的ICMP报文的Identifier字段全部都为0x0400,当多台内网PC同时PING一个外网PC时,如果设备仅仅对Identifier字段进行简单的运算,极有可能造成多个表项中响应方的参数相同,使得回程报文发送错误。为避免这种情况的发生,设备会在对ICMP请求报文进行IP地址转换的同时,还会选择一个空闲的端口号对报文中的Identifier字段进行变化,以避免上述情况的发生。

                                                                                                     图6 外网ICMP请求报文

在图6中我们可以看到转换后的ICMP请求报文的Identifier字段已经变成了0x040c,也就是十进制的1036,这与表项中响应方的目的端口一致,这样的一个五元组就能唯一确定一个PING操作了。

4      ICMP差错报文的处理

内网PC1试图通过TFTP协议从外网的PC2下载aaa.bin文件,但是PC2并没有开启TFTP服务,这时PC2会向PC1回应ICMP端口不可达的差错报文。如果我们依然按照上一节中的规则来理解ICMP差错报文的转换过程,那就大错特错了。对于源地址转换的NAT来说,外网的报文要想顺利进入内网,就必须五元组匹配设备上的NAT表项,内网访问外网时使用的是UDP协议,而ICMP差错报文是ICMP协议,这一点就不符合要求。但是从图7内网PC1上抓包我们清楚的看到这个ICMP差错报文确确实实的被转发了进来。这其中的奥妙就在于设备对ICMP差错报文的特殊处理。

                                                                                                     图7 内网TFTP访问抓包

当PC1访问PC2时,设备上会生成这样一个表项,PC1使用的是UDP协议,源IP和源端口为192.168.200.2/2428,目的IP和目的端口为218.197.70.2/69;设备进行NAT转换后的源IP和源端口为218.197.70.12/1048。

Initiator:                                                                     

  Source IP/Port : 192.168.200.2/2428                                          

  Dest IP/Port   : 218.197.70.2/69                                             

  VPN-Instance/VLAN ID/VLL ID:                                                 

Responder:                                                                     

  Source IP/Port : 218.197.70.2/69                                             

  Dest IP/Port   : 218.197.70.12/1048                                          

  VPN-Instance/VLAN ID/VLL ID:                                                 

Pro: UDP(17)    App: TFTP              State: UDP-OPEN                         

Start time: 2011-05-28 13:17:49  TTL: 119s                                     

Root                     Zone(in): Private                                     

                         Zone(out): Public                                      

Received packet(s)(Init): 2 packet(s) 88 byte(s)                               

Received packet(s)(Reply): 0 packet(s) 0 byte(s)                               

再让我们来看看PC2回应的ICMP差错报文的结构,如图8和图9所示:

                                                                                                 图8 外网ICMP差错报文结构

                                                                                                 图9 内网ICMP差错报文结构

比较内网和外网的报文之后答案已经非常清楚了,设备根据ICMP差错报文体中的IP地址和端口号匹配设备上的NAT表,再根据这个NAT表项对报文目的IP,以及报文体中的源IP和源端口进行了转换,然后发送到内网的PC1。

同时设备会根据ICMP差错报文对相应的会话进行加速老化,已达到节省设备资源的目的。刚才老化时间还是120秒的表项在收到ICMP差错报文后迅速将老化时间调整为15秒。会话状态也由UDP-OPEN变为了Accelerate。

Initiator:                                                                     

  Source IP/Port : 192.168.200.2/2428                                          

  Dest IP/Port   : 218.197.70.2/69                                              

  VPN-Instance/VLAN ID/VLL ID:                                                 

Responder:                                                                     

  Source IP/Port : 218.197.70.2/69                                             

  Dest IP/Port   : 218.197.70.12/1048                                          

  VPN-Instance/VLAN ID/VLL ID:                                                 

Pro: UDP(17)    App: TFTP              State: Accelerate                       

Start time: 2011-05-28 13:17:49  TTL: 14s                                      

Root                     Zone(in): Private                                     

                         Zone(out): Public                                     

Received packet(s)(Init): 9 packet(s) 403 byte(s)                              

Received packet(s)(Reply): 0 packet(s) 0 byte(s)                               

5      分片报文的NAT转换

在PAT转换类型的NAT地址转换中,NAT除了对IP地址转换外,还使用到TCP或UDP报文的端口号、ICMP报文的ICMP头中的Identifier字段信息。当一个报文被分成若干片之后,这些信息只有首片报文会携带,后续分片报文依靠报文ID、分片标志位、分片偏移量依次关联到前一个分片。以ICMP报文为例,说明NAT对分片的IP报文进行的处理。在ICMP报文分片后,只有在首片ICMP报文中包含ICMP头的Identifier字段。在首片报文到达NAT设备后,按照正常的转换流程,根据源IP地址和Identifier信息生成转换表项并转发出去。在第二个及后续分片到达后,由于只包含IP地址却没有Identifier信息,可能因此无法进行NAT转换。解决的办法有两种:

1)        先重组,再进行NAT转换,在分片报文到达后,先进缓存,等属于这个IP报文的所有分片到达后进行虚拟分片重组,再进行NAT地址转换。最后将NAT转换完成的IP报文按照顺序发送出去。

2)        在首片到达并转换后,设备记录并保存转换首片使用的IP及Identifier信息,并在后续分片到达后应用同样的转换表项进行转换。

在H3C SecPath F1000-E中会由流分类和虚拟分片重组两个模块对分片报文进行处理。首先流分类会对到达设备的报文进行标识,如果是非首片的IP报文,流分类模块会将这个报文打上和其首片报文相同的标记,交给后续模块处理。NAT模块根据这个标识就可以判断如何对非首片的IP报文进行NAT转换了。

而虚拟分片重组所解决的就是报文乱序到达设备的情况,也就是使用上面的第一种方法对分片的报文进行NAT转换。

6      多核产品的无限连接

最后我们来介绍一下多核产品特有的NAT无限连接。

顾名思义,NAT无限连接就是内网通过NAT访问外网不会受到公网地址数量的影响,并发访问的数量只与设备的最大会话数相关。

前面我们讲到,设备在判断从外网进入内网的报文是否合法是采用了五元组匹配,源地址、源端口号、协议类型、目的地址、目的端口号必须完全一样设备才会唯一确认一个表项。这里我们可以做一个实验,配置NAT设备的公网地址只有一个,并且配置成了高优先级。也就是说在内网所有的PC全部使用相同的协议访问外网同一台服务器、同一个端口的情况下,SecPath F1000-E可以支持64512个并发会话。

<SecPath F1000-E>display session statistics                                                    

Current session(s):64514                                                       

         Current     TCP session(s): 1                                         

                 Half-Open: 0            Half-Close: 0                         

         Current     UDP session(s): 64512                                     

         Current    ICMP session(s): 0                                         

         Current   RAWIP session(s): 0                                         

                                                                               

Current relation table(s): 0                                                   

                                                                                

Session establishment rate:         0/s                                        

         TCP     Session establishment rate:         0/s                       

         UDP     Session establishment rate:         0/s                       

         ICMP    Session establishment rate:         0/s                       

         RAWIP   Session establishment rate:         0/s                       

                                                                                

Received     TCP:               100945 packet(s)              22944126 byte(s) 

Received     UDP:              1222623 packet(s)              63581139 byte(s) 

Received    ICMP:               630395 packet(s)              17777039 byte(s) 

Received   RAWIP:                    0 packet(s)                     0 byte(s) 

Dropped      TCP:                    0 packet(s)                     0 byte(s) 

Dropped      UDP:                    0 packet(s)                     0 byte(s) 

Dropped     ICMP:                    0 packet(s)                     0 byte(s) 

Dropped    RAWIP:                    0 packet(s)                     0 byte(s) 

如果访问的目的地址有两个,则并发会话数可以达到129024个:

<SecPath F1000-E>display session statistics                                                      

Current session(s):129026                                                      

         Current     TCP session(s): 0                                         

                 Half-Open: 0            Half-Close: 0                         

         Current     UDP session(s): 129024                                    

         Current    ICMP session(s): 0                                         

         Current   RAWIP session(s): 0                                          

                                                                               

Current relation table(s): 0                                                   

                                                                                

Session establishment rate:         0/s                                        

         TCP     Session establishment rate:         0/s                       

         UDP     Session establishment rate:         0/s                       

         ICMP    Session establishment rate:         0/s                       

         RAWIP   Session establishment rate:         0/s                       

                                                                               

Received     TCP:               150635 packet(s)              62257395 byte(s) 

Received     UDP:              2940678 packet(s)             152925584 byte(s) 

Received    ICMP:               630395 packet(s)              17777039 byte(s) 

Received   RAWIP:                    0 packet(s)                     0 byte(s) 

Dropped      TCP:                    0 packet(s)                     0 byte(s) 

Dropped      UDP:                    0 packet(s)                     0 byte(s) 

Dropped     ICMP:                    0 packet(s)                     0 byte(s) 

Dropped    RAWIP:                    0 packet(s)                     0 byte(s) 

从下面的详细会话表项可以看到,经过NAT转换后,相同的源地址+端口可以与不同的目的地址+端口建立会话对应关系。

Initiator:                                                                      

  Source IP/Port : 192.168.200.3/52024                                         

  Dest IP/Port   : 218.197.70.3/5000                                           

  VPN-Instance/VLAN ID/VLL ID:

Responder:                                                                      

  Source IP/Port : 218.197.70.3/5000                                           

  Dest IP/Port   : 218.197.70.200/65535                                        

  VPN-Instance/VLAN ID/VLL ID:                                                  

Pro: UDP(17)    App: unknown           State: UDP-OPEN                         

Start time: 2011-05-28 17:24:12  TTL: 9881s                                    

Root                     Zone(in): Private                                     

                         Zone(out): Public                                     

Received packet(s)(Init): 2 packet(s) 104 byte(s)                              

Received packet(s)(Reply): 0 packet(s) 0 byte(s)                               

 

Initiator:                                                                      

  Source IP/Port : 192.168.200.3/50215                                         

  Dest IP/Port   : 218.197.70.4/5000                                           

  VPN-Instance/VLAN ID/VLL ID:                                                 

Responder:                                                                     

  Source IP/Port : 218.197.70.4/5000                                           

  Dest IP/Port   : 218.197.70.200/65535                                         

  VPN-Instance/VLAN ID/VLL ID:                                                 

Pro: UDP(17)    App: unknown           State: UDP-OPEN                         

Start time: 2011-05-28 17:18:28  TTL: 9697s                                     

Root                     Zone(in): Private                                     

                         Zone(out): Public                                     

Received packet(s)(Init): 6 packet(s) 312 byte(s)                               

Received packet(s)(Reply): 0 packet(s) 0 byte(s)     

而在真实的网络中,内网PC访问的目的IP和端口的组合可能有几千甚至上万个。那么NAT所能支持的并发数量也就变成了64512与目的地址数量的乘积,在理论上已经接近无限个了。

7      小结

虽然NAT可以解决IP地址空间不足,也可以很好地隐藏内部网络的拓扑结构,使网络更安全。但是它毕竟修改了报文的内容,随着应用场景的不断增多,相信还有很多需要NAT进行特殊处理的地方,这些地方有待于我们继续挖掘、探讨,使得NAT技术更加完善。

转载地址:http://peqfb.baihongyu.com/

你可能感兴趣的文章
(三)alin’s mysql学习笔记----常用的join连接查询
查看>>
(四)alin’s mysql学习笔记----索引简介
查看>>
分布式系统中的幂等性的理解
查看>>
spring的注解开发中的常用注解(一)------@bean @Configuration @ComponentScan @Import @Scope @Lazy
查看>>
(五)alin’s mysql学习笔记----索引性能分析
查看>>
Spring中使用@Transactional注解进行事务管理的时候只有应用到 public 方法才有效
查看>>
springboot整合rabbitmq及rabbitmq的简单入门
查看>>
mysql事务和隔离级别笔记
查看>>
事务的传播属性(有坑点)自调用失效学习笔记
查看>>
REDIS缓存穿透,缓存击穿,缓存雪崩原因+解决方案
查看>>
动态代理实现AOP
查看>>
23种常见的java设计模式
查看>>
关于被final修饰的基本数据类型一些注意事项
查看>>
java Thread中,run方法和start方法的区别
查看>>
在 XML 中有 5 个预定义的实体引用
查看>>
XML 元素是可扩展的
查看>>
避免 XML 属性?针对元数据的 XML 属性
查看>>
XML DOM nodeType 属性值代表的意思
查看>>
JSP相关知识
查看>>
JDBC的基本知识
查看>>