TCP/IP之三次握手

TCP 通讯过程

查看 tcp 的网络链接状况nginx

netstat -anp |grep tcp
复制代码

具体三次握手

关于三次握手的优化

TCP Fast Open

TCP快速打开(TCP Fast Open,TFO)是对TCP的一种简化握手手续的拓展,用于提升两端点间链接的打开速度。简而言之,就是在TCP的三次握手过程当中传输实际有用的数据安全

三次握手的过程当中,当用户首次访问server时,发送syn包,server根据用户IP生成cookie,并与syn+ack一同发回client;client再次访问server时,在syn包携带TCP cookie;若是server校验合法,则在用户回复ack前就能够直接发送数据;不然按照正常三次握手进行。bash

TFO提升性能的关键是省去了热请求的三次握手,这在充斥着小对象的移动应用场景中可以极大提高性能。服务器

开启 tcp_fastopen

sysctl -w net.ipv4.tcp_fastopen=1

其中数字包含含义以下:
0: 关闭
1: 做为客户端时使用 TFO
2: 做为服务端时使用 TFO
3. 所有使用TFO
复制代码

因须要相关代码支持开启 TCP_FASTOPEN 选项, 因此没法正常抓nginx请求包, 此图来源于网络.cookie

从上面的示例中能够看到 TFO 的其中一个优势就是能够提升网络的利用率,尤为是有频繁网络创建的情景,TFO 的优点尤为明显。可是,除此以外,TFO 还有一个很大的优势就是能够防止 SYN泛洪攻击。网络

Message Flow:tcp

Requesting Fast Open Cookie in connection 1:

   TCP A (Client)                                      TCP B (Server)
   ______________                                      ______________
   CLOSED                                                      LISTEN

   #1 SYN-SENT ----- <SYN,CookieOpt=NIL> ----------> SYN-RCVD

   #2 ESTABLISHED <---- <SYN,ACK,CookieOpt=C> ---------- SYN-RCVD
   (caches cookie C)

   Performing TCP Fast Open in connection 2:

   TCP A (Client)                                      TCP B (Server)
   ______________                                      ______________
   CLOSED                                                      LISTEN

   #1 SYN-SENT ----- <SYN=x,CookieOpt=C,DATA_A> ----> SYN-RCVD

   #2 ESTABLISHED <---- <SYN=y,ACK=x+len(DATA_A)+1> ---- SYN-RCVD

   #3 ESTABLISHED <---- <ACK=x+len(DATA_A)+1,DATA_B>---- SYN-RCVD

   #4 ESTABLISHED ----- <ACK=y+1>--------------------> ESTABLISHED

   #5 ESTABLISHED --- <ACK=y+len(DATA_B)+1>----------> ESTABLISHED

复制代码

安全问题之如何应对 SYN 泛洪攻击

TCP SYN泛洪发生在OSI第四层,这种方式利用TCP协议的特性,就是三次握手。攻击者发送TCP SYN,SYN是TCP三次握手中的第一个数据包,而当服务器返回ACK后,该攻击者就不对其进行再确认,那这个TCP链接就处于挂起状态,也就是所谓的半链接状态,服务器收不到再确认的话,还会重复发送ACK给攻击者。这样更加会浪费服务器的资源。攻击者就对服务器发送很是大量的这种TCP链接,因为每个都无法完成三次握手,因此在服务器上,这些TCP链接会由于挂起状态而消耗CPU和内存,最后服务器可能死机,就没法为正经常使用户提供服务了。(来源:百度百科)性能

经过上图流程, 咱们发如今 SYN 中间实际上是维护了一个队列, SYN 攻击就是短期内伪造不一样 IP 地址的 SYN 报文, 快速占满 backlog 队列, 使服务不能提供正常服务.优化

咱们观察图中, 在 server 端维护着两个队列, 分别是 syns queue 和 accept queue, 这两个队列的大小可使用 tcp_max_syn_backlog 和 somaxconn 两个内核配置.spa

tcp_max_syn_backlog 是指定所能接受SYN同步包的最大客户端数量,即半链接上限
somaxconn 是指服务端所能accept即处理数据的最大客户端数量,即完成链接上限
复制代码

其中还有两个内核参数咱们常常接触:

tcp_abort_on_overflow

当 tcp 创建链接的 3 路握手完成后,将链接置入 ESTABLISHED 状态并交付给应用程序的 backlog 队列时,会检查 backlog 队列是否已满。若已满,一般行为是将链接还原至 SYN_ACK 状态,以形成 3 路握手最后的 ACK 包意外丢失假象 —— 这样在客户端等待超时后可重发 ACK —— 以再次尝试进入 ESTABLISHED 状态 —— 做为一种修复/重试机制。若是启用 tcp_abort_on_overflow 则在检查到 backlog 队列已满时,直接发 RST 包给客户端终止此链接 —— 此时客户端程序会收到 104 Connection reset by peer 错误。

tcp_syncookies

在 tcp 创建链接的 3 次握手过程当中,当服务端收到最初的 SYN 请求时,会检查应用程序的 syn_backlog 队列是否已满。若已满,一般行为是丢弃此 SYN 包。若未满,会再检查应用程序的 backlog 队列是否已满。若已满而且系统根据历史记录判断该应用程序不会较快消耗链接时,则丢弃此 SYN 包。若是启用 tcp_syncookies 则在检查到 syn_backlog 队列已满时,不丢弃该 SYN 包,而改用 syncookie 技术进行 3 次握手。 (当队列未满时, 不会使用此方式).

参考文档

文中部分图片和知识来源于网络.

部分 TCP 内核参数完全了解(blog.csdn.net/rain_qingti…)

更多精彩内容关注公众号 (呆呆熊的技术路) :

相关文章
相关标签/搜索