欢迎关注:1,欢迎关注本博客,你可点击右手边的【QQ邮件订阅】订阅本博客!2,本博客推出江湖救急计划,主要为工作中遇到疑难杂症的兄弟提供远程技术支持和分析,如有需要,请在江湖救急计划页面给我留言!

TCP MSS与PMTUD

作者:易隐者 发布于:2012-9-6 19:16 Thursday 分类:网络分析

 

       一旦DF位置一,将不允许中间设备对该报文进行分片,那么在遇到IP报文长度超过中间设备转发接口的MTU值时,该IP报文将会被中间设备丢弃。在丢弃之后,中间设备会向发送方发送ICMP差错报文。
为了简单直观的展示这个交互的过程,我做了下面这个图示: 

点击查看原图


       我找了一个实际环境下捕获的ICMP需要分片但DF位置一的差错报文,下图为其解码格式: 

点击查看原图


       我们可以看到其差错类型为3,代码为4,并且告知了下一跳的MTU值为1478。在ICMP差错报文里封装导致此差错的原始IP报文的报头(包含IP报头和四层报头)。

       一旦出现这种因DF位置一而引起丢包,如果客户端无法正常处理的话,将会导致业务应用出现异常,外在表现为页面无法打开、页面打开不全、某些大文件无法传输等等,这将严重影响业务的正常运行。
那么客户端如何处理这种状况呢?
TCP主要通过两种方式来应对:
1, 协商MSS,在交互之前避免分片的产生
2, 路径MTU发现(PMTUD)

TCP MSS

       TCP在三次握手建立连接过程中,会在SYN报文中使用MSS(Maximum Segment Size)选项功能,协商交互双方能够接收的最大段长MSS值。
       MSS是传输层TCP协议范畴内的概念,顾名思义,其标识TCP能够承载的最大的应用数据段长度,因此,MSS=MTU-20字节TCP报头-20字节IP报头,那么在以太网环境下,MSS值一般就是1500-20-20=1460字节。
客户端与服务器端分别根据自己发包接口的MTU值计算出相应MSS值,并通过SYN报文告知对方,我们还是通过一个实际环境中捕获的数据报文来看一下MSS协商的过程:

点击查看原图

       这是整个报文交互过程的截图,我们再来看一下客户端的报文详细解码: 

点击查看原图

       上图为客户端的SYN报文,在其TCP选项字段,我们可以看到其通告的MSS值为1460;我们在看看服务器端的SYN/ACK报文解码: 

点击查看原图


       上图为服务器端给客户端回应的SYN/ACK报文,查看其TCP选项字段,我们可以发现其通告的MSS值为1440。

       交互双方会以双方通告的MSS值中取最小值作为发送报文的最大段长。在此TCP连接后续的交互过程中,我们可以清楚的看到服务器端向客户端发送的报文中,TCP的最大段长度都是1440字节,如下图解码所示:

点击查看原图

       通过在TCP连接之初,协商MSS值巧妙的解决了避免端系统分片的问题,但是在复杂的实际网络环境下,影响到IP报文分片的并不仅仅是发送方和接收方,还有路由器、防火墙等中间系统,假设在下图的网络环境下: 

点击查看原图

       中间路径上的MTU问题,端系统并不知道,因此需要一个告知的机制,这个机制就是路径MTU发现(PMTUD: Path MTU Discovery )!

PMTUD

       说起PMTUD,我们必须在此回到上面讲到的ICMP需要分片但DF位置一差错报文,还记得那个ICMP差错报文中有一个字段是告知下一跳的MTU值的吗?PMTUD正是利用ICMP需要分片但DF位置一差错报文的这一特性来实现的。
       发送方在接收到该差错报文后,会根据该报文给出的下一跳的MTU值计算适合传输的最大段长度,从而在后续的发送报文过程中,避免在中间路径被分片的情况产生。
       这在端系统主要是通过在路由表里临时添加目的主机路由并将ICMP差错报文告知的下一跳MTU值跟该主机路由关联起来来实现。
       PMTUD的确是个非常不错的机制,但是在复杂的实际网络环境中,有时候会失效,因为为了安全起见,有些网络管理员会在路由器、防火墙等中间设备上设置过滤ICMP报文的安全策略,这将导致ICMP差错报文被这些中间设备丢弃,无法达到发送方,从而引起PMTUD的失效,网上有个宫一鸣前辈共享的案例——《错误的网络访问控制策略导致PMTUD 实现故障一例》,该案例正是说明这种情况绝好的例子,大家可以自行百度此文档学习参考。

       值得一提的是PMTUD仅TCP支持,UDP并不支持PMTUD。

       由于PMTUD可能存在ICMP差错报文被过滤的情况,很多中间设备的接口支持adjust tcp mss设置功能,思科路由器一般是在接口模式下使用命令“ip tcp adjust-mss 1400 ”来做设置,其他的品牌产品的相关设置大家可在实际工作环境下自查相关品牌和产品的使用手册。

        这个功能主要是通过由中间设备修改经过其转发的TCP SYN报文中的MSS值,让中间设备参与进TCP 三次握手时SYN报文的MSS协商来避免分片。

       需要注意的是,该功能不像MTU值,只针对出接口,此功能一旦开启,其将针对该接口的收发双向有效。
我做一个简化环境下的工作过程图示以便于大家理解其工作过程:

点击查看原图

阅读全文>>

标签: TCP icmp差错 分片 SYN TCP选项 UDP MTU ICMP PMTUD MSS

评论(4) 引用(0) 浏览(27933)

IP分片(IP Fragment)

作者:易隐者 发布于:2012-9-3 22:22 Monday 分类:网络分析

为什么要分片

       不同的链路类型能够支持的最大传输单元值(MTU: Maxitum Transmission Unit)主要是由相关RFC文档规定的,常见的以太网链路的MTU值为1500,如果需要转发的IP报文超出其转发接口的MTU值,则在转发该报文之前,需要将其分片,分为多个适合于该链路类型传输的报文,这些分片报文在到达接收方的时候,由接收方完成重组。

       各种常见链路类型的MTU值如下图所示: 

点击查看原图


报文的分片和重组

       我们先来看一下分片的过程,为了简单起见,我就用《TCPIP详解卷一》第11章《UDP:用户数据报协议》中关于IP分片的案例,应用进程将1473字节应用字段交给UDP处理,UDP加上8字节的UDP报头之后,交给IP层处理,IP层在转发之前,发现该报文长度超出转发接口的MTU,因此需要分片,分为两个IP分组,如下图所示: 

点击查看原图


       从上图可以看出原始的IP报文经过分片后,只有第一个分片报文是带有四层信息的,后续报文均不带四层信息,为做直观展示,我找了一个实际环境下抓取的分片报文,如下图所示: 

点击查看原图

       这是分片的第一个报文,我们可以看到该报文IP层封装的上层协议为ICMP协议,这是一个ping报文(上层协议信息),我们再来看一下后续分片报文的解码:

点击查看原图

       这是分片后续报文,我们能看到封装的是ICMP协议,但是封装的上层协议的具体信息就无法看到了。

       IP数据报被分片之后,所有分片报文的IP报头中的源IP、目的IP、IP标识、上层协议等信息都是一样的(TTL不一定是一样的,因为不同的分片报文可能会经过不同的路由路径达到目的端),不同的地方在于分片标志位和分片偏移量,而接收方正是根据接收到的分片报文的源IP、目的IP、 IP标识、分片标志位、分片偏移量来对接收到的分片报文进行重组

       接收方根据报文的源IP、目的IP、IP标识将接收到的分片报文归为不同原始IP数据报的分片分组;分片标志中的MF位(More Fragment)标识了是否是最后一个分片报文,如果是最后一个分片报文,则根据分片偏移量计算出各个分片报文在原始IP数据报中的位置,重组为分片前的原始IP报文。如果不是最后一个分片报文,则等待最后一个分片报文达到后完成重组。

分片带来的问题

1, 分片带来的性能消耗

       分片和重组会消耗发送方、接收方一定的CPU等资源,如果存在大量的分片报文的话,可能会造成较为严重的资源消耗;
       分片对接收方内存资源的消耗较多,因为接收方要为接收到的每个分片报文分配内存空间,以便于最后一个分片报文到达后完成重组。

2,分片丢包导致的重传问题

       如果某个分片报文在网络传输过程中丢失,那么接收方将无法完成重组,如果应用进程要求重传的话,发送方必须重传所有分片报文而不是仅重传被丢弃的那个分片报文,这种效率低下的重传行为会给端系统和网络资源带来额外的消耗。

3, 分片攻击

       黑客构造的分片报文,但是不向接收方发送最后一个分片报文,导致接收方要为所有的分片报文分配内存空间,可由于最后一个分片报文永远不会达到,接收方的内存得不到及时的释放(接收方会启动一个分片重组的定时器,在一定时间内如果无法完成重组,将向发送方发送ICMP重组超时差错报文,请大家参考本博客《ICMP重组超时》一文),只要这种攻击的分片报文发送的足够多、足够快,很容易占满接收方内存,让接收方无内存资源处理正常的业务,从而达到DOS的攻击效果。

4, 安全隐患

       由于分片只有第一个分片报文具有四层信息而其他分片没有,这给路由器、防火墙等中间设备在做访问控制策略匹配的时候带来了麻烦。
       如果路由器、防火墙等中间设备不对分片报文进行安全策略的匹配检测而直接放行IP分片报文,则有可能给接收方带来安全隐患和威胁,因为黑客可以利用这个特性,绕过路由器、防火墙的安全策略检查对接收方实施攻击;
       如果路由器、防火墙等中间设备对这些分片报文进行重组后在匹配其安全策略,那么又会对这些中间设备的资源带来极大的消耗,特别是在遇到分片攻击的时候,这些中间设备会在第一时间内消耗完其所有内存资源,从而导致全网中断的严重后果。

       基于以上原因,很多应用程序都尽量避免分片的产生,其通过将IP报文的分片标志中的DF位(Don’t Fragment)置一来实现,而这可能给应用带来一些难以预料的麻烦。下一篇我将介绍端系统如何处理这种状况,请大家关注。

分片补充

1,分片既有可能发生在端系统(发送主机)上,也可能发生在转发报文的路由器、防火墙等中间系统上
2,分片只发生在转发出接口上

跟分片有关的案例

        后续我会在本博客里添加一些跟分片有关的案例,有兴趣的同学可关注。

阅读全文>>

标签: ip分片 重组超时 IP标识 icmp差错 分片 ip fragment IPID UDP 分片攻击 分片偏移量 DF位 MF位 MTU 重组 fragment ICMP

评论(6) 引用(0) 浏览(88305)

基于UDP的应用如何保证应用数据的可靠性

作者:易隐者 发布于:2012-8-28 22:58 Tuesday 分类:网络分析

       UDP的传输效率比TCP更高一些,其在网络中交互时具有更小的延时,因为其一,发送方只要把应用字段全部交给网络层处理就行了,接收方不需要确认发送方发送的数据,发送方也没有等待接收方确认报文这些过程;其二,TCP报头一般20个字节,UDP报头只有8字节,因此UDP跟TCP相比,在同长度的IP报文中能够承载更多的有效应用数据。

       很多应用设计者和开发者正是看中了UDP的这种特性,将他们的应用程序利用UDP来实现端对端的数据交互,但是UDP不可靠,它没有TCP的确认、重传、窗口、保活等机制,那么基于UDP的应用如何保证其应用数据在交互过程的可靠性呢?答案是由基于UDP的应用程序来完成

    为此我花费了点时间找了一些基于UDP 的应用报文解码,我们一起逐一来看看吧。 

TFTP(应用层确认):  

点击查看原图

某UDP应用(应用层保活):

点击查看原图

RTP(应用层排序): 

点击查看原图

DHCP:(应用层标识) 

点击查看原图

       上次有个网友问我QQ传大文件的时候,为什么没抓到分片包文?我的回答是:应用层做了分片。虽然我并不清楚QQ文件传输协议的具体工作机制,但是其实跟我上面分析讨论的一样,QQ利用UDP传输文件,抓包的时候也看到的确是UDP的连接,但是没看到分片报文,那么原因只能是QQ应用程序为了保障传输文件的可靠性,避免在网络层被分片,应用程序在将大的应用字段交付给UDP之前,针对大的应用字段做了分片处理,这个过程跟TCP的MSS协商后做分段处理有点类似。

       现实工作环境下常见的UDP应用主要有P2P下载、视频会议、在线视频、VOIP语音、在线游戏等,有兴趣的兄弟姐妹,可以找一些工作环境中的这些应用的报文,来验证或完善一下我上述所言,如果找到的话,记得给我留言,顺便把报文给我一份。

阅读全文>>

标签: UDP 基于UDP的应用 可靠性 DHCP RTP TFTP 保活

评论(0) 引用(0) 浏览(18651)

基于UDP组播实施分片攻击的可能性

作者:易隐者 发布于:2012-8-27 18:36 Monday 分类:网络安全

        UDP是无连接的,这种特性决定了其可以通过组播或广播来进行业务数据的交付,同时我们也知道UDP不会像TCP那样将应用程序交付的大应用字段划分为适合网络传输的数据段(segment),UDP会将大应用字段直接交付于网络层处理,那么在网络层必然会面对分片的问题。

关于应用程序、UDP、IP之间交互的过程,我做了一个图示:

点击查看原图

应用层、UDP以及IP间的交互情况图示

       大的应用字段会被网络层分片后,在网络中传输,这些分片报文会在接收端的网络层重组后,提交给UDP和应用程序。

       我们接下来再来看一下协议栈在各层对数据帧/数据报的过滤过程:

点击查看原图

协议栈在各层对数据帧/数据报的过滤过程图示

       这个是根据《TCP/IP详解卷一》中的第十二章《广播和多播》总结出来的,在此不针对此图做详细描述,有兴趣的兄弟姐妹可以自行参考详解卷一第十二章相关的内容。

       我们接着来看一个实际用户工作环境下抓取的UDP 组播分片报文: 

点击查看原图

用户实际环境中的UDP多播分片报文

         因此,基于UDP组播实施分片攻击的可能性是存在

遭受这种攻击的假设场景:

       用户的某个业务(视频会议、语音、IPTV等)使用组播传输数据报文,黑客只需要构造一些永远无法重组的IP分片报文,以该业务用到的组播地址发送出去,那么所有属于这个多播组的业务主机都将会接收到这些精心构造的攻击报文,那么,可想而知这些多播组内的业务主机在处理的时候,将会出现资源耗尽以至于死机的情况,黑客从而达到拒绝服务的攻击效果。


 

阅读全文>>

标签: UDP 组播 分片攻击 多播 协议栈 拒绝服务攻击

评论(0) 引用(0) 浏览(12674)

【转】tcpdump使用手册

作者:易隐者 发布于:2012-6-16 17:35 Saturday 分类:参考资料

       Linux下使用最广泛的就是tcpdump,下面是tcpdump的使用手册:

总览 (SYNOPSIS)

tcpdump [ -adeflnNOpqStvx ] [ -c count ] [ -F file ] [ -i interface ] [ -r file ] [ -s snaplen ] [ -T type ] [ -w file ] [ expression ]  

描述 (DESCRIPTION)

Tcpdump显示网络接口上符合布尔表达式expression的报头.
对于SunOS的nit或 bpf 界面: 要运行tcpdump,你必须有/dev/nit或/dev/bpf*的读访问权限.
对于Solaris 的dlpi:你必须有网络仿真设备(network pseudo device), 如/dev/le的读访问权限
对于HP-UX的dlpi:你必须是 root, 或者把它安装成root的setuid程序.
对于IRIX的snoop: 你 必须是 root, 或者把它安装成root的setuid 程序. 对于Linux:你必须是root,或者把它安装成 root的setuid程序.
对于Ultrix和Digital UNIX: 一旦超级用户用pfconfig(8)开放了杂凑模式(promiscuous-mode),任何用户都可以运行tcpdump.
对于BSD: 你必须有/dev/bpf*的读访问权限.

选项 (OPTIONS)

-a
试着把网络和广播地址转换成名称.
-c
当收到count个报文后退出.
-d
把编译好的报文匹配模板 (packet-matching code) 翻译成可读形式,传往标准输出,然后退出.
-dd
把报文匹配模板(packet-matching code)以C程序片断的形式输出.
-ddd
把报文匹配模板(packet-matching code)以十进制数形式输出(前面加上总数).
-e
每行都显示链路层报头.
-f
用数字形式显示“外部的”互联网地址,而不是字符形式(这个选项用来绕开脑壳坏掉的SUN黄页服务器的问题——一般说来,它翻译外部网络数字地址的时候 会长期挂起).
-F
指定文件file的内容为过滤表达式. 忽略命令行上的表达式.
-i
监听interface接口.如果不指定接口,tcpdump在系统的接口清单中,寻找号码最小,已经配置好的接口(loopback除外).选中的时候会中断连接.
-l
行缓冲标准输出.可用于捕捉数据的同时查看数据. 例如,
``tcpdump  -l  |  tee dat'' or’`tcpdump  -l   > dat  &  tail  -f  dat''.
-n
不把 地址 转换成 名字 (如主机地址, 端口号等)
-N
不显示 主机名字 中的 域名 部分. 例如, 如果 使用 这个 选项, tcpdump 只显示’`nic'', 而不是’`nic.ddn.mil''.
-O
禁止运行 报文匹配模板 的 优化器. 当 怀疑 优化器 含有 bug 时, 这个选项 才有用.
-p
禁止 把 接口 置成 promiscuous 模式. 注意, 接口 有可能 因 其他原因而 处于 promiscuous 模式; 因此, '-p' 不能 作为’ether host {local-hw-addr} 或 ether broadcast' 的 简写.
-q
快速输出. 显示 较少的 协议信息, 输出行 将 短一点点.
-r
从 file 中 读入 数据报 (文件 是用 -w 选项 创建的). 如果 file 是’`-'', 就 读 标准输入.
-s
从每个 报文 中 截取 snaplen 字节的数据, 而不是 缺省的 68 (如果是 SunOS 的 NIT, 最小值是 96). 68 个字节 适用于 IP, ICMP, TCP 和 UDP, 但是 有可能 截掉 名字服务器 和 NFS 报文 的 协议 信息 (见下面). 输出时 如果指定’`[|proto]'', tcpdump 可以 指出 那些 捕捉量过小的 数据报, 这里的 proto 是 截断发生处 的 协议层 名称. 注意, 采用 更大的 捕捉范围 既增加了 处理 报文 的 时间, 又 相应的 减少了报文的 缓冲 数量, 可能 导致 报文的丢失. 你 应该 把 snaplen 设的尽量小, 只要 能够 容纳 你 需要 的 协议信息 就可以了.

-T
把 通过 "expression" 挑选出来的 报文 解释成 指定的 type. 目前 已知 的 类型 有: rpc (远程过程调用 Remote Procedure Call), rtp (实时应用协议 Real-Time Applications protocol), rtcp (实时应用控制协议 Real-Time Applications control protocol), vat (可视音频工具 Visual Audio Tool), 和 wb (分布式白板 distributed White Board).
-S
显示 绝对的, 而不是 相对的 TCP 序列号.
-t
禁止 显示 时戳标志.
-tt
显示 未格式化的 时戳标志.
-v
(稍微多一点) 繁琐的输出. 例如, 显示 IP 数据报 中的 生存周期 和 服务类型.
-vv
更繁琐的输出. 例如, 显示 NFS 应答报文 的 附加域.
-w
把 原始报文 存进 file, 不分析 也 不显示. 它们 可以 以后 用 -r 选项 显示. 如果 file 是’`-'', 就 写到 标准输出.

阅读全文>>

标签: TCP tcpdump UDP 抓包 Linux 报文

评论(0) 引用(0) 浏览(91609)

Powered by 易隐者 基于emlog 皖ICP备12002343号-1