Translated message

A translation of this page exists in English.

Warning message

This translation is outdated. For the most up-to-date information, please refer to the English version.

如何用 tcpdump 抓包?

Solution In Progress - Updated -

Environment

  • Red Hat Enterprise Linux (RHEL) 3
  • Red Hat Enterprise Linux (RHEL) 4
  • Red Hat Enterprise Linux (RHEL) 5
  • Red Hat Enterprise Linux (RHEL) 6
  • OpenShift Enterprise (OSE)
    • 1.x

Issue

  • 如何用 tcpdump 抓包?
  • 如何监视系统网络接口上的所有数据包?

Resolution

  • 您可以通过 tcpdump 命令来抓包。最新版本 (RHEL 6 之后)的 tcpdump 抓取数据包时每个包的默认抓取长度为 65535 字节,而旧版本(RHEL5 之前)的 tcpdump 每个包默认抓取长度为 68 字节。但是抓取68字节的数据往往不能满足所有故障排除及诊断的需要,所以如果您不确定系统的默认值,请以 "snaplen" 为关键字查找相关信息参考 tcpdump 的 man 手册。如果您想抓到完整的数据包,请您参考以下执行命令,把 tcpdump-s 参数的值设为 0:
# tcpdump -n -i {interface} -s 0 -w /tmp/network.cap [expression]
  • interface 常用值是 "eth0" 或 "bond0"。您也可以将其设为 "any" 抓取所有网络接口的数据包,但这会导致同一数据包被抓取多次(例如,某系统配置了 bonding,如果用 "any" 的话既可以抓到 master 的包,也可以抓到 slave 的包)。这种情况下反而使得故障排除/诊断更为复杂,因为很多工具会将多余的包标记为重发的数据。如果您知道正在与之通信的远端 IP 地址,那么您就可以通过 ip route get 确定与远程通信的本地网卡。例:
# ip route get 10.16.29.55
10.16.29.55 via 10.16.47.254 dev eth0  src 10.16.46.34 
    cache 

在上述实例中,与远程通信的本地网卡是 eth0 , 所以您需要在 tcpdump -i 后面传入 “eth0” 这个参数。
如果您不知道接口参数应该传什么,请设成 "any"。

  • man 手册里对于 "-s" 这个参数的描述如下:
       -s     Snarf  snaplen  bytes  of  data from each packet rather than the default of 65535 bytes.  Packets truncated because of a
              limited snapshot are indicated in the output with ‘‘[|proto]’’, where proto is the name of the protocol level  at  which
              the  truncation  has  occurred.  Note that taking larger snapshots both increases the amount of time it takes to process
              packets and, effectively, decreases the amount of packet buffering.  This may cause packets  to  be  lost.   You  should
              limit  snaplen  to the smallest number that will capture the protocol information you’re interested in.  Setting snaplen
              to 0 sets it to the default of 65535, for backwards compatibility with recent older versions of tcpdump.
  • 注意对于 NFS v3, 把 snaplen 设为 256 就可以满足需求。但如果是针对 READDIR/READDIRPLUS 的故障排除,您可能需要设置 snaplen 为 0。对于 NFS v4, 您需要将 snaplen 设为0。(注:在处理 NFS 的相关问题时,对于RHEL5 及以前旧版本的 tcpdump ,一般都需要设定snaplen 的值,而不是使用默认的 68 字节)。

  • 您可以通过 expression 过滤包。关于 expression 的介绍,请参考 pcap-filter 的man 手册。

# man pcap-filter
  • 更多关于 tcpdump 的信息,请参考 man 手册。

  • tcpdump 时请注意以下问题:

  1. 接口选择 请您确认在抓包时选择了正确的接口。如果您使用 bonding 或者 vlan,请确认抓取的数据包是经过该设备的。例如,对于bonding,您可以用 "bond0" 作为网络接口。您可以通过主机名或 IP 地址和路由表( "route -n" )的组合形式决定用了哪个接口。此外,如果您未使用 -i 参数,tcpdump 只会抓取某个网络接口的数据包,而这个接口有可能不是您需要用的。如果您需要抓取 vlan 的流量包,请参考 Capture vlan traffic
  2. 抓包文件路径 请您尽量把抓包文件存在本地磁盘上。如果您是为了处理网络文件系统的问题(例如 NFS 和 cifs),请您不要把capture 文件存到网络文件系统,因为这会导致抓取多余的包。
  3. 抓包文件大小 如果您需要抓取大量的数据包,或者数据流通不连贯,建议您使用 "-W" 和 "-C" 参数循环抓取流量包。
  • 以下是抓取服务器端和客户端之间网络流量包的步骤。 (注:该例假设客户端和服务器端都是Red Hat Enterprise Linux(RHEL)操作系统。如果不是这种情况,请您选择适合您系统的内容):
  1. 确定客户端和服务器端都安装了 tcpdump RPM 包。
    在 RHEL3 或 RHEL4 里,请您使用 up2date 命令:

    # up2date -i tcpdump
    

    在 RHEL5 或 RHEL6 里,请您使用 yum 命令:

    # yum install tcpdump
    
  2. 请以 root 用户的身份在服务器端执行以下命令:

    # tcpdump -n -vv -s 0 -i {interface} -w /tmp/server.cap host {hostname or IP address of client} 
    

    {interface} 处填入与客户端通信的网络设备。如果您想列出所有可以用 tcpdump 抓包的设备,请执行以下命令:

    # tcpdump -D 
    
    • 如果服务器端有很多网络设备,请您确保抓取的是正确接口的流量包。

    • 如果您使用了 bonding 或 vlan 接口,请确保抓取的是该设备的流量包。

  3. 请以 root 用户的身份在客户端执行以下命令:

    # tcpdump -n -vv -s 0 -i {interface} -w /tmp/client.cap host {hostname or IP address of server} 
    

    {interface} 处填入与服务器端通信的网络设备。

  4. 现在,请您尽可能的重现几次需要故障排除的问题。当出现问题后,用 ctrl+c 终止 tcpdump 命令。然后,请您使用 tcpdump 命令的 -r 参数确认是否已经抓取了需要的流量包。如果准确地抓取了流量包,这条命令将会输出从客户端和服务器端发出的包。以下是针对 NFS getttr 的请求和响应抓包的实例:

    # tcpdump -r /tmp/client.cap
     ...
    09:39:06.272688 IP 192.168.155.74.3337237041 > 192.168.155.2.nfs: 216 getattr fh 0,0/22
    09:39:06.273342 IP 192.168.155.2.nfs > 192.168.155.74.3337237041: reply ok 88 getattr NON 2 ids 0/9 sz 0
    09:39:06.273365 IP 192.168.155.3354014257 > 192.168.155.2.nfs: 220 getattr fh 0,0/22
    09:39:06.273840 IP 192.168.155.2.nfs > 192.168.155.74.3354014257: reply ok 108 getattr NON 2 ids 0/9 sz 0
    
  5. 如果需要追踪的文件很大(几百MB,甚至几GB), 请用 gzip 工具压缩。您也可以使用其他压缩方法,例如 bzip2 ,但是一些工具例如tshark 也许不能识别这些文件,所以建议您使用 gzip

    # gzip /tmp/client.cap
    # gzip /tmp/server.cap
    
  6. 请您将客户端和服务器端抓取的流量包的压缩文件( *.cap.gz )以附件形式添加到问题单或者上传到Red Hat Global Support Services anonymous FTP server (dropbox.redhat.com)。

This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.