走近科学:带你解密“映射报文”失踪之谜 | 运维实战家

2020-06-02 15:50:03

来源:MOUU网络

作者:old wolf

大家好,我是 “老狼”,曾经也算文艺青年一枚。无奈,一入IT深似海,只是一个转身,就完成了从文艺青年到IT狗的华丽变身。

言归正传,今天要和大家分享的内容是关于一个端口映射问题真实案例,我们知道端口映射不成功问题经常遇到,这次为了正经且系统带引大家学习映射问题排查,我将通过引入身边一个真实案例对话,层层深入剖析映射问题症结,希望能给大家提供一些启示及帮助。

Ok,话不多说,我们开始吧。

一、什么场景会用到端口映射——情景

为了讲清问题,我们有必要提前了解一下什么场景会用到端口映射及几个基础概念。

首先是NAT(Network Address Translation)全称网络地址转换。详细概念介绍建议百度。简单来讲就是在持有私网地址的主机想和公网的地址通信的时候需要使用到的公网和私网的地址互换的技术。我们都知道IPv4路由是区分公网地址和私网地址的,私网地址在公网是没有路由的,那这个时候拥有私网地址的主机想要和公网的主机通信,这个技术是必不可少的。

其次是端口映射

图(1)

如上图所示,PC位于外网,某服务器(如web服务器)位于内网。但由于IP地址已经耗尽的问题,整个网络只分配了一个外网IP地址。出口路由器属于内网,用于连接外网。PC要访问到内网的服务器,需要在出口路由器上开启NAPT(端口映射)功能,即针对web服务提供的端口进行端口映射。

端口映射其实就是一种内网服务器对外开放的一种网络地址转换,其实转换的原理就是当访问公网某个地址的某个端口的时候由NAT设备将目的地址转换为要访问的内网服务器的地址,并转发给内网服务器,等待内网服务器报文返回到对应的接口的时候再根据之前的会话转换回之前的报文。

二、迷失的映射报文

话说前些天五一小假期,小王好容易借着疫情常态化的契机出去踏个青,晚上回来累的不行,早早的洗洗就睡了。结果半夜一点多睡的正香的时候就被好机油(小李)的电话吵醒了,于是有了下面对话……

图(2)

此时的小王睡意完全没了,你割接苦逼也就罢了,拉着我一起苦逼你就是犯罪了。我这小暴脾气啊。当时我就开喷了:咱俩谁跟谁啊,别客气。用的什么设备啊?具体情况和我说下。

三、迷失的映射报文——还原现场

原来现场用一台EG做出口,对内就是核心交换—汇聚—接入—服务器啦,中间还串了一台防火墙!不过安全策略全放通,直接用接口地址映射内网的服务器。

图(3)

好机油说这个映射配置肯定是没问题,这种配置他配过很多遍,而且在内网测试过服务器业务,是正常的啊。内部的服务器也可以直接上公网,但是就是无法成功通过公网地址访问到内部服务器。

就这啊,机油别怕,so  easy ,来吧,让我们一步一步work it out!

哈哈,听到这里,小王放肆的笑了

哎呦我去,这自信的,突然闪了老子的腰。险些装逼失败,没关系,next,老纸要放大招了。

四、迷失的映射报文——破迷

下面我们对收集这几个信息详细解读下,看看他们作用是什么:

首先先稍微解释下,收集两个命令作用:

1.先show ip fpm modules | i FLOW-AUDIT—用来查看流量审计的业务号(左侧第一列,如本案例为10)

2.show ip fpm pri filter 10 0 x.x.x.x(访问外网ip) 32 0.0.0.0 32—用来收集数据包选路路径是否正确(如从WAN口接口到数据包后是否从正确LAN口转发,来回转发路径是否正确)

3.show ip fpm flow filter 0 x.x.x.x(访问外网ip) 32 0.0.0.0 32—用来收集数据包流表信息是否正常做了端口转换及转换后数据收发是否正常(一般如果正确转换的话在流信息会有转换记录)

Ok,那么我们接下来看看现场收集回来信息:

1.首先我们可以看到:外网访问的终端ip(即218.106.154.158)访问映射接口ip(58.x.x.59)时候,数据包转发来回路径确实没问题,从WAN3口进,LAN-Te0/0出,回程数据流也没问题,如下图:

图(5)

2.外网触发访问时候,访问的目的地址(即WAN3口的ip),设备确实正确做了转换(看括号里面地址是内部服务器要映射地址),但这里数据收发确实也有点问题(看send和rec列,多次show结果数据未有明显上涨),如下:

图(6)

以上两点测试可以得出:EG的端口映射配置没有问题,服务器页面没有问题,EG上数据转发没有问题,现象是有点奇怪,继续看看报文:

1.在服务器端抓包,能看到正常的http GET报文到达到服务器:

图(7)

不过服务器端收到get报文之后,收到一个rst的重置连接报文,导致http连接终止。

2.在EG端抓包,也能看到报文正常到达EG,并且正常转换之后转发给内网服务器:

图(8)

从这里看RST报文都是访问服务器的终端发起来的,如果是正常的交互过程不会有rst的报文。

从抓包结果:怀疑是中间运营商设备抑制行为导致回应RST异常报文。

五、迷失的映射报文——解密

为了证明确实是运营商所为,给小李一个交代,小王赶紧从打开电脑在本地电脑终端访问抓了个包,结果发现电脑发起GET报文之后,又收到一个由映射的外网服务器发来的一个RST报文!哈哈,果然问题出在这里,赶紧给小李解释了整个过程,建议联系运营商协助排查!

小李持着怀疑的态度,又做了一个操作:将电脑模拟运营商环境,配置成外网网关地址,充当外网线路进行访问,是可以正常访问,至此基本确认是运营商抑制行为所致。小李赶紧联系运营商更换了个外网地址后,一试果然好了,连连和小王道谢,说这次不但问题解决了,还理清了映射问题的排查思路,最后还非要请小王吃烧烤呢。

六、案例经验总结

对此类故障的排查除了关注配置,更换端口及确认现场网络环境以外,很重要是要先弄清楚数据转发路径,多思考数据的走向,可能遇到的问题,必要时候结合抓包定位分析,一步步排查,从最基本的开始,不放过一个可能的原因。

通用排查思路如下:

七、背后技术原理

1、流表:

-EG/NPE设备底层的一张表,存储设备接收以及转发的数据流信息。流表可以记录数据流的源目的地址、源目的端口、发送和接收的字节数、是否做了NAT、NAT前后IP、端口的变化等信息。

-流表是EG/NPE设备中非常重要的一张表,数据处理时优先使用到这张表中已有的数据流信息,同时所有的数据转发的基本信息都会存储到这张表中。

命令:

show ip fpm flow filter 0(协议,0表示任意) SrcAddr(源ip) 掩码 DstAddr (目的ip) 掩码(推荐用此种方式查看) 

show ip fpm flow | include x.x.x.x(过滤的ip地址) -- 10.x/11.x通用(不推荐,流表太大可能会导致CPU高)

举例说明各个字段含义:

–Pr(协议):如6是TCP,17是UDP;

–SrcAddr(源地址):发起数据包的地址,括号内的地址为NAT后的地址;

–DstAddr(目的地址):数据包的目的地址,括号内的地址为nat后的地址

–SrcPort(源端口):发起数据包的源端口信息,括号内为nat后的端口

–DstPort(目的端口):发起数据包的目的端口信息,括号内为nat后的端口

–Vrf:EG只有一个VRF数据都是在VRF0,可以不看;

–SendBytes(发送):以内网用户来看就是内网用户从内网发送到EG设备的数据包总的大小,字节为单位;

–RecvBytes(接收):以内网用户来看就是EG设备上收到外网发到这个内网IP的数据包的总的大小,字节为单位;

–St(流当前状态):流的状态要对应于当前的协议。不同协议含义不一样,举例说明如下:

如协议号:17   udp流

CLOSED                  0               连接处于关闭状态

STARTED                 1               连接发起状态

CONNECTED               2               对方响应之后的状态

ESTABLISHED             3               在对方响应之后连接发起方又有发送报文

 

如协议号:1    icmp流

CLOSED                 0                连接处于关闭状态

STARTED                1                连接发起状态

CONNECTED              2                对方响应之后的状态

–srcif(源接口号):代表数据从那个接口收到,show interface可以看到接口的编号对应那个接口如下,举例:

流表中srcif对应9,如show interface可以看到9代表TenGigabitEthernet 0/0,10.x无此功能, 接口显示“fff”代表设备自己发送的数据,或者是设备接收并处理的数据或者是某个方向上面未收到报文的初始值;

–================= TenGigabitEthernet 0/0 ========================

–  Index(dec):9 (hex):9

–dstif(目的接口号):代表数据从那个接口转发;

–ctrl_flag(流控制字段):无实际意义研发调试使用

–说明:接口显示“fff”代表设备自己发送的数据,或者是设备接收并处理的数据,举例说明:

上面红色方框内的流设为流1和流2:

流1:设备自己发送给114.114.114.114的DNS解析报文,因设备自己主动发送这个报文,设备认为源端口是自己,显示为“fff”

流2:10.112(实验室APM设备)向EG发送SNMP报文,因设备接收此报文并直接处理,设备直接就处理这个数据,不需要再通过任何接口转发,目的端口显示为“fff” 

对于流表上最前面两条流,属于组播数据,接口显示为“fff”也是表示本接收或发送,如源接口是6、目标接口是fff,表示是数据从编号6接口收到,设备本地接收;

2、私有空间:

- 除流表之外,EG/NPE底层还开辟了部分空间,用于存储数据流处理过程中除流表外更详细的一些信息,如应用识别情况、流控匹配情况等。这部分空间实际上存在,但对于用户而言是透明的,因此被称为设备的私有空间。私有空间在设备中被分成若干块,每块记录不同的数据处理内容,并通过私有空间ID进行区分;

- 在EG/NPE 10.x平台上,因产品限制,私有空间ID和实际存储的数据内容不是一一对应,需要根据版本进行区分;在EG 11.x平台上,所有私有空间ID是固定的。

命令:

–Show ip fpm mudule(确定选路结果对应的私有空间ID,不同型号可能不一样,以具体show结果为准)

–show ip fp pri filter x(私有空间ID,可通过show ip fpm module查看,如1表示查看数据流选路方式,10表示数据转发路径,13表示流控匹配等等) 0(协议,0表示任意) SrcAddr(源ip) 掩码 DstAddr (目的ip) 掩码

示例1:查看数据选路方式

•命令:

–show ip fp pri 1  | include x.x.x.x(过滤的ip地址)或show ip fpm pri filter 1 0(0代表任意协议) x.x.x.x(x.x.x.x这里代表源ip) 32(掩码32代表主机ip) y.y.y.y(y.y.y.y这里代表目的ip) 32(掩码32代表主机ip)   -- 10.x/11.x通用,查看选路方式

•需要关注的字段含义如下:

–Ref_ip/rpl表示数据通过什么选路方式走的,如ref_ip代表普通路由选路,rpl代表源进源出, pbr代表策略路由,mllb表示多链路负载均衡,dns_proxy代表正向dns代理,app_route代表应用路由等,unknown说明未匹配选路,一般到本地或被丢弃;

–ref_ip(7)/rpl(1) :前面是正向流代表出方向,后面是反向流代表入方向 , 括号里面数字表示对应代码,只是表示顺序而已,这里7表示选路出去的路径,1则表示到内网的路径,如1:ref/4:rpl/5:dns/6:app_route

–25/3747,前面是数据流出方向接口索引id(出接口),后面是数据流入方向接口索引id(入接口),可通过命令show ip ref adj或show ip ref route确定实际流出入接口,如上图所示,该流出接口为Te0/1,入接口为Gi0/0。

示例2:确定选路转发路径匹配情况(11.x)

•命令:

–show ip fpm module找到对应的索引id和name(左边前两列,如本例10为数据转发路径),然后通过命令show ip fpm priv xx(module id)| include x.x.x.x(过滤具体ip)或show ip fpm pri filter 10 0(0代表任意协议) x.x.x.x(x.x.x.x这里代表源ip) 32(掩码32代表主机ip) y.y.y.y(y.y.y.y这里代表目的ip) 32(掩码32代表主机ip)

说明:需要注意的是这里的module id是动态的,以实际show结果为准。

•各需要关注的字段含义如下:

–Ori:srcif-dif(源-目的接口号):代表原始数据流从源接口(Gi0/3)收到,往目的接口(Gi0/4)转发出去;

–Rep:srcif-dif(源-目的接口号):代表回程数据流从源接口(Gi0/4)收到,往目的接口(Gi0/3)转发出去;

–Up_if:出接口

写在最后

目前遇到的外网无法访问映射服务器的故障,基本上这一套“组合拳”下来,大部分的映射问题都可以解决啦。伴着好机油的道谢和烧烤到手,本来这一波分享就结束了,但是最后还是友情奉送下史上最全故障排查“杀手锏”:

索取“此产品”的详细资料,请留言
  • *姓名:
  • *手机:
  • *邮寄地址:
<