tcpdump学习

linux提供了tcpdump这个工具进行网络数据抓包。通过对抓包的数据进行分析,可以排查解决一些疑难问题。例如网络程序异常崩溃、网络应用程序响应慢、网络不可用等。

libpcap

tcpdump底层依赖的是libpcap库。libpcap使用了一种不同的套接字:PF_PACKET。PF_PACKET套接字作用于数据链路层。数据的传递并不是先经过libpcap处理,然后再传递给上层协议栈,而是在链路层增加了旁路处理机制,这种机制不会干涉原有的数据处理逻辑,更不会因抓包软件的出错而导致原本的处理流程异常,这与iptables的监控机制不同。在C语言中使用PF_PACKET套接字的方法如下:

# include 
# include 
# include 
packet_socket = socket(PF_PACKET, int socket_type, int protocal)

socket_type可以是SOCK_RAW和SOCK_DGRAM,区别是SOCK_RAW由用户自己处理链路层协议头,而后者由系统处理。

BPF

libpcap的抓包是在内核空间工作的,如果抓到的包不加过滤全部拷贝到用户空间,让用户进程进行过滤,那么开销会很大,特别是在高流量的场景下。类似的epoll相比于poll的优势中有一点,就是优化了文件描述符在两个空间的拷贝开销。BPF支持在内核态就将抓到的数据过滤,高效处理大量的网络数据。BPF 过滤代码从逻辑上看很类似于汇编语言,显然,由用户来写过滤代码太过复杂,因此 libpcap 允许用户书写高层的、容易理解的过滤字符串,然后将其编译为BPF代码。

tcpdump与iptables

根据上面的介绍,应该知道tcpdump直接作用于数据链路层。那么iptables作为防火墙拦截的流量能被tcpdump抓取到吗?
iptables依赖的netfilter工作在linux网络协议栈站中。情况分为两种:

  • input的流量首先经过链路层然后进入linux的网络协议栈,所以此种情况,tcpdump可以抓取到。
  • output的流量先经过网络协议栈层,然后经过最下层的链路层,此种情况如果流量被iptables过滤,那么tcpdump是抓取不到的

tcpdump部分参数

  • -i参数:指定需要抓包的网卡。如果未指定的话,tcpdump会默认选择搜索到的系统中状态为up的最小数字的网卡,一般情况下是eth0。-i lo抓取回环的数据包。
  • -nnn参数:禁用tcpdump展示时把IP、端口等转换为域名、端口知名服务名称。这样看起来会更清晰
  • -s参数:指定抓包的包大小。使用-s 0指定数据包大小为262144。可以使抓到的数据包不被截断,完整反映数据包的内容。默认68字节
  • -c参数:指定抓包的数量
  • -w参数:指定抓包结果保存的文件,以便后续用wireshark等工具进行分析。
  • -P参数:in/out/inout,指定要抓取的包是流入还是流出的包。默认inout
  • -F参数:使用file 文件作为过滤条件表达式的输入, 此时命令行上的输入将被忽略.
  • -p参数: 一般情况下, 把网络接口设置为非'混杂'模式.

tcpdump过滤器

tcpdump提供了丰富的过滤器,以支持抓包时的精细化控制,达到减少无效信息干扰的效果

  • host a.b.c.d :指定仅抓取本机和某主机a.b.c.d的通信数据
  • tcp port x: 指定仅抓取tcp协议端口为x的通信数据
  • icmp: 指定仅抓取icmp协议的数据
  • src: 指定数据来源,src host a.b.c.d指定仅抓取来自于主机a.b.c.d的通信数据。类似的有src port x。
  • dst: 指定数据目的地,dst host a.b.c.d指定仅抓取目的主机为a.b.c.d的通信数据。类似的有dst port x。
  • portrange x-y: 仅抓取端口号在x和y之间的通信数据
  • !:反向匹配,例如port!22,抓取非22端口的数据通信

以上的过滤器规则可以使用and或者or进行组合

  • host a.b.c.d and tcp port x:只抓取本机和某主机a.b.c.d之间tcp端口为x的通信数据
  • tcp port x or icmp :抓取tcp端口为x或者协议为icmp的通信数据

tcmdump表达式

表达式由一个或多个'表达元'组成(nt: primitive, 表达元, 可理解为组成表达式的基本元素). 一个表达元通常由一个或多个修饰符(qualifiers)后跟一个名字或数字表示的id组成(nt: 即, 'qualifiers id').有三种不同类型的修饰符:type, dir以及 proto.

  • type 修饰符指定id 所代表的对象类型, id可以是名字也可以是数字. 可选的对象类型有: host, net, port 以及portrange(nt: host 表明id表示主机, net 表明id是网络, port 表明id是端而portrange 表明id 是一个端口范围). 如, 'host foo', 'net 128.3', 'port 20', 'portrange 6000-6008'(nt: 分别表示主机 foo,网络 128.3, 端口 20, 端口范围 6000-6008). 如果不指定type 修饰符, id默认的修饰符为host.
  • dir 修饰符描述id 所对应的传输方向, 即发往id 还是从id 接收(nt: 而id 到底指什么需要看其前面的type 修饰符).可取的方向为: src, dst, src 或 dst, src并且dst.(nt:分别表示, id是传输源, id是传输目的, id是传输源或者传输目的, id是传输源并且是传输目的). 例如, 'src foo','dst net 128.3', 'src or dst port ftp-data'.(nt: 分别表示符合条件的数据包中, 源主机是foo, 目的网络是128.3, 源或目的端口为 ftp-data).如果不指定dir修饰符, id 默认的修饰符为src 或 dst.
  • proto 修饰符描述id 所属的协议. 可选的协议有: ether, fddi, tr, wlan, ip, ip6, arp, rarp, decnet, tcp以及 upd.(nt | rt: ether, fddi, tr, 具体含义未知, 需补充. 如果不指定proto 修饰符, 则默认为与相应type匹配的修饰符. 例如, 'src foo' 含义是 '(ip or arp or rarp) src foo'
    可以看出表达式的书写符合 proto dir type的顺序,修饰符省略时使用默认值

结语

tcpdump和wireshark是网络分析的两个非常重要的工具,高效的使用这两个工具,可以起到事半功倍的作用。

你可能感兴趣的:(tcpdump学习)