Operation

tcpdump 生产网Troubleshooting之实用篇

tcpdump 生产网Troubleshooting之实用篇

1. 基础

  • 安装 tcpdump
sudo apt-get install tcpdump # Focal Linux(Ubuntu/Debian)
sudo yum install tcpdump # Redhat Linux(CentOS/Oracle Linux)
  • 查看 tcpdump 示例
sudo man tcpdump | less -Ip examples

2. 应用层数据包(实用)

2.1 捕获 HTTP 包

  • 捕获 HTTP GET 请求(原理:GET 的十六进制是 0x47455420)
sudo tcpdump -s 0 -A 'tcp dst port 80 and tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420'
  • 捕获 HTTP POST 请求
sudo tcpdump -s 0 -A 'tcp dst port 80 and (tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x504f5354)'
  • 捕获 HTTP 请求响应头及数据
# 文本输出
sudo tcpdump -A -s 0 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)'
# HEX 输出
sudo tcpdump -X -s 0 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)'

2.2 捕获 SMTP 包

  • 捕获数据区开始为MAIL的包,MAIL的十六进制为 0x4d41494c。
sudo tcpdump -i eth0 '((port 25) and (tcp[(tcp[12]>>2):4] = 0x4d41494c))'

2.3 捕获 SSH 包

sudo tcpdump -i eth0 'tcp[(tcp[12]>>2):4] = 0x5353482D'

SSH-的十六进制是 0x5353482D,抓老版本的 SSH 返回信息,如SSH-1.99..

sudo tcpdump -i eth0 '(tcp[(tcp[12]>>2):4] = 0x5353482D) and (tcp[((tcp[12]>>2)+4):2]=0x312E)'

2.4 捕获 DNS 包

sudo tcpdump -i eth0 udp dst port 53

3. 传输层数据包(实用)

3.1 捕获 8080 端口 tcp 协议所有数据包

sudo tcpdump -i eth0 -s 0 tcp port 8080 -w /tmp/tcpdump.cap

3.2 捕获从本机 8070 端口出和入的所有 “HT”开头或“PO”、“GE” 开头的数据包

sudo tcpdump -XvvennSs 0 -i eth0 '((tcp[20:2]=0x4745 or tcp[20:2]=0x4854 or tcp[20:2]=0x504f) or (port 8070))' -w /root/log.cap
  • 注: 0x4745 为GET前两个字母GE, 0x4854 为HTTP前两个字母HT, 0x504f为POST前缀PO

3.3 按地址过滤

  • 捕获所有经过 eth0 源地址或目的地址为 192.168.1.1 的所有数据包
sudo tcpdump -i eth0 host 192.168.1.1
  • 过滤源地址
sudo tcpdump -i eth0 src host 192.168.1.1
  • 过滤目的地址
sudo tcpdump -i eth0 dst host 192.168.1.1

3.4 按端口过滤

  • 捕获经过 eth0 源端口或目的端口为 25 的所有数据包
sudo tcpdump -i eth0 port 25
  • 过滤源端口
sudotcpdump -i eth0 src port 25
  • 过滤目的端口
sudo tcpdump -i eth0 dst port 25

3.5 按网段过滤

sudo tcpdump -i eth0 net 192.168
sudo tcpdump -i eth0 src net 192.168
sudo tcpdump -i dst net 192.168

3.6 按协议过滤

sudo tcpdump -i eth0 arp
sudo tcpdump -i eth0 ip
sudo tcpdump -i eth0 tcp
sudo tcpdump -i eth0 udp
sudo tcpdump -i eth0 icmp

3.7 运算符

  • 非运算:!、or、not(去掉双引号)

  • 与运算:&&、and

  • 或运算:||、or

  • 捕获所有经过 eth0,目的地址是 192.168.1.254 或 192.168.1.200 端口是 80 的 TCP 数据

sudo tcpdump -i eth0 '((tcp) and (port 80) and ((dst host 192.168.1.254) or (dst host 192.168.1.200)))'
  • 捕获所有经过 eth0,目标 MAC 地址是 00:01:02:03:04:05 的 ICMP 数据
sudo tcpdump -i eth0 '((icmp) and ((ether dst host 00:01:02:03:04:05)))'
  • 捕获所有经过 eth0,目的网络是 192.168,但目的主机不是 192.168.1.200 的 TCP 数据
sudo tcpdump -i eth0 '((tcp) and ((dst net 192.168) and (not dst host 192.168.1.200)))'
  • 只抓 SYN 包
sudo tcpdump -i eth0 'tcp[tcpflags] = tcp-syn'
  • 抓 SYN, ACK
sudo tcpdump -i eth0 'tcp[tcpflags] & tcp-syn != 0 and tcp[tcpflags] & tcp-ack != 0'

4. 说明

  • -c 参数对于运维人员来说也比较常用,因为流量比较大的服务器,靠人工 CTRL+C 还是抓的太多,于是可以用-c 参数指定抓多少个包。

  • 以下命令计算抓 10000 个 SYN 包花费多少时间,可以判断访问量大概是多少

sudo time tcpdump -nn -i eth0 '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

5. 参考

6. FAQ

6.1 如何在 TCPdump 中显示 MAC 地址

sudo tcpdump -i any dst port 8080 or src port 8080 -e

留言

您的电子邮箱地址不会被公开。