互联网上有很多关于NAT回流故障的分析,但大多数是模棱两可,没有从根本上给出NAT回流故障的具体原因,本文通过数据包捕获、分析数据包,结合TCP三次握手原理,详细的分析了NAT回流故障的具体原因,并给出相应的解决办法。
术语”NAT回流“,有的技术文档上又称为”NAT回环“,什么是NAT回流?举例说明或许会更加通俗易懂:
某公司有一个出口路由器连接ISP网络,在公司内部有web服务器。
公司员工在公司内部网络,使用公司网站的域名或公网IP地址(ISP的DNS服务器解析域名后,得到公司的公网IP地址),来访问公司内部的web服务器,其访问请求数据包在网络设备上的转发映射过程,就叫做”NAT回流“,如果访问请求失败,则意味着NAT回流发生故障了,这也是本文需要分析原因并加以解决的目标。
网络设备在NAT回流的过程中,将目标公网地址转换为web服务器的私有地址,然后将http访问请求数据包转发到web服务器上,这叫做”NAT映射“。
PS:
有人问,在公司内网为什么不直接使用web服务器的私有地址访问web服务器?
答,很多普通员工不知道什么是”IP地址“,只知道”网址“。如果公司内网没有架设DNS服务器,而使用ISP的DNS服务器解析域名,则解析结果为公网IP地址。
工具/原料
-
在线远程实验室网络(见之前的文章)
-
MSR5040路由器、DCR2659路由器、MSR30路由器、交换机S16、PC2、PC3
-
sniffer抓包程序、360流量防火墙
方法/步骤
-
提供实验拓扑图和说明如下:
S16(模拟内网普通交换机)
R1(MSR5040路由器,提供NAT服务)
R4(DCR2659路由器,模拟ISP网络)
R3(MSR30路由器,模拟公网用户终端)
PC2(模拟内网客户端PC,提供抓包功能)
PC3(模拟内网WEB服务器、Telnet服务器,提供抓包功能)
-
在PC3上配置WEB服务、Telnet服务、安装sniffer抓包软件。
配置WEB服务比较简单,这里配置步骤省略。
安装sniffer抓包软件比较简单,这里安装过程省略。
配置Telnet服务,这里简单配置一下(达到测试目的即可),如下列截图所示:
-
在内网PC2上测试PC3的WEB服务、Telnet服务是否正常:
-
根据实验拓扑图,配置下列网络参数,具体步骤很简单,这里省略:
配置R3、R4、R1的相关接口的IP地址;
配置R3的默认路由指向R4的G0/4(192.168.34.4);
配置R1的默认路由指向R4的G0/6(192.168.14.4);
测试R3到R1的G0/0接口的连通性(ping 192.168.14.1),确保连通性;
-
配置PC2和PC3的默认网关为:192.168.8.13。
本案例中,远程在线实验用户vpn拨号后分配的ip网段为192.168.5.0/24,为了保持远程在线实验用户持续、正常的远程登录PC2和PC3,务必确保PC2和PC3有到192.168.5.0/24、192.168.6.0/24网段的静态路由,具体原因见之前的文章:“ 远程在线网络实验室搭建”
-
下面开始配置R1的NAT服务,包括src-nat和dst-nat,并测试scr-nat
1)、配置基本acl 2000,permit 192.168.8.0/24网段
2)、在G0/0接口上配置src-nat
3)、在G0/0接口上配置nat server(即dst-nat),针对www服务(80端口)和telnet服务(23端口)进行dst-nat转换
4)、在R3上开启icmp的debug调试,在PC2上pingR3,测试src-nat是否成功
截图如下:
-
接下来开始测试外网用户(R3)对内部服务器PC3的访问。
假设PC3的域名解析结果IP地址为R1的G0/0接口地址192.168.14.1
1)、内部服务器PC3上打开360流量防火墙,检测呼入连接
2)、R1上开启nat packet debug调试输出,查看nat的状态
3)、R1关闭自身的http服务和telnet服务,避免冲突
4)、测试R3到PC3的telnet连接
5)、测试R3到PC3的http连接
具体截图如下:
-
到目前,外网用户已经可以通过PC3的公网IP来访问PC3,下面重点分析内网用户通过PC3的公网IP来访问PC3的过程,抓包分析,结合TCP三次握手原理。
-
在R1的G0/1接口配置并开启nat server(dst-nat),这样当R1在G0/1接口收到PC2针对PC3的公网IP地址的访问请求时,才能进行nat转换
且在R1上开启nat packet的debug调试输出
-
在PC2和PC3上同时启动sniffer抓包功能
在PC2上分别使用telnet和http两种方式来访问PC3的公网IP(192.168.14.1),发现访问失败
-
在PC2上停止并查看数据包,分析如下:
首先,PC2原本希望和PC3的公网IP(192.168.14.1)建立三次握手,但一直没有收到192.168.14.1的ACK,所以此连接请求失败;
其次,PC2收到了PC3的内网IP(192.168.8.203)返回的ACK,但是PC2认为自己从来没有向PC3的内网IP进行过连接请求,所以此连接请求失败;
第三,PC2向PC3发送了一个RST类型的TCP报文,PC2和PC3之间的“非法连接”被复位了(reset)
-
在R1上查看调试信息输出,分析如下:
R1在这个通信过程中,只干了一件事,就是不断的将目标IP 192.168.14.1转换为192.168.8.203,源IP 192.168.8.202保持不变,将数据包转发给192.168.8.203(PC3)
而PC3收到数据包后,PC3认为是PC2向它发送了连接请求,所以回应一个SYN ACK连接响应给PC2,且此回应包没有经过R1的转发(直接经过交换机到达PC2)
-
在PC3上停止并查看数据包,分析如下:
首先,PC3收到R1转发过来的数据包,源IP为PC2(192.168.8.202),它认为这是PC2向自己发送的TCP连接请求;
其次,PC3向PC2发送回应数据包SYN ACK;
第三,PC3期待收到PC2的SYN ACK,但事与愿违,它收到了PC2的reset包
所以,连接请求建立不成功;
-
到目前为止,NAT回流不成功的原因已经找到了,就是TCP三次握手无法完整的建立导致的。
知道深层次的原因后,自然就有解决方法了:
首先,在R1的G0/1接口配置src-nat,这样,R1转发PC2到PC3公网IP的请求时,一方面将PC3的公网IP转换为PC3的内网IP(目标地址),另一方面,将源地址(PC2的IP)转换为G0/1接口的IP(192.168.8.13)
其次,当PC3收到这个SYN请求时,回应SYN ACK包,目标为R1的G0/1接口IP,由于R1的G0/1接口同时配置了dst-nat和src-nat,所以此数据包的源IP转换为192.168.14.1(根据上一步建立的IP端口映射表),目标IP转换为192.168.8.202(根据上一步建立的IP端口映射表),R1完成转换后,从G0/1接口转发数据包给PC2
第三,PC2收到这个SYN ACK后,发现源地址为192.168.14.1,即原先SYN请求的目标地址,于是向192.168.14.1回应SYN ACK
……
以此类推,后面的通信过程是一样的。
在这里,PC2认为自己一直是和192.168.14.1通信的,而PC3则认为自己一直是和192.168.8.13进行通信的,而实际上PC2和PC3一直进行着真正的通信。
-
R1的G0/1接口同时配置src-nat和dst-nat(nat server)
-
R1的nat packet debug输出如下:
可以看出来,第一条和最后一条的源、目标IP地址以及端口号达到了一致性
-
PC2成功的和192.168.14.1建立了三次握手
PC3成功的和192.168.8.13建立了三次握手