Tcp握手和挥手的抓包分析

1. 三次握手建立连接

TCP是TCP/IP的传输层控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接。

TCP 3-Way Handshake (SYN,SYN-ACK,ACK),事例图示很多,拿来:

握手过程

准备一个简单的socket 代码段

  • client.py
from socket import *
import time

addr = ('127.0.0.1',8888)
client = socket(AF_INET, SOCK_STREAM)
client.connect(addr)
time.sleep(5)
print "client closed"
  • server.py
import socket
import sys
import os
addr = ('127.0.0.1', 8888)
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(addr)
server.listen(10)

while True:
        connection, address = server.accept()
        print 'connection ip:', address

client 端会在连接5秒后,关闭连接,用于查看挥手的过程,暂时我们先分析下建立连接的过程。

  • 抓包:
[root@ip-*-*-*-* ~]# tcpdump -nn -vvv -XX  -i lo -S tcp
04:33:24.476992 IP (tos 0x0, ttl 64, id 40015, offset 0, flags [DF], proto TCP (6), length 60)
    127.0.0.1.54800 > 127.0.0.1.8888: Flags [S], cksum 0xfe30 (incorrect -> 0x4f2d), seq 2359231437, win 43690, options [mss 65495,sackOK,TS val 759865218 ecr 0,nop,wscale 7], length 0
    0x0000:  0000 0000 0000 0000 0000 0000 0800 4500  ..............E.
    0x0010:  003c 9c4f 4000 4006 a06a 7f00 0001 7f00  .<.O@[email protected]......
    0x0020:  0001 d610 22b8 8c9f 03cd 0000 0000 a002  ...."...........
    0x0030:  aaaa fe30 0000 0204 ffd7 0402 080a 2d4a  ...0..........-J
    0x0040:  9f82 0000 0000 0103 0307                 ..........
04:33:24.477010 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60)
    127.0.0.1.8888 > 127.0.0.1.54800: Flags [S.], cksum 0xfe30 (incorrect -> 0x6480), seq 4014354056, ack 2359231438, win 43690, options [mss 65495,sackOK,TS val 759865218 ecr 759865218,nop,wscale 7], length 0
    0x0000:  0000 0000 0000 0000 0000 0000 0800 4500  ..............E.
    0x0010:  003c 0000 4000 4006 3cba 7f00 0001 7f00  .<..@.@.<.......
    0x0020:  0001 22b8 d610 ef46 2e88 8c9f 03ce a012  .."....F........
    0x0030:  aaaa fe30 0000 0204 ffd7 0402 080a 2d4a  ...0..........-J
    0x0040:  9f82 2d4a 9f82 0103 0307                 ..-J......
04:33:24.477023 IP (tos 0x0, ttl 64, id 40016, offset 0, flags [DF], proto TCP (6), length 52)
    127.0.0.1.54800 > 127.0.0.1.8888: Flags [.], cksum 0xfe28 (incorrect -> 0x36c5), seq 2359231438, ack 4014354057, win 342, options [nop,nop,TS val 759865218 ecr 759865218], length 0
    0x0000:  0000 0000 0000 0000 0000 0000 0800 4500  ..............E.
    0x0010:  0034 9c50 4000 4006 a071 7f00 0001 7f00  .4.P@[email protected]......
    0x0020:  0001 d610 22b8 8c9f 03ce ef46 2e89 8010  ...."......F....
    0x0030:  0156 fe28 0000 0101 080a 2d4a 9f82 2d4a  .V.(......-J..-J
    0x0040:  9f82                                     ..

分析:
1. 第一条client给server发送了一个SYN包,TCP 协议的报文从0x0020 + 2 的位置开始,TCP-FLAGS是:a002;对应TCP的首部。
握手第一个
只有SYN位为1, 序号是2359231437。
2. 第二条,server给client发送了一个 ACK包,ack的序号是2359231438(2359231437 + 1)。同样的TCP-FLAGS:a012,ACK=1,SYN=1。
3. 第三条,client给server发送了一个ACK包TCP-FLAGS:8010,ACK=1,其余位是0。

 注意:tcp在收到第一条数据包之后,后续的数据包,是使用之前数据包的偏移来显示的,所以抓包加-S选项,会打印绝对编号。

2. 四次挥手

示意图:
挥手过程
连接5秒后,client端会close掉当前连接。

此时抓包会接着打印:

04:33:29.484395 IP (tos 0x0, ttl 64, id 40017, offset 0, flags [DF], proto TCP (6), length 52)
    127.0.0.1.54800 > 127.0.0.1.8888: Flags [F.], cksum 0xfe28 (incorrect -> 0x2335), seq 2359231438, ack 4014354057, win 342, options [nop,nop,TS val 759870225 ecr 759865218], length 0
    0x0000:  0000 0000 0000 0000 0000 0000 0800 4500  ..............E.
    0x0010:  0034 9c51 4000 4006 a070 7f00 0001 7f00  .4.Q@[email protected]......
    0x0020:  0001 d610 22b8 8c9f 03ce ef46 2e89 8011  ...."......F....
    0x0030:  0156 fe28 0000 0101 080a 2d4a b311 2d4a  .V.(......-J..-J
    0x0040:  9f82                                     ..
04:33:29.484840 IP (tos 0x0, ttl 64, id 45323, offset 0, flags [DF], proto TCP (6), length 52)
    127.0.0.1.8888 > 127.0.0.1.54800: Flags [.], cksum 0xfe28 (incorrect -> 0x0fa5), seq 4014354057, ack 2359231439, win 342, options [nop,nop,TS val 759870226 ecr 759870225], length 0
    0x0000:  0000 0000 0000 0000 0000 0000 0800 4500  ..............E.
    0x0010:  0034 b10b 4000 4006 8bb6 7f00 0001 7f00  .4..@.@.........
    0x0020:  0001 22b8 d610 ef46 2e89 8c9f 03cf 8010  .."....F........
    0x0030:  0156 fe28 0000 0101 080a 2d4a b312 2d4a  .V.(......-J..-J
    0x0040:  b311

分析:

  • client 给server端发了一个[F],分析TCP-FLAGS:8011,对应就是:ACK=1,FIN=1。
  • server 马上回复8010, ACK = 1,这个时候,你也可以看下server的TCP 状态,CLOSE_WAIT
[ec2-user@ip-172-31-28-112 ~]$ netstat -natp
(No info could be read for "-p": geteuid()=1000 but you should be root.)
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -
tcp        0      0 127.0.0.1:8888          0.0.0.0:*               LISTEN      -
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      -
tcp        1      0 127.0.0.1:8888          127.0.0.1:54876         CLOSE_WAIT  -
tcp        0     36 172.31.28.112:22        123.121.20.194:53087    ESTABLISHED -
tcp        0      0 172.31.28.112:22        123.121.20.194:62244    ESTABLISHED -
tcp        0      0 172.31.28.112:22        123.121.20.194:62758    ESTABLISHED -
tcp        0      0 127.0.0.1:54876         127.0.0.1:8888          FIN_WAIT2   -
tcp        0      0 172.31.28.112:40916     173.194.175.188:443     ESTABLISHED -
tcp        0      0 172.31.28.112:22        123.121.20.194:62785    ESTABLISHED -
tcp6       0      0 :::22                   :::*                    LISTEN      -
tcp6       0      0 ::1:25                  :::*                    LISTEN      -
  • 这时候,ctl + c 关掉server 进程,会自动关闭打开的socket。抓包会继续打印:
06:15:56.777552 IP (tos 0x0, ttl 64, id 34340, offset 0, flags [DF], proto TCP (6), length 52)
    127.0.0.1.8888 > 127.0.0.1.54874: Flags [F.], cksum 0xfe28 (incorrect -> 0xfe34), seq 1558878509, ack 4191715919, win 342, options [nop,nop,TS val 766017518 ecr 765997725], length 0
    0x0000:  0000 0000 0000 0000 0000 0000 0800 4500  ..............E.
    0x0010:  0034 8624 4000 4006 b69d 7f00 0001 7f00  .4.$@.@.........
    0x0020:  0001 22b8 d65a 5cea 992d f9d8 824f 8011  .."..Z\..-...O..
    0x0030:  0156 fe28 0000 0101 080a 2da8 7fee 2da8  .V.(......-...-.
    0x0040:  329d                                     2.
06:15:56.777568 IP (tos 0x0, ttl 64, id 61211, offset 0, flags [DF], proto TCP (6), length 52)
    127.0.0.1.54874 > 127.0.0.1.8888: Flags [.], cksum 0xb0e3 (correct), seq 4191715919, ack 1558878510, win 342, options [nop,nop,TS val 766017518 ecr 766017518], length 0
    0x0000:  0000 0000 0000 0000 0000 0000 0800 4500  ..............E.
    0x0010:  0034 ef1b 4000 4006 4da6 7f00 0001 7f00  .4..@[email protected].......
    0x0020:  0001 d65a 22b8 f9d8 824f 5cea 992e 8010  ...Z"....O\.....
    0x0030:  0156 b0e3 0000 0101 080a 2da8 7fee 2da8  .V........-...-.
    0x0040:  7fee

其中,第一条:8011,其中ACK=1,FIN=1。
- 第2条8010,其中ACK=1。
和原理完全匹配。只是不清楚,为什么close 的时候,ACK为什么要发。

猜你喜欢

转载自blog.csdn.net/xialingming/article/details/81291599