技术文档收录
ASCII
Tcpdump
Linux
WireGuard 一键安装脚本 | 秋水逸冰
SSH Config 那些你所知道和不知道的事 | Deepzz's Blog
Linux 让终端走代理的几种方法
ubuntu 20.04 server 版设置静态 IP 地址 - 链滴
Linux 挂载 Windows 共享磁盘的方法 - 技术学堂
将 SMB/CIFS 网络硬盘永久的挂载到 Ubuntu 上 - 简书
linux 获取当前脚本的绝对路径 | aimuke
[Linux] Linux 使用 / dev/urandom 生成随机数 - piaohua's blog
Linux 生成随机数的多种方法 | Just Do It
Linux 的 Centos7 版本下忘记 root 或者普通用户密码怎么办?
Git 强制拉取覆盖本地
SSH 安全加固指南 - FreeBuf 网络安全行业门户
Linux 系统安全强化指南 - FreeBuf 网络安全行业门户
Linux 入侵排查 - FreeBuf 网络安全行业门户
sshd_config 配置详解 - 简书
SSH 权限详解 - SegmentFault 思否
CentOS 安装 node.js 环境 - SegmentFault 思否
如何在 CentOS 7 上安装 Node.js 和 npm | myfreax
几款 ping tcping 工具总结
OpenVpn 搭建教程 | Jesse's home
openvpn 一键安装脚本 - 那片云
OpenVPN 解决 每小时断线一次 - 爱开源
OpenVPN 路由设置 – 凤曦的小窝
OpenVPN 设置非全局代理 - 镜子的记录簿
TinyProxy 使用帮助 - 简书
Ubuntu 下使用 TinyProxy 搭建代理 HTTP 服务器_Linux_运维开发网_运维开发技术经验分享
Linux 软件包管理工具 Snap 常用命令 - 简书
linux systemd 参数详解
Systemd 入门教程:命令篇 - 阮一峰的网络日志
记一次 Linux 木马清除过程
rtty:在任何地方通过 Web 访问您的终端
02 . Ansible 高级用法 (运维开发篇)
终于搞懂了服务器为啥产生大量的 TIME_WAIT!
巧妙的 Linux 命令,再来 6 个!
77% 的 Linux 运维都不懂的内核问题,这篇全告诉你了
运维工程师必备:请收好 Linux 网络命令集锦
一份阿里员工的 Java 问题排查工具单
肝了 15000 字性能调优系列专题(JVM、MySQL、Nginx and Tomcat),看不完先收
作业调度算法(FCFS,SJF,优先级调度,时间片轮转,多级反馈队列) | The Blog Of WaiterXiaoYY
看了这篇还不会 Linux 性能分析和优化,你来打我
2019 运维技能风向标
更安全的 rm 命令,保护重要数据
求你了,别再纠结线程池大小了!
重启大法好!线上常见问题排查手册
Docker
「Docker」 - 保存镜像 - 知乎
终于可以像使用 Docker 一样丝滑地使用 Containerd 了!
私有镜像仓库选型:Harbor VS Quay - 乐金明的博客 | Robin Blog
exec 与 entrypoint 使用脚本 | Mr.Cheng
Dockerfile 中的 CMD 与 ENTRYPOINT
使用 Docker 配置 MySQL 主从数据库 - 墨天轮
Alpine vs Distroless vs Busybox – 云原生实验室 - Kubernetes|Docker|Istio|Envoy|Hugo|Golang | 云原生
再见,Docker!
Python
Pipenv:新一代Python项目环境与依赖管理工具 - 知乎
Python list 列表实现栈和队列
Python 各种排序 | Lesley's blog
Python 中使用 dateutil 模块解析时间 - SegmentFault 思否
一个小破网站,居然比 Python 官网还牛逼
Python 打包 exe 的王炸 - Nuitka
Window
批处理中分割字符串 | 网络进行时
Windows 批处理基础命令学习 - 简书
在Windows上设置WireGuard
Windows LTSC、LTSB、Server 安装 Windows Store 应用商店
中间件
Nginx 中的 Rewrite 的重定向配置与实践
RabbitMQ 的监控
RabbitMq 最全的性能调优笔记 - SegmentFault 思否
为什么不建议生产用 Redis 主从模式?
高性能消息中间件——NATS
详解:Nginx 反代实现 Kibana 登录认证功能
分布式系统关注点:仅需这一篇,吃透 “负载均衡” 妥妥的
仅需这一篇,妥妥的吃透” 负载均衡”
基于 nginx 实现上游服务器动态自动上下线——不需 reload
Nginx 学习书单整理
最常见的日志收集架构(ELK Stack)
分布式之 elk 日志架构的演进
CAT 3.0 开源发布,支持多语言客户端及多项性能提升
Kafka 如何做到 1 秒处理 1500 万条消息?
Grafana 与 Kibana
ELK 日志系统之通用应用程序日志接入方案
ELK 简易 Nginx 日志系统搭建: ElasticSearch+Kibana+Filebeat
记一次 Redis 连接池问题引发的 RST
把 Redis 当作队列来用,你好大的胆子……
Redis 最佳实践:业务层面和运维层面优化
Redis 为什么变慢了?常见延迟问题定位与分析
好饭不怕晚,扒一下 Redis 配置文件的底 Ku
rabbitmq 集群搭建以及万级并发下的性能调优
别再问我 Redis 内存满了该怎么办了
Nginx 状态监控及日志分析
数据库
SQLite全文检索
Mysql 查看用户连接数配置及每个 IP 的请求情况 - 墨天轮
防火墙-iptables
iptables 常用规则:屏蔽 IP 地址、禁用 ping、协议设置、NAT 与转发、负载平衡、自定义链
防火墙 iptables 企业防火墙之 iptables
Linux 防火墙 ufw 简介
在 Ubuntu 中用 UFW 配置防火墙
在 Ubuntu20.04 上怎样使用 UFW 配置防火墙 - 技术库存网
监控类
开箱即用的 Prometheus 告警规则集
prometheus☞搭建 | zyh
docker 部署 Prometheus 监控服务器及容器并发送告警 | chris'wang
PromQL 常用命令 | LRF 成长记
持续集成CI/CD
GitHub Actions 的应用场景 | 记录干杯
GithubActions · Mr.li's Blog
工具类
GitHub 中的开源网络广告杀手,十分钟快速提升网络性能
SSH-Auditor:一款 SHH 弱密码探测工具
别再找了,Github 热门开源富文本编辑器,最实用的都在这里了 - srcmini
我最喜欢的 CLI 工具
推荐几款 Redis 可视化工具
内网代理工具与检测方法研究
环境篇:数据同步工具 DataX
全能系统监控工具 dstat
常用 Web 安全扫描工具合集
给你一款利器!轻松生成 Nginx 配置文件
教程类
手把手教你打造高效的 Kubernetes 命令行终端
Keras 作者:给软件开发者的 33 条黄金法则
超详细的网络抓包神器 Tcpdump 使用指南
使用 fail2ban 和 FirewallD 黑名单保护你的系统
linux 下 mysql 数据库单向同步配置方法分享 (Mysql)
MySQL 快速删除大量数据(千万级别)的几种实践方案
GitHub 上的优质 Linux 开源项目,真滴牛逼!
WireGuard 教程:使用 Netmaker 来管理 WireGuard 的配置 – 云原生实验室 - Kubernetes|Docker|Istio|Envoy|Hugo|Golang | 云原生
Tailscale 基础教程:Headscale 的部署方法和使用教程 – 云原生实验室 - Kubernetes|Docker|Istio|Envoy|Hugo|Golang | 云原生
Nebula Graph 的 Ansible 实践
改进你的 Ansible 剧本的 4 行代码
Caddy 2 快速简单安装配置教程 – 高玩梁的博客
切换至 Caddy2 | 某不科学的博客
Caddy2 简明教程 - bleem
树莓派安装 OpenWrt 突破校园网限制 | Asttear's Blog
OpenVPN 路由设置 – 凤曦的小窝
个性化编译 LEDE 固件
盘点各种 Windows/Office 激活工具
[VirtualBox] 1、NAT 模式下端口映射
VirtualBox 虚拟机安装 openwrt 供本机使用
NUC 折腾笔记 - 安装 ESXi 7 - 苏洋博客
锐捷、赛尔认证 MentoHUST - Ubuntu 中文
How Do I Use A Client Certificate And Private Key From The IOS Keychain? | OpenVPN
比特记事簿: 笔记: 使用电信 TR069 内网架设 WireGuard 隧道异地组网
利用 GitHub API 获取最新 Releases 的版本号 | 这是只兔子
docsify - 生成文档网站简单使用教程 - SegmentFault 思否
【干货】Chrome 插件 (扩展) 开发全攻略 - 好记的博客
一看就会的 GitHub 骚操作,让你看上去像一位开源大佬
【计算机网络】了解内网、外网、宽带、带宽、流量、网速_墩墩分墩 - CSDN 博客
mac-ssh 配置 | Sail
如何科学管理你的密码
VirtualBox NAT 端口映射实现宿主机与虚拟机相互通信 | Shao Guoliang 的博客
CentOS7 配置网卡为静态 IP,如果你还学不会那真的没有办法了!
laisky-blog: 近期折腾 tailscale 的一些心得
使用 acme.sh 给 Nginx 安装 Let’ s Encrypt 提供的免费 SSL 证书 · Ruby China
acme 申请 Let’s Encrypt 泛域名 SSL 证书
从 nginx 迁移到 caddy
使用 Caddy 替代 Nginx,全站升级 https,配置更加简单 - Diamond-Blog
http.proxy - Caddy 中文文档
动手撸个 Caddy(二)| Caddy 命令行参数最全教程 | 飞雪无情的总结
Caddy | 学习笔记 - ijayer
Caddy 代理 SpringBoot Fatjar 应用上传静态资源
使用 graylog3.0 收集 open××× 日志进行审计_年轻人,少吐槽,多搬砖的技术博客_51CTO 博客
提高国内访问 github 速度的 9 种方法! - SegmentFault 思否
VM16 安装 macOS 全网最详细
2022 目前三种有效加速国内 Github
How to install MariaDB on Alpine Linux | LibreByte
局域网内电脑 - ipad 文件共享的三种方法 | 岚
多机共享键鼠软件横向测评 - 尚弟的小笔记
本文档发布于https://mrdoc.fun
-
+
首页
Tcpdump
> 本文由 [简悦 SimpRead](http://ksria.com/simpread/) 转码, 原文地址 [tengwait.com](https://tengwait.com/2020/07/16/Tcpdump/) [](#关于Tcpdump抓包总结 "关于Tcpdump抓包总结")关于 Tcpdump 抓包总结 ------------------------------------------------- ### [](#一、简介 "一、简介")一、简介 tcpdump 是一个用于截取网络分组,并输出分组内容的工具。凭借强大的功能和灵活的截取策略,使其成为类 UNIX 系统下用于网络分析和问题排查的首选工具 tcpdump 提供了源代码,公开了接口,因此具备很强的可扩展性,对于网络维护和入侵者都是非常有用的工具 tcpdump 支持针对网络层、协议、主机、网络或端口的过滤,并提供 and、or、not 等逻辑语句来帮助你去掉无用的信息 When _tcpdump_ finishes capturing packets, it will report counts of: packets ``captured’’ (this is the number of packets that _tcpdump_ has received and processed); packets ``received by filter’’ (the meaning of this depends on the OS on which you’re running _tcpdump_, and possibly on the way the OS was configured - if a filter was specified on the command line, on some OSes it counts packets regardless of whether they were matched by the filter expression and, even if they were matched by the filter expression, regardless of whether _tcpdump_ has read and processed them yet, on other OSes it counts only packets that were matched by the filter expression regardless of whether _tcpdump_ has read and processed them yet, and on other OSes it counts only packets that were matched by the filter expression and were processed by _tcpdump_); packets ``dropped by kernel’’ (this is the number of packets that were dropped, due to a lack of buffer space, by the packet capture mechanism in the OS on which _tcpdump_ is running, if the OS reports that information to applications; if not, it will be reported as 0). ### [](#二、语法 "二、语法")二、语法 完整的英文文档:[https://www.tcpdump.org/tcpdump_man.html](https://www.tcpdump.org/tcpdump_man.html) * -c 在收到指定的数量的分组后,tcpdump 就会停止。 * -C 在将一个原始分组写入文件之前,检查文件当前的大小是否超过了参数 file_size 中指定的大小。如果超过了指定大小,则关闭当前文件,然后在打开一个新的文件。参数 file_size 的单位是兆字节(是 1,000,000 字节,而不是 1,048,576 字节)。 * -d 将匹配信息包的代码以人们能够理解的汇编格式给出。 * -dd 将匹配信息包的代码以 C 语言程序段的格式给出。 * -ddd 将匹配信息包的代码以十进制的形式给出。 * -D 打印出系统中所有可以用 tcpdump 截包的网络接口。 * -e 在输出行打印出数据链路层的头部信息。 * -E 用 spi@ipaddr algo:secret 解密那些以 addr 作为地址,并且包含了安全参数索引值 spi 的 IPsec ESP 分组。 * -f 将外部的 Internet 地址以数字的形式打印出来。 * -F 从指定的文件中读取表达式,忽略命令行中给出的表达式。 * -i 指定监听的网络接口。 * -l 使标准输出变为缓冲行形式,可以把数据导出到文件。 * -L 列出网络接口的已知数据链路。 * -m 从文件 module 中导入 SMI MIB 模块定义。该参数可以被使用多次,以导入多个 MIB 模块。 * -M 如果 tcp 报文中存在 TCP-MD5 选项,则需要用 secret 作为共享的验证码用于验证 TCP-MD5 选选项摘要(详情可参考 RFC 2385)。 * -b 在数据 - 链路层上选择协议,包括 ip、arp、rarp、ipx 都是这一层的。 * -n 不把网络地址转换成名字。 * -nn 不进行端口名称的转换。 * -N 不输出主机名中的域名部分。例如,‘nic.ddn.mil‘只输出’nic‘。 * -t 在输出的每一行不打印时间戳。 * -O 不运行分组分组匹配(packet-matching)代码优化程序。 * -P 不将网络接口设置成混杂模式。 * -q 快速输出。只输出较少的协议信息。 * -r 从指定的文件中读取包 (这些包一般通过 - w 选项产生)。 * -S 将 tcp 的序列号以绝对值形式输出,而不是相对值。 * -s 从每个分组中读取最开始的 snaplen 个字节,而不是默认的 68 个字节。 * -T 将监听到的包直接解释为指定的类型的报文,常见的类型有 rpc 远程过程调用)和 snmp(简单网络管理协议)。 * -t 不在每一行中输出时间戳。 * -tt 在每一行中输出非格式化的时间戳。 * -ttt 输出本行和前面一行之间的时间差。 * -tttt 在每一行中输出由 date 处理的默认格式的时间戳。 * -u 输出未解码的 NFS 句柄。 * -v 输出一个稍微详细的信息,例如在 ip 包中可以包括 ttl 和服务类型的信息。 * -vv 输出详细的报文信息。 * -w 直接将分组写入文件中,而不是不分析并打印出来。 * Ethernet Header =14 Byte =Dst Physical Address(6 Byte)+ Src Physical Address(6 Byte)+Type(2 Byte),以太网帧头以下称之为数据帧。 * IP Header =20 Byte(without options field),数据在 IP 层称为 Datagram,分片称为 Fragment。 * TCP Header = 20 Byte(without options field),数据在 TCP 层称为 Stream,分段称为 Segment(UDP 中称为 Message)。 * 54 个字节后为 TCP 数据负载部分(Data Portion),即应用层用户数据。 Ethernet Header 以下的 IP 数据报最大传输单位为 MTU(Maximum Transmission Unit,Effect of short board),对于大多数使用以太网的局域网来说,MTU=1500。 TCP 数据包每次能够传输的最大数据分段为 MSS,为了达到最佳的传输效能,在建立 TCP 连接时双方将协商 MSS 值——双方提供的 MSS 值中的最小值为这次连接的最大 MSS 值。MSS 往往基于 MTU 计算出来,通常 MSS=MTU-sizeof(IP Header)-sizeof(TCP Header)=1500-20-20=1460。 这样,数据经过本地 TCP 层分段后,交给本地 IP 层,在本地 IP 层就不需要分片了。但是在下一跳路由(Next Hop)的邻居路由器上可能发生 IP 分片!因为路由器的网卡的 MTU 可能小于需要转发的 IP 数据报的大小。 这时候,在路由器上可能发生两种情况: 1. 如果源发送端设置了这个 IP 数据包可以分片(May Fragment,DF=0),路由器将 IP 数据报分片后转发。 2. 如果源发送端设置了这个 IP 数据报不可以分片(Don’t Fragment,DF=1),路由器将 IP 数据报丢弃,并发送 ICMP 分片错误消息给源发送端。 ### [](#三、实例 "三、实例")三、实例 #### [](#1、默认启动 "1、默认启动")1、默认启动 ``` tcpdump -vv ``` #### [](#2、过滤主机 "2、过滤主机")2、过滤主机 ``` tcpdump -i eth1 host 192.168.1.1 tcpdump -i eth1 src host 192.168.1.1 tcpdump -i eth1 dst host 192.168.1.1 ``` 抓取所有经过 eth1,目的或源地址是 192.168.1.1 的网络数据 指定源地址,192.168.1.1 指定目的地址,192.168.1.1 #### [](#3、过滤端口 "3、过滤端口")3、过滤端口 ``` tcpdump -i eth1 port 25 tcpdump -i eth1 src port 25 tcpdump -i eth1 dst port 25 ``` 抓取所有经过 eth1,目的或源端口是 25 的网络数据 指定源端口 指定目的端口 #### [](#4、网络过滤 "4、网络过滤")4、网络过滤 ``` tcpdump -i eth1 net 192.168 tcpdump -i eth1 src net 192.168 tcpdump -i eth1 dst net 192.168 ``` #### [](#5、协议过滤 "5、协议过滤")5、协议过滤 ``` tcpdump -i eth1 arp tcpdump -i eth1 ip tcpdump -i eth1 tcp tcpdump -i eth1 udp tcpdump -i eth1 icmp ``` #### [](#6、常用表达式 "6、常用表达式")6、常用表达式 ``` 非 : ! or "not" (去掉双引号) 且 : && or "and" 或 : || or "or" ``` 抓取所有经过 eth1,目的地址是 192.168.1.254 或 192.168.1.200 端口是 80 的 TCP 数 ``` tcpdump -i eth1 '((tcp) and (port 80) and ((dst host 192.168.1.254) or (dst host 192.168.1.200)))' ``` 抓取所有经过 eth1,目标 MAC 地址是 00:01:02:03:04:05 的 ICMP 数据 ``` tcpdump -i eth1 '((icmp) and ((ether dst host 00:01:02:03:04:05)))' ``` 抓取所有经过 eth1,目的网络是 192.168,但目的主机不是 192.168.1.200 的 TCP 数据 ``` tcpdump -i eth1 '((tcp) and ((dst net 192.168) and (not dst host 192.168.1.200)))' ``` ### [](#四、高级过滤方式 "四、高级过滤方式")四、高级过滤方式 首先了解如何从包头过滤信息 ``` proto[x:y] : 过滤从x字节开始的y字节数。比如ip[2:2]过滤出3、4字节(第一字节从0开始排) proto[x:y] & z = 0 : proto[x:y]和z的与操作为0 proto[x:y] & z !=0 : proto[x:y]和z的与操作不为0 proto[x:y] & z = z : proto[x:y]和z的与操作为z proto[x:y] = z : proto[x:y]等于z ``` 操作符 : >, <,>=, <=, =, != ### [](#1-IP头(IPV4) "1. IP头(IPV4)")1. IP 头(IPV4) ``` 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |Version| IHL |Type of Service| Total Length | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Identification |Flags| Fragment Offset | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Time to Live | Protocol | Header Checksum | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Source Address | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Destination Address | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Options | Padding | <-- optional +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | DATA ... | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ``` 中文: ![](https://tengwait.com/image/global/17.png) ``` typedef struct _IP_HEADER { char m_cVersionAndHeaderLen; char m_cTypeOfService; short m_sTotalLenOfPacket; short m_sPacketID; short m_sSliceinfo; char m_cTTL; char m_cTypeOfProtocol; short m_sCheckSum; unsigned int m_uiSourIp; unsigned int m_uiDestIp; } __attribute__((packed))IP_HEADER, *PIP_HEADER ; ``` * **版本**:指 IP 协议的版本,通信双方使用的 IP 协议版本必须一致。一般的值为 0100(IPv4),0110(IPv6)。 * **首部长度**:长度 4 比特。这个字段的作用是为了描述 IP 包头的长度,因为在 IP 包头中有变长的可选部分。该部分占 4 个 bit 位,单位为 32bit(4 个字节),即本区域值 = IP 头部长度(单位为 bit)/(8_4),因此,一个 IP 包头的长度最长为 “1111”,即 15_4=60 个字节。IP 包头最小长度为 20 字节。 * **优先级与服务类型**:长度 8 比特,定义了数据包传输的紧急程度以及时延、可靠性、传输成本等。 * **总长度**:16 比特,以字节为单位描述 IP 包的总长度(包括头部和数据两部分),最大值为 65535。第二行中标识符、标志和段偏移量通常联合使用,用于数据拆分时的分组和重组。 * **标识符**:对于上层发来的较大的数据包,往往需要拆分。路由器将一个大包进行拆分后,拆出来的所有部分被标上相同的值,该值即为标识符,用于告诉目的端哪些包属于同一个大包。 * **标志**:长度 3 比特。该字段第一位不使用。第二位是 DF(Don’t Fragment)位,DF 位设为 1 时表明路由器不能对该上层数据包分段。如果一个上层数据包无法在不分段的情况下进行转发,则路由器会丢弃该上层数据包并返回一个错误信息。第三位是 MF(More Fragments)位,当路由器对一个上层数据包分段,则路由器会在除了最后一个分段的 IP 包的包头中将 MF 位设为 1。 * **段偏移量**:长度 13 比特,表示一个数据包在原先被拆分前的大包中的位置。接收端据此来还原和组装 IP 包。 * **TTL**:表示 IP 包的生存时间,长度 8 比特。长度 8 比特。当 IP 包进行传送时,先会对该字段赋予某个特定的值。当 IP 包经过每一个沿途的路由器的时候,每个沿途的路由器会将 IP 包的 TTL 值减少 1。如果 TTL 减少为 0,则该 IP 包会被丢弃。这个字段可以防止由于路由环路而导致 IP 包在网络中不停被转发。 * **协议号**:长度 8 比特,标识上一层即传输层在本次数据传输中所使用的协议。比如 6 代表 TCP,17 代表 UDP 等 * **首部校验和**:长度 16 位。用来做 IP 头部的正确性检测,但不包含数据部分。 因为每个路由器要改变 TTL 的值, 所以路由器会为每个通过的数据包重新计算这个值。 * **源地址**:长度 32 比特,标识 IP 包的起源地址。 * **目标地址**:长度 32 比特,表示 IP 包的目的地址。 * **可选项**:可变长字段,主要用于测试,由起源设备跟据需要改写。 * **填充**:因为 IP 包头长度(Header Length)部分的单位为 32bit,所以 IP 包头的长度必须为 32bit 的整数倍。因此,在可选项后面,IP 协议会填充若干个 0,以达到 32bit 的整数倍。 ### [](#2-IP选项 "2. IP选项")2. IP 选项 “一般” 的 IP 头是 20 字节,但 IP 头有选项设置,不能直接从偏移 21 字节处读取数据。IP 头有个长度字段可以知道头长度是否大于 20 字节。 通常第一个字节的二进制值是:01000101,分成两个部分: 0100 = 4 表示 IP 版本 0101 = 5 表示 IP 头 32 bit 的块数,5 x 32 bits = 160 bits or 20 bytes 如果第一字节第二部分的值大于 5,那么表示头有 IP 选项。 下面介绍有过滤方法 0100 0101 : 第一字节的二进制 0000 1111 : 与操作 <========= 0000 0101 : 结果 正确的过滤方法 ``` tcpdump -i eth1 'ip[0] & 15 > 5' ``` 或者 ``` tcpdump -i eth1 'ip[0] & 0x0f > 5' ``` ### [](#3-分片标记 "3. 分片标记")3. 分片标记 当发送端的 MTU 大于到目的路径链路上的 MTU 时就会被分片,分片信息在 IP 头的第七和第八字节: ``` +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |Flags| Fragment Offset | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ``` Bit 0: 保留,必须是 0 Bit 1: (DF) 0 = 可能分片, 1 = 不分片 Bit 2: (MF) 0 = 最后的分片, 1 = 还有分片 Fragment Offset 字段只有在分片的时候才使用。 要抓带 DF 位标记的不分片的包,第七字节的值应该是: 01000000 = 64 ``` tcpdump -i eth1 'ip[6] = 64' ``` ### [](#4-抓分片包 "4. 抓分片包")4. 抓分片包 * 匹配 MF,分片包 ``` tcpdump -i eth1 'ip[6] = 32' ``` 最后分片包的开始 3 位是 0,但是有 Fragment Offset 字段。 * 匹配分片和最后分片 ``` tcpdump -i eth1 '((ip > 0) and (not ip = 64))' ``` 测试分片可以用下面的命令: ``` ping -M want -s 3000 192.168.1.1 ``` ### [](#5-匹配小TTL "5. 匹配小TTL")5. 匹配小 TTL TTL 字段在第九字节,并且正好是完整的一个字节,TTL 最大值是 255,二进制为 11111111。 可以用下面的命令验证一下: ``` $ ping -M want -s 3000 -t 256 192.168.1.200 ping: ttl 256 out of range ``` ``` +-+-+-+-+-+-+-+-+ | Time to Live | +-+-+-+-+-+-+-+-+ ``` * 在网关可以用下面的命令看看网络中谁在使用 traceroute ``` tcpdump -i eth1 'ip[8] < 5' ``` ### [](#6-抓大于X字节的包 "6. 抓大于X字节的包")6. 抓大于 X 字节的包 * 大于 600 字节 ``` tcpdump -i eth1 'ip[2:2] > 600' ``` ### [](#7-更多的过滤方式 "7. 更多的过滤方式")7. 更多的过滤方式 首先还是需要知道 TCP 基本结构 * TCP 头 ``` 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Source Port | Destination Port | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Sequence Number | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Acknowledgment Number | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Data | |C|E|U|A|P|R|S|F| | | Offset| Res. |W|C|R|C|S|S|Y|I| Window | | | |R|E|G|K|H|T|N|N| | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Checksum | Urgent Pointer | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Options | Padding | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | data | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ``` ![](https://tengwait.com/image/global/18.png) ``` typedef struct _TCP_HEADER { short m_sSourPort; short m_sDestPort; unsigned int m_uiSequNum; unsigned int m_uiAcknowledgeNum; short m_sHeaderLenAndFlag; short m_sWindowSize; short m_sCheckSum; short m_surgentPointer; }__attribute__((packed))TCP_HEADER, *PTCP_HEADER; ``` 16 位源端口号和 16 位目的端口号。 32 位序号:一次 TCP 通信过程中某一个传输方向上的字节流的每个字节的编号,通过这个来确认发送的数据有序,比如现在序列号为 1000,发送了 1000,下一个序列号就是 2000。 32 位确认号:用来响应 TCP 报文段,给收到的 TCP 报文段的序号加 1,三握时还要携带自己的序号。 4 位头部长度:标识该 TCP 头部有多少个 4 字节,共表示最长 15*4=60 字节。同 IP 头部。 6 位保留。6 位标志。URG(紧急指针是否有效)ACK(表示确认号是否有效)PSH(提示接收端应用程序应该立即从 TCP 接收缓冲区读走数据)RST(表示要求对方重新建立连接)SYN(表示请求建立一个连接)FIN(表示通知对方本端要关闭连接) 16 位窗口大小:TCP 流量控制的一个手段,用来告诉对端 TCP 缓冲区还能容纳多少字节。 16 位校验和:由发送端填充,接收端对报文段执行 CRC 算法以检验 TCP 报文段在传输中是否损坏。 16 位紧急指针:一个正的偏移量,它和序号段的值相加表示最后一个紧急数据的下一字节的序号。 标志位字段(U、A、P、R、S、F):占 6 比特。各比特的含义如下: * URG:紧急指针(urgent pointer)有效。 * ACK:确认序号有效。 * PSH:接收方应该尽快将这个报文段交给应用层。 * RST:重建连接。 * SYN:发起一个连接。 * FIN:释放一个连接。 * 窗口大小字段:占 16 比特。此字段用来进行流量控制。单位为字节数,这个值是本机期望一次接收的字节数。 * TCP 校验和字段:占 16 比特。对整个 TCP 报文段,即 TCP 头部和 TCP 数据进行校验和计算,并由目标端进行验证。 * 紧急指针字段:占 16 比特。它是一个偏移量,和序号字段中的值相加表示紧急数据最后一个字节的序号。 * 选项字段:占 32 比特。可能包括” 窗口扩大因子”、” 时间戳” 等选项。 * 抓取源端口大于 1024 的 TCP 数据包 ``` tcpdump -i eth1 'tcp[0:2] > 1024' ``` * 匹配 TCP 数据包的特殊标记 ``` +-+-+-+-+-+-+-+-+ |C|E|U|A|P|R|S|F| |W|C|R|C|S|S|Y|I| |R|E|G|K|H|T|N|N| +-+-+-+-+-+-+-+-+ ``` * 只抓 SYN 包,第十四字节是二进制的 00000010,也就是十进制的 2 ``` tcpdump -i eth1 'tcp[13] = 2' ``` * 抓 SYN, ACK (00010010 or 18) ``` tcpdump -i eth1 'tcp[13] & 2 = 2' ``` * 抓 PSH-ACK ``` tcpdump -i eth1 'tcp[13] = 24' ``` * 抓所有包含 FIN 标记的包(FIN 通常和 ACK 一起,表示幽会完了,回见) ``` tcpdump -i eth1 'tcp[13] & 1 = 1' ``` * 抓 RST ``` tcpdump -i eth1 'tcp[13] & 4 = 4' ``` ### [](#8-常用的字段偏移名字 "8. 常用的字段偏移名字")8. 常用的字段偏移名字 tcpdump 考虑了一些数字恐惧症者的需求,提供了部分常用的字段偏移名字: * icmptype (ICMP 类型字段) * icmpcode (ICMP 符号字段) * tcpflags (TCP 标记字段) ICMP 类型值有: icmp-echoreply, icmp-unreach, icmp-sourcequench, icmp-redirect, icmp-echo, icmp-routeradvert, icmp-routersolicit, icmp-timxceed, icmp-paramprob, icmp-tstamp, icmp-tstampreply, icmp-ireq, icmp-ireqreply, icmp-maskreq, icmp-maskreply TCP 标记值: tcp-fin, tcp-syn, tcp-rst, tcp-push, tcp-push, tcp-ack, tcp-urg 这样上面按照 TCP 标记位抓包的就可以写直观的表达式了: * 只抓 SYN 包 ``` tcpdump -i eth1 'tcp[tcpflags] = tcp-syn' ``` * 抓 SYN, ACK ``` tcpdump -i eth1 'tcp & tcp-syn != 0 and tcp & tcp-ack != 0' ``` ### [](#9-抓SMTP数据 "9. 抓SMTP数据")9. 抓 SMTP 数据 ``` tcpdump -i eth1 '((port 25) and (tcp[(tcp[12]>>2):4] = 0x4d41494c))' ``` ### [](#10-抓HTTP-GET数据 "10. 抓HTTP GET数据")10. 抓 HTTP GET 数据 ``` tcpdump -i eth1 'tcp[(tcp[12]>>2):4] = 0x47455420' ``` ### [](#11-抓SSH返回 "11. 抓SSH返回")11. 抓 SSH 返回 ``` tcpdump -i eth1 'tcp[(tcp[12]>>2):4] = 0x5353482D' ``` “SSH-“的十六进制是 0x5353482D ``` tcpdump -i eth1 '(tcp = 0x5353482D) and (tcp = 0x312E)' ``` [](#五、比较常用的方式 "五、比较常用的方式")五、比较常用的方式 ----------------------------------- 如果是为了查看数据内容,建议用`tcpdump -s 0 -w filename`把数据包都保存下来,然后用 wireshark 的 Follow TCP Stream/Follow UDP Stream 来查看整个会话的内容。`-s 0`是抓取完整数据包,否则默认只抓 68 字节。用 tcpflow 也可以方便的获取 TCP 会话内容,支持 tcpdump 的各种表达式。 ### [](#1-UDP头 "1. UDP头")1. UDP 头 ``` 0 7 8 15 16 23 24 31 +--------+--------+--------+--------+ | Source | Destination | | Port | Port | +--------+--------+--------+--------+ | | | | Length | Checksum | +--------+--------+--------+--------+ | | | DATA ... | +-----------------------------------+ ``` ``` typedef struct _UDP_HEADER { unsigned short m_usSourPort; unsigned short m_usDestPort; unsigned short m_usLength; unsigned short m_usCheckSum; }__attribute__((packed))UDP_HEADER, *PUDP_HEADER; ``` * 抓 DNS 请求数据 ``` tcpdump -i eth1 udp dst port 53 ``` ### [](#2-系统测试 "2. 系统测试")2. 系统测试 `-c`参数对于运维人员来说也比较常用,因为流量比较大的服务器,靠人工 CTRL+C 还是抓的太多,甚至导致服务器宕机,于是可以用`-c`参数指定抓多少个包。 ``` time tcpdump -nn -i eth0 'tcp[tcpflags] = tcp-syn' -c 10000 > /dev/null ``` ### [](#3-tcpdump-与wireshark "3. tcpdump 与wireshark")3. **tcpdump 与 wireshark** Wireshark(以前是 ethereal) 是 Windows 下非常简单易用的抓包工具。但在 Linux 下很难找到一个好用的图形化抓包工具。 还好有 Tcpdump。我们可以用 Tcpdump + Wireshark 的完美组合实现:在 Linux 里抓包,然后在 Windows 里分析包。 ``` tcpdump tcp -i eth1 -t -s 0 -c 100 and dst port ! 22 and src net 192.168.1.0/24 -w ./target.cap ``` * tcp: ip icmp arp rarp 和 tcp、udp、icmp 这些选项等都要放到第一个参数的位置,用来过滤数据报的类型 * -i eth1 : 只抓经过接口 eth1 的包 * -t : 不显示时间戳 * -s 0 : 抓取数据包时默认抓取长度为 68 字节。加上 - S 0 后可以抓到完整的数据包 * -c 100 : 只抓取 100 个数据包 * dst port ! 22 : 不抓取目标端口是 22 的数据包 * src net 192.168.1.0/24 : 数据包的源网络地址为 192.168.1.0/24 * -w ./target.cap : 保存成 cap 文件,方便用 ethereal(即 wireshark) 分析 ### [](#4-使用tcpdump抓取HTTP包 "4. 使用tcpdump抓取HTTP包")4. **使用 tcpdump 抓取 HTTP 包** ``` tcpdump -XvvennSs 0 -i eth0 tcp[20:2]=0x4745 or tcp[20:2]=0x4854 ``` 0x4745 为”GET” 前两个字母”GE”,0x4854 为”HTTP” 前两个字母”HT”。 tcpdump 对截获的数据并没有进行彻底解码,数据包内的大部分内容是使用十六进制的形式直接打印输出的。显然这不利于分析网络故障,通常的解决办法是先使用带 - w 参数的 tcpdump 截获数据并保存到文件中,然后再使用其他程序 (如 Wireshark) 进行解码分析。当然也应该定义过滤规则,以避免捕获的数据包填满整个硬盘。 基本上 tcpdump 总的的输出格式为:系统时间 来源主机. 端口 > 目标主机. 端口 数据包参数 转载请注明来源,欢迎指出任何有错误或不够清晰的表达,可以邮件至 admin@tengwait.com
Jonny
2021年9月16日 12:29
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
【腾讯云】爆款2核2G4M云服务器一年45元,企业首购最高获赠300元京东卡
【腾讯云】爆款2核2G4M云服务器一年45元,企业首购最高获赠300元京东卡
Markdown文件
Word文件
PDF文档
PDF文档(打印)
分享
链接
类型
密码
更新密码
有效期