TCP 头格式
![](https://img.haomeiwen.com/i12979420/82d1f5e9ab7c8847.png)
![](https://img.haomeiwen.com/i12979420/cfef51eab0a8dd81.png)
关于 PAWS 机制
TCP PAWS(Protect Against Wrapped Sequences)机制是一种用于保护TCP连接免受回环序列攻击(Sequence Number Attacks)的机制。
回环序列攻击是一种利用TCP序列号回绕的攻击方式,攻击者可以通过发送具有旧TCP序列号的伪造数据包来欺骗TCP连接,进而实现各种恶意攻击。
TCP PAWS机制的基本思想是在TCP报文中引入时间戳选项(Timestamp Option),用于标识TCP报文的时间戳和序列号的对应关系。具体来说,TCP PAWS机制要求TCP报文的时间戳必须满足以下两个条件:
-
TCP报文的时间戳必须是单调递增的,即后面的报文时间戳必须大于前面的报文时间戳。
-
TCP报文的时间戳必须与序列号有对应关系,即时间戳必须与序列号一起用于标识数据流中的每个字节。
通过满足这两个条件,TCP PAWS机制可以保证TCP连接不受回环序列攻击的影响。
具体来说,当接收到一个TCP报文时,接收方会首先检查报文中的时间戳和序列号是否满足上述两个条件。
如果满足,那么这个报文就是合法的,可以被接受。否则,这个报文就是非法的,应该被丢弃。
需要注意的是,TCP PAWS机制并不能完全防止回环序列攻击。
攻击者仍然有可能通过一些手段来绕过TCP PAWS机制,从而实现攻击。
因此,在实际应用中,TCP PAWS机制只能作为一种辅助手段,不能完全替代其他安全机制。
开启 TCP Timestamp Option 还有什么其他作用?
开启TCP Timestamp Option除了可以用于PAWS机制保护TCP连接免受回环序列攻击之外,还有以下几个作用:
-
改善网络性能:TCP Timestamp Option可以用于计算往返时间(RTT),从而提高TCP连接的性能。通过计算RTT,TCP协议可以调整拥塞窗口大小和超时时间,从而避免网络拥塞和丢包,提高数据传输的效率。
-
提高TCP连接的稳定性:TCP Timestamp Option可以用于检测重复数据包和失序数据包。通过比较时间戳和序列号,TCP协议可以判断数据包是否是重复数据包或者失序数据包,从而保证TCP连接的稳定性和可靠性。
-
支持更高的带宽:TCP Timestamp Option可以用于支持更高的带宽。在高速网络中,TCP协议的性能通常会受到时间戳回绕的影响。通过开启TCP Timestamp Option,TCP协议可以更准确地计算时间戳,从而提高TCP连接的性能和稳定性。
需要注意的是,开启TCP Timestamp Option会增加TCP报文的长度,从而增加网络传输的负担。
因此,在实际应用中,需要根据具体情况来确定是否开启TCP Timestamp Option,以达到最优的网络性能和稳定性。
什么是 PAWS 机制?
tcp_timestamps 选项开启之后, PAWS 机制会自动开启,它的作用是防止 TCP 包中的序列号发生绕回。
正常来说每个 TCP 包都会有自己唯一的 SEQ,出现 TCP 数据包重传的时候会复用 SEQ 号,这样接收方能通过 SEQ 号来判断数据包的唯一性,也能在重复收到某个数据包的时候判断数据是不是重传的。但是 TCP 这个 SEQ 号是有限的,一共 32 bit,SEQ 开始是递增,溢出之后从 0 开始再次依次递增。
所以当 SEQ 号出现溢出后单纯通过 SEQ 号无法标识数据包的唯一性,某个数据包延迟或因重发而延迟时可能导致连接传递的数据被破坏,比如:
![](https://img.haomeiwen.com/i12979420/3dfb6b4f0757cbd3.png)
上图 A 数据包出现了重传,并在 SEQ 号耗尽再次从 A 递增时,第一次发的 A 数据包延迟到达了 Server,这种情况下如果没有别的机制来保证,Server 会认为延迟到达的 A 数据包是正确的而接收,反而是将正常的第三次发的 SEQ 为 A 的数据包丢弃,造成数据传输错误。
PAWS 就是为了避免这个问题而产生的,在开启 tcp_timestamps 选项情况下,一台机器发的所有 TCP 包都会带上发送时的时间戳,PAWS 要求连接双方维护最近一次收到的数据包的时间戳(Recent TSval),每收到一个新数据包都会读取数据包中的时间戳值跟 Recent TSval 值做比较,如果发现收到的数据包中时间戳不是递增的,则表示该数据包是过期的,就会直接丢弃这个数据包。
对于上面图中的例子有了 PAWS 机制就能做到在收到 Delay 到达的 A 号数据包时,识别出它是个过期的数据包而将其丢掉。
什么是 per-host 的 PAWS 机制呢?
开启 tcp_tw_recycle 参数,并且在 NAT 环境下,造成 SYN 报文被丢弃。
前面我提到,开启了 recycle 和 timestamps 选项,就会开启一种叫 per-host 的 PAWS 机制。
per-host 是对「对端 IP 做 PAWS 检查」,而非对「IP + 端口」四元组做 PAWS 检查。
但是如果客户端网络环境是用了 NAT 网关,那么客户端环境的每一台机器通过 NAT 网关后,都会是相同的 IP 地址,在服务端看来,就好像只是在跟一个客户端打交道一样,无法区分出来。
Per-host PAWS 机制利用TCP option里的 timestamp 字段的增长来判断串扰数据,而 timestamp 是根据客户端各自的 CPU tick 得出的值。
当客户端 A 通过 NAT 网关和服务器建立 TCP 连接,然后服务器主动关闭并且快速回收 TIME-WAIT 状态的连接后,客户端 B 也通过 NAT 网关和服务器建立 TCP 连接,注意客户端 A 和 客户端 B 因为经过相同的 NAT 网关,所以是用相同的 IP 地址与服务端建立 TCP 连接,如果客户端 B 的 timestamp 比 客户端 A 的 timestamp 小,那么由于服务端的 per-host 的 PAWS 机制的作用,服务端就会丢弃客户端主机 B 发来的 SYN 包。
因此,tcp_tw_recycle 在使用了 NAT 的网络下是存在问题的,如果它是对 TCP 四元组做 PAWS 检查,而不是对「相同的 IP 做 PAWS 检查」,那么就不会存在这个问题了。
网上很多博客都说开启 tcp_tw_recycle 参数来优化 TCP,我信你个鬼,糟老头坏的很!
tcp_tw_recycle 在 Linux 4.12 版本后,直接取消了这一参数。
TCP timestamp 时间参照是什么?
TCP timestamp option中的时间参考是每个TCP实体的本地时钟。
每个TCP实体都有自己的本地时钟,通过timestamp option,TCP报文中可以携带发送端的本地时钟值,接收端可以根据这个值来计算RTT和确认报文的有效性。
因此,TCP timestamp option并不依赖于全局时钟参考,而是依赖于每个TCP实体的本地时钟。
TCP timestamp option中的时间参考是每个TCP实体的本地时钟,跟服务器时间没有直接的关系。
TCP实体包括客户端和服务器端,每个实体都有自己的本地时钟。
在TCP连接建立时,客户端和服务器端会通过timestamp option交换彼此的本地时钟值,以便双方可以根据这些值来计算RTT和确认报文的有效性。
因此,TCP timestamp option的时间参考是基于每个TCP实体的本地时钟,而不是基于服务器时间。
TCP实体的本地时钟指的是每个TCP实体(包括客户端和服务器端)内部维护的一个计时器,用于计算时间间隔。这个计时器可以基于本地硬件时钟或者软件计时器来实现。
TCP实体的本地时钟一般都是一个单调递增的计时器,用于计算时间间隔和记录时间戳。
在TCP连接建立时,客户端和服务器端会通过TCP timestamp option交换彼此的本地时钟值,以便双方可以根据这些值来计算RTT和确认报文的有效性。
客户端发送的TCP报文中会携带一个Timestamp Value字段,这个字段记录了客户端本地时钟的当前值。服务器端接收到这个报文后会记录下客户端的本地时钟值,并在后续的报文中返回一个自己的Timestamp Value字段,表示服务器端的本地时钟值。
通过比较两个Timestamp Value字段的值,客户端和服务器端可以计算出TCP报文的往返时间(RTT),进而调整超时时间和重传策略,以保证TCP连接的可靠性和稳定性。
因此,TCP实体的本地时钟是TCP协议中非常重要的一个组成部分,它直接影响到TCP连接的性能和可靠性。
参考
SYN 包在什么场景下会被丢弃?
https://www.cnblogs.com/xiaolincoding/p/15710376.html
35 张图解:被问千百遍的 TCP 三次握手和四次挥手面试题
https://www.cnblogs.com/xiaolincoding/p/12638546.html
网友评论