TCP连接不止用TCP协议沟通

1、如果服务端不想接受这次握手,它会怎么做呢?可能会出现这么几种情况:

  • 不搭理这次连接,就当什么都没收到,什么都没发生。这种行为,也可以说是“装聋作哑”。
  • 给予回复,明确拒绝。相当于有人伸手过来想握手,你一巴掌拍掉,真的是非常刚了。

第一种情况,因为服务端做了“静默丢包”,也就是虽然收到了 SYN,但是它直接丢弃了,也不给客户端回复任何消息。这也导致了一个问题,就是客户端无法分清楚这个 SYN 到底是下面哪种情况:

  1. 在网络上丢失了,服务端收不到,自然不会有回复;
  2. 对端收到了但没回,就是刚才说的“静默丢包”;
  3. 对端收到了也回了,但这个回包在网络中丢了。

在这里插入图片描述

2、测试

第一步,在服务端,执行下面的这条命令,让 Iptables 静默丢弃掉发往自己 80 端口的数据包:

Iptables -I INPUT -p tcp --dport 80 -j DROP

第二步,在客户端启动 tcpdump 抓包:

sudo tcpdump -i any -w telnet-80.pcap port 80

第三步,从客户端发起一次 telnet:

telnet 服务端IP 80

在这里插入图片描述
telnet 挂起的原因就在这里:握手请求一直没成功。客户端一共有 7 个 SYN 包发出,或者说,除了第一次 SYN,后续还有 6 次重试。客户端当然也不是“傻子”,这么多次都失败,就放弃了连接尝试,把失败的消息传递给了用户空间程序,然后就是 telnet 退出。

TCP 握手没响应的话,操作系统会做重试

在 Linux 中,这个设置是由内核参数 net.ipv4.tcp_syn_retries 控制的,默认值为 6

$ sudo sysctl net.ipv4.tcp_syn_retries
net.ipv4.tcp_syn_retries = 6

REJECT,这应该能让客户端立刻退出了。执行下面的这条命令,让 Iptables 拒绝发到 80 端口的数据包:

Iptables -I INPUT -p tcp --dport 80 -j REJECT

此时telnet会立即退出
在这里插入图片描述
查看iptables规则发现它自动补上了–reject-with icmp-port-unreachable,也就是说确实用 ICMP 消息做了回复。当然,你还可以把这个动作定义为–reject-with tcp-reset,那样的话就符合我们一开始的期望了。
在这里插入图片描述

sudo tcpdump -i any -w telnet-80-reject.pcap host 47.94.129.219 and port 80

配置iptables将端口Reset

iptables -I INPUT -p tcp --dport 80  -j REJECT --reject-with tcp-reset

3、TCP握手流程图

在这里插入图片描述
在上面这张图里,无论是客户端或者服务端,我们从上往下看,它要经历的各个 TCP 状态,都展示得十分清楚。我把这个过程解读如下:
在这里插入图片描述
SYN_SENT 这个状态,意味着当时这个连接请求(SYN 包),已经从这台 Windows 服务器发出,试图跟远端的 AD 域控制器进行连接。但由于对端迟迟没有回应 SYN+ACK 报文,那么客户端这个连接的状态,就只能“停留”在 SYN_SENT 状态,无法转化为 ESTABLISHED 状态。

猜你喜欢

转载自blog.csdn.net/weixin_43883625/article/details/125190512
今日推荐