tcpdump 是类 Unix 系统上最常用、最轻量的网络抓包与分析工具。它直接调用 libpcap 库,在内核层抓取链路层的数据包,然后解析输出文本格式的“数据包头部摘要”,也可将原始数据保存为 pcap 文件供 Wireshark 等 GUI 工具进一步分析。
字多不看
sudo tcpdump host httpforever.com and tcp port 80 -A -nn
一举成名天下知
man tcpdump
常用参数速查
参数 | 作用 |
---|---|
-i | 指定接口(不指定默认第一个可用接口) |
-nn | 不解析主机名和端口名(仅显示数字) |
-v/-vv/-vvv | 详细级别(-v/-vv/-vvv) |
-c | 捕获指定数量后退出 |
-s | 抓取长度(0 = 全包;新版默认 262144 bytes) |
-w | 将原始数据写入 pcap 文件 |
-r | 读取 pcap 文件离线解析 |
-A / -X | 以 ASCII / 十六进制+ASCII 方式打印负载 |
- -i any 监听所有的网卡
- -A 只使用 ascii 打印报文的全部数据,不要和 -X 一起使用。截取 http 请求的时候可以用
sudo tcpdump -nSA port 80
- -S 显示绝对的序列号(sequence number),而不是相对编号
过滤语法
tcpdump 采用 BPF 过滤语法(Berkeley Packet Filter
[proto] [src|dst] [host|net|port] <对象> [逻辑运算]
tcp and dst port 80 and src net 10.0.0.0/8
- 协议:ip, tcp, udp, icmp, arp, vlan, ip6, …
- 方向:src, dst, src or dst, src and dst
- 对象:host 10.0.0.1, net 192.168.0.0/16, port 443
- 逻辑:and, or, not, ( )
- 与:&& 或 and
- 或:|| 或 or
- 非:! 或 not
# 抓取所有经过 en0,目的或源地址是 192.168.50.1 的网络数据
sudo tcpdump -i en0 host 192.168.50.1
# 源地址
sudo tcpdump -i en0 src host 192.168.50.1
# 目的地址
sudo tcpdump -i en0 dst host 192.168.50.1
# 端口
sudo tcpdump -i en0 port 8080
### 过滤网段
sudo tcpdump -i en0 net 192.168
### 协议过滤
sudo tcpdump -i en0 tcp
sudo tcpdump -i en0 udp
sudo tcpdump -i en0 ip
sudo tcpdump -i en0 arp
sudo tcpdump -i en0 icmp
输出格式拆解
14:24:12.196582 IP 192.168.91.29.56930 > 146.190.62.39.http: Flags [SEW], seq 193726297, win 65535, options [mss 1460,nop,wscale 6,nop,nop,TS val 2297696209 ecr 0,sackOK,eol], length 0
- 时间戳
- 协议层 (IP/ARP/…)
- 源地址.端口 > 目标地址.端口
- TCP 标志位
- seq/ack/win 等字段
- 报文长度
可加 -tttt 打印完整日期;-e 显示以太网头(MAC 地址)。
获取适配器列表
sudo tcpdump -D
sudo tcpdump --list-interfaces
1.en0 [Up, Running]
2.p2p0 [Up, Running]
3.awdl0 [Up, Running]
...
监听适配器
Listen on interface.
macOS 下监听适配器,必须使用 root 权限。
sudo tcpdump -i en0
sudo tcpdump -i 1
Flags
TCP Flag | Flag | Meaning |
---|---|---|
SYN | S | Syn packet, a session establishment request. 一个会话建立请求 |
ACK | A | Ack packet, acknowledge sender’s data. 确认发送方的数据 |
FIN | F | Finish flag, indication of termination. 终止的的标识 |
RESET | R | Reset, indication of immediate abort of conn. 指令立即中止 |
PUSH | P | Push, immediate push of data from sender. 从发送方立即推送数据 |
URGENT | U | Urgent, takes precedence over other data. 优先于其他数据 |
NONE | A dot . | Placeholder, usually used for ACK. 占位符,通常用于 ACK |
实例
抓取所有经过 eth1,目的地址是 192.168.1.254 或 192.168.1.200 端口是 80 的 TCP 数据:
sudo tcpdump -i eth1 '((tcp) and (port 80) and ((dst host 192.168.1.254) or (dst host
192.168.1.200)))'
抓取所有经过 eth1,目的网络是 192.168,但目的主机不是 192.168.1.200 的 TCP 数据:
sudo tcpdump -i eth1 '((tcp) and ((dst net 192.168) and (not dst host 192.168.1.200)))'
只抓 SYN 包:
sudo tcpdump -i eth1 'tcp[tcpflags] = tcp-syn'
抓 SYN, ACK:
sudo tcpdump -i eth1 'tcp[tcpflags] & tcp-syn != 0 and tcp[tcpflags] & tcp-ack != 0'
抓 DNS 请求数据:
sudo tcpdump -i en0 udp dst port 53
-c 参数对于运维人员来说也比较常用,因为流量比较大的服务器,靠人工 CTRL+C 还是抓的太多,于是可以用 -c 参数指定抓多少个包:
sudo time tcpdump -nn -i en0 'tcp[tcpflags] = tcp-syn' -c 10000 > /dev/null
实时抓取端口号 8000 的 GET 包,然后写入 GET.log:
sudo tcpdump -i eth0 '((port 8000) and (tcp[(tcp[12]>>2):4]=0x47455420))' -nnAl -w /tmp/GET.log
三次握手 四次挥手
TCP 连接建立(三次握手)
客户端 A,服务器 B,初始序号 seq,确认号 ack。
初始状态:B 处于监听状态,A 处于打开状态。
- A -> B : seq = x (A 向 B 发送连接请求报文段,A 进入同步发送状态 SYN-SENT)
- B -> A : ack = x + 1,seq = y (B 收到报文段,向 A 发送确认,B 进入同步收到状态 SYN-RCVD)
- A -> B : ack = y + 1 (A 收到 B 的确认后,再次确认,A 进入连接状态 ESTABLISHED)
连接后的状态:B 收到 A 的确认后,进入连接状态 ESTABLISHED。
为什么要握手要三次?防止失效的连接请求突然传到服务器端,让服务器端误认为要建立连接。
TCP 连接释放(四次挥手)
- A -> B : seq = u (A 发出连接释放报文段,进入终止等待 1 状态 FIN-WAIT-1)
- B -> A : ack = u + 1,seq = v (B 收到报文段,发出确认,TCP 处于半关闭,B 还可向 A 发数据,B 进入关闭等待状态 WAIT)
- B -> A : ack = u + 1,seq = w (B 重复发送确认号,进入最后确认状态 LAST-ACK)
- A -> B : ack = w + 1,seq = u + 1 (A 发出确认,进入时间等待状态 TIME-WAIT)
经过时间等待计时器设置的时间 2MSL 后,A 才进入 CLOSED 状态。
为什么 A 进入 TIME-WAIT 后必须等待 2MSL:
- 保证 A 发送的最后一个 ACK 报文段能达到 B
- 防止失效的报文段出现在连接中
需要思考的问题
问题 1: 请详细描述三次握手和四次挥手的过程 要求熟悉三次握手和四次挥手的机制,要求画出状态图。
问题 2: 四次挥手中 TIME_WAIT 状态存在的目的是什么? 这个问题是画出四次挥手状态图,会引申问你。不排除还会问为什么四次挥手是四次不是二次等问题。最好是把相关问题均掌握。
问题 3: TCP 是通过什么机制保障可靠性的? 从四个方面进行回答,ACK 确认机制、超时重传、滑动窗口以及流量控制,深入的话要求详细讲出流量控制的机制。
抓包分析握手过程
sudo tcpdump -i en0 host www.qq.com and tcp -S -c 50
References
– EOF –