Wireshark & Packetdrill | TCP 三次握手之 TCP Options 字段 TSOPT

admin 2024年8月5日10:20:42评论12 views字数 5751阅读19分10秒阅读模式

真正搞明白一个问题不容易

实验目的

基于 packetdrill TCP 三次握手脚本,测试 TCP options 中 TSOPT 字段的由来,此次构造模拟的是客户端场景。

对于 TCP options,各类介绍资料已经数不胜数,本篇就不再赘述。

基础脚本

# cat tcp_3hs_007.pkt // TCP 基础之三次握手0  socket(..., SOCK_STREAM, IPPROTO_TCP) = 3+0 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0+0 setsockopt(3, SOL_TCP, TCP_NODELAY, [1], 4) = 0+0 connect(3, ..., ...) = -1 EINPROGRESS (Operation now in progress)+0 > S 0:0(0) <...>+0.01 < S. 0:0(0) ack 1 win 10000 <mss 1000>+0 > . 1:1(0) ack 1

实验测试一

因为 >  表示预期协议栈会发送的数据包,所以内核协议栈自动构建发送 SYN 数据包。

+0 > S 0:0(0) <...>// +0 本行代码执行时间相对于上一行代码的偏移时间。// > ,表示预期协议栈会发送的数据包。// 0:0(0) ,表示开始序号:结束序号(数据包长度)。// <> 表示 TCP options,... 表示默认值。

模拟的是客户端场景,SYN 数据包自动构建的情况下,各字段因此无需自定义。

1.执行脚本# packetdrill tcp_3hs_007.pkt # 执行完成后退出。2.捕获数据包# tcpdump -i any port 8080 -nn tcpdump: data link type LINUX_SLL2tcpdump: verbose output suppressed, use -v[v]... for full protocol decodelistening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes15:49:36.529121 tun0  Out IP 192.168.174.54.50762 > 192.0.2.1.8080: Flags [S], seq 1691568983, win 64240, options [mss 1460,sackOK,TS val 329810675 ecr 0,nop,wscale 7], length 015:49:36.629222 ?     In  IP 192.0.2.1.8080 > 192.168.174.54.50762: Flags [S.], seq 0, ack 1691568984, win 10000, options [mss 1000], length 015:49:36.629256 ?     Out IP 192.168.174.54.50762 > 192.0.2.1.8080: Flags [.], ack 1, win 64240, length 015:49:36.629427 ?     Out IP 192.168.174.54.50762 > 192.0.2.1.8080: Flags [F.], seq 1, ack 1, win 64240, length 015:49:36.629444 ?     In  IP 192.0.2.1.8080 > 192.168.174.54.50762: Flags [R.], seq 1, ack 1, win 10000, length 0#

观察 tcpdump 抓包结果可以看到客户端 SYN TCP Options 包含 TSOPT ,因为此时在客户端开启了 Timestamps 支持,所以如上结果。

# sysctl -a | grep timestampsnet.ipv4.tcp_timestamps = 1#

而服务器端响应的 SYN/ACK 不包含 TSOPT,因为此时服务器端属于 < 自行构造的数据包,在 <> TCP options 中只有 mss 1000,并没注入 TSOPT,所以此时 TCP 三次握手的结果,表明之后的 TCP 通讯将不支持 Timestamps

实验测试二

此时修改 SYN/ACK 的 TCP options ,同样增加 Timestamps 支持,同时考虑到双方的 Timestamps 匹配关系,脚本需修改如下:

# cat tcp_3hs_options_tsopt_001.pkt 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3+0 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0+0 setsockopt(3, SOL_TCP, TCP_NODELAY, [1], 4) = 0+0 connect(3, ..., ...) = -1 EINPROGRESS (Operation now in progress)+0 > S 0:0(0) <mss 1460,sackOK,TS val 100 ecr 0,nop ,wscale 7>+.1 < S. 0:0(0) ack 1 win 10000 <mss 1000, nop, nop, TS val 100 ecr 100>+0 > . 1:1(0) ack 1 <nop,nop,TS val 200 ecr 100>## packetdrill tcp_3hs_options_tsopt_001.pkt #

观察 tcpdump 抓包结果可以看到确实  SYN TCP Options 中包含 TSOPT ,且服务器端响应的 SYN/ACK 同样也包含 TSOPT ,所以此时 TCP 三次握手的结果,表明之后的 TCP 通讯将支持 Timestamps ,因为双方均支持。

# tcpdump -i any port 8080 -nntcpdump: data link type LINUX_SLL2tcpdump: verbose output suppressed, use -v[v]... for full protocol decodelistening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes11:29:29.149147 tun0  Out IP 192.168.131.232.51364 > 192.0.2.1.8080: Flags [S], seq 1726783205, win 65535, options [mss 1460,sackOK,TS val 2146277730 ecr 0,nop,wscale 7], length 011:29:29.249271 tun0  In  IP 192.0.2.1.8080 > 192.168.131.232.51364: Flags [S.], seq 0, ack 1726783206, win 10000, options [mss 1000,nop,nop,TS val 100 ecr 2146277730], length 011:29:29.249303 tun0  Out IP 192.168.131.232.51364 > 192.0.2.1.8080: Flags [.], ack 1, win 65535, options [nop,nop,TS val 2146277830 ecr 100], length 011:29:29.249436 tun0  Out IP 192.168.131.232.51364 > 192.0.2.1.8080: Flags [F.], seq 1, ack 1, win 65535, options [nop,nop,TS val 2146277830 ecr 100], length 011:29:29.249453 tun0  In  IP 192.0.2.1.8080 > 192.168.131.232.51364: Flags [R.], seq 1, ack 1, win 10000, length 0#

实验测试三

此时如果将客户端 Timestamps 支持关闭,则:

# sysctl -q net.ipv4.tcp_timestamps=0## sysctl -a | grep timestampsnet.ipv4.tcp_timestamps = 0#

仍然执行如下脚本,那么可以看到 tcpdump 抓包结果中客户端所发送的 SYN 不再包含 TSOPT ,那么不管服务器端本地的 net.ipv4.tcp_timestamps 是否启用(对于真实环境),在响应的 SYN/ACK 中都不会包含 TSOPT。此时 TCP 三次握手的结果,也表明之后的 TCP 通讯将不支持 Timestamps

# packetdrill tcp_3hs_007.pkt ## tcpdump -i any port 8080 -nn tcpdump: data link type LINUX_SLL2tcpdump: verbose output suppressed, use -v[v]... for full protocol decodelistening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes11:34:32.709140 tun0  Out IP 192.168.100.137.46794 > 192.0.2.1.8080: Flags [S], seq 518444255, win 65535, options [mss 1460,nop,nop,sackOK,nop,wscale 7], length 011:34:32.809271 tun0  In  IP 192.0.2.1.8080 > 192.168.100.137.46794: Flags [S.], seq 0, ack 518444256, win 10000, options [mss 1000], length 011:34:32.809309 tun0  Out IP 192.168.100.137.46794 > 192.0.2.1.8080: Flags [.], ack 1, win 65535, length 011:34:32.809433 tun0  Out IP 192.168.100.137.46794 > 192.0.2.1.8080: Flags [F.], seq 1, ack 1, win 65535, length 011:34:32.809452 tun0  In  IP 192.0.2.1.8080 > 192.168.100.137.46794: Flags [R.], seq 1, ack 1, win 10000, length 0#
测试脚本的服务器端 < 属于手工模拟,所以即便是注入了 TSOPT 字段,也非真实场景。

SYN TSOPT

SYN 中 TCP options 的 TSOPT,代码中是通过 tcp_syn_options 函数确定的,相关的代码流程简要说明如下:

sys_connect   |--inet_stream_connect   |  |--tcp_v4_connect   |     |--tcp_connect   |        |--tcp_transmit_skb   |           |--tcp_syn_options

tcp_connect -> tcp_transmit_skb -> __tcp_transmit_skb -> tcp_syn_options 构造 SYN 的 Options 各字段,其中涉及 TSOPT 。

/* Build a SYN and send it off. */int tcp_connect(struct sock *sk){...  /* Send off SYN; include data in Fast Open. */  err = tp->fastopen_req ? tcp_send_syn_data(sk, buff) :        tcp_transmit_skb(sk, buff, 1, sk->sk_allocation);  if (err == -ECONNREFUSED)    return err;...}EXPORT_SYMBOL(tcp_connect);
static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,          gfp_t gfp_mask){  return __tcp_transmit_skb(sk, skb, clone_it, gfp_mask,          tcp_sk(sk)->rcv_nxt);}static int __tcp_transmit_skb(struct sock *sk, struct sk_buff *skb,            int clone_it, gfp_t gfp_mask, u32 rcv_nxt){...  if (unlikely(tcb->tcp_flags & TCPHDR_SYN)) {    tcp_options_size = tcp_syn_options(sk, skb, &opts, &md5);  } ...}

如果启用了 TCP TSOPT(ipv4.sysctl_tcp_timestamps),则设置 Timestamps 选项标志,同时计算出 tsval 和 tsecr 的值。

static unsigned int tcp_syn_options(struct sock *sk, struct sk_buff *skb,        struct tcp_out_options *opts,        struct tcp_md5sig_key **md5){...  if (likely(sock_net(sk)->ipv4.sysctl_tcp_timestamps && !*md5)) {    opts->options |= OPTION_TS;    opts->tsval = tcp_skb_timestamp(skb) + tp->tsoffset;    opts->tsecr = tp->rx_opt.ts_recent;    remaining -= TCPOLEN_TSTAMP_ALIGNED;  }...}
Wireshark & Packetdrill | TCP 三次握手之 TCP Options 字段 TSOPT

往期推荐

1. Wireshark 提示和技巧 | 捕获点之 TCP 三次握手
2. Wireshark 提示和技巧 | a == ${a} 显示过滤宏
3. Wireshark TS | 防火墙空闲会话超时问题
4. Wireshark TS | HTTP 传输文件慢问题
5. 网络设备 MTU MSS Jumboframe 全解

后台回复「TT」获取 Wireshark 提示和技巧系列 合集
后台回复「TS」获取 Wireshark Troubleshooting 系列 合集
如需交流或加技术群,可后台直接留言,我会在第一时间回复,谢谢!
Wireshark & Packetdrill | TCP 三次握手之 TCP Options 字段 TSOPT

原文始发于微信公众号(Echo Reply):Wireshark & Packetdrill | TCP 三次握手之 TCP Options 字段 TSOPT

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年8月5日10:20:42
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Wireshark & Packetdrill | TCP 三次握手之 TCP Options 字段 TSOPThttps://cn-sec.com/archives/3035993.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息