一文教会实战网络抓包和分析包( 五 )


文章插图
 
从图中可以发现:
 

  • 客户端发起 SYN 后 , 由于防火墙屏蔽了服务端的所有数据包 , 所以 curl 是无法收到服务端的 SYN、ACK 包 , 当发生超时后 , 就会重传 SYN 包
  • 服务端收到客户的 SYN 包后 , 就会回 SYN、ACK 包 , 但是客户端一直没有回 ACK , 服务端在超时后 , 重传了 SYN、ACK 包 , 接着一会 , 客户端超时重传的 SYN 包又抵达了服务端 , 服务端收到后 , 然后回了 SYN、ACK 包 , 但是SYN、ACK包的重传定时器并没有重置 , 还持续在重传 , 因为第二次握手在没收到第三次握手的 ACK 确认报文时 , 就会重传到最大次数 。
  • 最后 , 客户端 SYN 超时重传次数达到了 5 次(tcp_syn_retries 默认值 5 次) , 就不再继续发送 SYN 包了 。
 
所以 , 我们可以发现 , 当第二次握手的 SYN、ACK 丢包时 , 客户端会超时重发 SYN 包 , 服务端也会超时重传 SYN、ACK 包 。
 
咦?客户端设置了防火墙 , 屏蔽了服务端的网络包 , 为什么 tcpdump 还能抓到服务端的网络包?
 
添加 iptables 限制后 ,  tcpdump 是否能抓到包  , 这要看添加的 iptables 限制条件:
 
  • 如果添加的是 INPUT 规则 , 则可以抓得到包
  • 如果添加的是 OUTPUT 规则 , 则抓不到包
 
网络包进入主机后的顺序如下:
 
  • 进来的顺序 Wire -> NIC ->tcpdump -> netfilter/iptables
  • 出去的顺序iptables -> tcpdump-> NIC -> Wire
tcp_syn_retries 是限制 SYN 重传次数 , 那第二次握手 SYN、ACK 限制最大重传次数是多少?
 
TCP 第二次握手 SYN、ACK 包的最大重传次数是通过 tcp_synack_retries 内核参数限制的 , 其默认值如下:
$ cat /proc/sys/net/ipv4/tcp_synack_retries 5
是的 , TCP 第二次握手 SYN、ACK 包的最大重传次数默认值是 5 次 。
为了验证 SYN、ACK 包最大重传次数是 5 次 , 我们继续做下实验 , 我们先把客户端的 tcp_syn_retries 设置为 1 , 表示客户端 SYN 最大超时次数是 1 次 , 目的是为了防止多次重传 SYN , 把服务端 SYN、ACK 超时定时器重置 。
接着 , 还是如上面的步骤:
 
  1. 客户端配置防火墙屏蔽服务端的数据包
  2. 客户端 tcpdump 抓取 curl 执行时的数据包
 
把抓取的数据包 , 用 Wireshark 打开分析 , 显示的时序图如下:
一文教会实战网络抓包和分析包

文章插图
 
从上图 , 我们可以分析出:
 
  • 客户端的 SYN 只超时重传了 1 次 , 因为 tcp_syn_retries 值为 1
  • 服务端应答了客户端超时重传的 SYN 包后 , 由于一直收不到客户端的 ACK 包 , 所以服务端一直在超时重传 SYN、ACK 包 , 每次的 RTO 也是指数上涨的 , 一共超时重传了 5 次 , 因为 tcp_synack_retries 值为 5
 
接着 , 我把tcp_synack_retries 设置为 2 , tcp_syn_retries 依然设置为 1:
$ echo 2 > /proc/sys/net/ipv4/tcp_synack_retries $ echo 1 > /proc/sys/net/ipv4/tcp_syn_retries
依然保持一样的实验步骤进行操作 , 接着把抓取的数据包 , 用 Wireshark 打开分析 , 显示的时序图如下:
一文教会实战网络抓包和分析包

文章插图
 
可见:
 
  • 客户端的 SYN 包只超时重传了 1 次 , 符合 tcp_syn_retries 设置的值;
  • 服务端的 SYN、ACK 超时重传了 2 次 , 符合 tcp_synack_retries 设置的值
实验二的实验小结


推荐阅读