TCP/IP之三次握手
Posted 呆呆熊的技术路
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TCP/IP之三次握手相关的知识,希望对你有一定的参考价值。
TCP 通信过程
查看 tcp 的网络连接情况
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前就可以直接发送数据;否则按照正常三次握手进行。
TFO提高性能的关键是省去了热请求的三次握手,这在充斥着小对象的移动应用场景中能够极大提升性能。
开启 tcp_fastopen
sysctl -w net.ipv4.tcp_fastopen=1
其中数字包含含义如下:
0: 关闭
1: 作为客户端时使用 TFO
2: 作为服务端时使用 TFO
3. 全部使用TFO
“因需要相关代码支持开启 TCP_FASTOPEN 选项, 所以无法正常抓nginx请求包, 此图来源于网络.
从上面的示例中可以看到 TFO 的其中一个优点就是可以提高网络的利用率,尤其是有频繁网络建立的情景,TFO 的优势尤其明显。但是,除此之外,TFO 还有一个很大的优点就是可以防止 SYN泛洪攻击。
Message Flow:
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和内存,最后服务器可能死机,就无法为正常用户提供服务了。(来源:百度百科)
“
我们观察图中, 在 server 端维护着两个队列, 分别是 syns queue 和 accept queue, 这两个队列的大小可以使用 tcp_max_syn_backlog 和 somaxconn 两个内核配置.
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 内核参数彻底了解(https://blog.csdn.net/rain_qingtian/article/details/41864589)
以上是关于TCP/IP之三次握手的主要内容,如果未能解决你的问题,请参考以下文章