tcpdump 是一个功能强大的命令行网络数据包分析工具,用于捕获、显示和分析网络流量。它是网络管理员、安全专家和开发人员必备的网络调试工具,可以深入分析TCP/IP协议栈的各个层面。
在基于Debian/Ubuntu的系统上安装:
sudo apt-get update
sudo apt-get install tcpdump
在基于RHEL/CentOS的系统上安装:
sudo yum install tcpdump
# 或者
sudo dnf install tcpdump
在基于Arch Linux的系统上安装:
sudo pacman -S tcpdump
在macOS上安装(通过Homebrew):
brew install tcpdump
tcpdump [选项] [表达式]
| 选项 | 说明 |
|---|---|
-i 接口 |
指定要监听的网络接口(如eth0、wlan0) |
-c 数量 |
捕获指定数量的数据包后退出 |
-n |
不将地址转换为主机名(禁用DNS解析) |
-nn |
不将地址和端口转换为主机名和服务名 |
-v, -vv, -vvv |
详细输出模式,v越多越详细 |
-s 长度 |
设置捕获数据包的长度(默认96字节) |
-w 文件 |
将捕获的数据包写入文件(pcap格式) |
-r 文件 |
从文件读取数据包进行分析 |
-A |
以ASCII格式显示数据包内容 |
-X |
以十六进制和ASCII格式显示数据包内容 |
-q |
快速输出模式,显示较少信息 |
-l |
行缓冲模式,适合管道处理 |
-D |
列出可用的网络接口 |
-e |
显示数据链路层头部信息 |
--version |
显示版本信息 |
# 列出所有可用接口
tcpdump -D
# 或
tcpdump --list-interfaces
# 使用ip命令查看接口
ip addr show
# 使用ifconfig查看接口
ifconfig -a
输出示例:
1.eth0
2.eth1
3.wlan0
4.any (Pseudo-device that captures on all interfaces)
5.lo [Loopback]
sudo tcpdump -i any
sudo tcpdump -i eth0
sudo tcpdump -i eth0 -c 10
sudo tcpdump -i eth0 -n
sudo tcpdump -i eth0 -v
sudo tcpdump -i eth0 -vv
sudo tcpdump -i eth0 -vvv
tcpdump支持强大的BPF(Berkeley Packet Filter)过滤器语法:
# 捕获与特定主机的所有通信
sudo tcpdump host 192.168.1.100
# 捕获来源或目标为特定主机的数据包
sudo tcpdump src host 192.168.1.100
sudo tcpdump dst host 192.168.1.100
# 使用主机名
sudo tcpdump host example.com
# 捕获特定端口的数据包
sudo tcpdump port 80
sudo tcpdump port 443
# 捕获来源端口
sudo tcpdump src port 22
# 捕获目标端口
sudo tcpdump dst port 53
# 端口范围
sudo tcpdump portrange 20-23
# 捕获特定网络的流量
sudo tcpdump net 192.168.1.0/24
sudo tcpdump src net 192.168.1.0/24
sudo tcpdump dst net 192.168.1.0/24
# 捕获特定协议的数据包
sudo tcpdump icmp
sudo tcpdump tcp
sudo tcpdump udp
sudo tcpdump arp
sudo tcpdump icmp6
# 使用逻辑运算符
sudo tcpdump host 192.168.1.100 and port 80
sudo tcpdump src host 192.168.1.100 and dst port 443
sudo tcpdump host 192.168.1.100 and not port 22
sudo tcpdump port 80 or port 443
sudo tcpdump "(src host 192.168.1.100 and dst port 80) or (dst host 192.168.1.100 and src port 80)"
# 捕获TCP SYN包
sudo tcpdump 'tcp[tcpflags] & tcp-syn != 0'
# 捕获TCP SYN-ACK包
sudo tcpdump 'tcp[tcpflags] & tcp-syn != 0 and tcp[tcpflags] & tcp-ack != 0'
# 捕获TCP RST包
sudo tcpdump 'tcp[tcpflags] & tcp-rst != 0'
# 捕获TCP FIN包
sudo tcpdump 'tcp[tcpflags] & tcp-fin != 0'
# 捕获大于指定大小的数据包
sudo tcpdump greater 1000
# 捕获小于指定大小的数据包
sudo tcpdump less 100
# 捕获特定大小的数据包
sudo tcpdump length == 64
# 捕获包含特定字符串的数据包
sudo tcpdump -A 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)'
# 捕获HTTP流量
sudo tcpdump -i eth0 -A 'tcp port 80'
# 捕获特定网站的HTTP流量
sudo tcpdump -i eth0 -A 'host example.com and tcp port 80'
# 捕获HTTP GET请求
sudo tcpdump -i eth0 -s 0 -A 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420'
# 捕获DNS查询和响应
sudo tcpdump -i eth0 -n 'udp port 53'
# 捕获特定域名的DNS查询
sudo tcpdump -i eth0 -n 'udp port 53 and dst host 8.8.8.8'
# 捕获SSH连接尝试
sudo tcpdump -i eth0 'tcp port 22'
# 捕获到特定主机的SSH连接
sudo tcpdump -i eth0 'tcp port 22 and host 192.168.1.100'
# 捕获ICMP Echo请求和回复
sudo tcpdump -i eth0 icmp
# 捕获特定主机的Ping流量
sudo tcpdump -i eth0 'icmp and host 8.8.8.8'
# 以十六进制和ASCII格式显示
sudo tcpdump -i eth0 -X 'tcp port 80'
# 以ASCII格式显示
sudo tcpdump -i eth0 -A 'tcp port 80'
# 显示数据链路层头部
sudo tcpdump -i eth0 -e 'tcp port 80'
# 将数据包保存到文件
sudo tcpdump -i eth0 -w capture.pcap
# 保存特定流量
sudo tcpdump -i eth0 -w http.pcap 'tcp port 80'
# 从文件读取数据包
tcpdump -r capture.pcap
# 从文件读取并过滤
tcpdump -r capture.pcap 'tcp port 80'
15:30:45.123456 IP 192.168.1.100.51234 > 93.184.216.34.80: Flags [S], seq 1234567890, win 64240, options [mss 1460,sackOK,TS val 1000 ecr 0,nop,wscale 7], length 0
| 字段 | 说明 | 示例值 |
|---|---|---|
| 时间戳 | 数据包捕获时间 | 15:30:45.123456 |
| 协议 | 网络层协议 | IP |
| 来源 | 源IP地址和端口 | 192.168.1.100.51234 |
| 目标 | 目标IP地址和端口 | 93.184.216.34.80 |
| Flags | TCP标志位 | [S] (SYN) |
| seq | 序列号 | 1234567890 |
| win | 窗口大小 | 64240 |
| options | TCP选项 | [mss 1460,...] |
| length | 数据长度 | 0 |
| 标志 | 说明 | 含义 |
|---|---|---|
| S | SYN | 连接建立请求 |
| . | ACK | 确认 |
| P | PSH | 推送数据 |
| F | FIN | 连接终止 |
| R | RST | 连接重置 |
| U | URG | 紧急数据 |
| E | ECE | ECN-Echo |
| C | CWR | 拥塞窗口减少 |
# 只捕获头部,不捕获数据
sudo tcpdump -i eth0 -s 0
# 捕获前96字节(默认)
sudo tcpdump -i eth0 -s 96
# 捕获完整数据包
sudo tcpdump -i eth0 -s 65535
# 使用-nn禁用DNS解析
sudo tcpdump -i eth0 -nn
# 使用-q快速输出模式
sudo tcpdump -i eth0 -q
# 将输出重定向到文件而不是屏幕
sudo tcpdump -i eth0 -w /tmp/capture.pcap
# 使用BPF过滤器减少处理的数据量
sudo tcpdump -i eth0 'tcp port 80'
| 工具 | 说明 | 特点 |
|---|---|---|
wireshark |
图形化网络协议分析器 | 功能强大,支持深度分析,GUI界面 |
tshark |
Wireshark的命令行版本 | 命令行操作,适合脚本处理 |
ngrep |
网络grep工具 | 基于正则表达式过滤网络数据 |
tcpflow |
TCP流重组工具 | 重建TCP会话内容 |
tcpreplay |
网络流量重放工具 | 重放捕获的网络流量 |
nmap |
网络探测和安全审计工具 | 端口扫描、服务识别 |
netstat |
网络连接统计工具 | 显示网络连接、路由表等 |
ss |
socket统计工具 | netstat的现代替代品 |
tcpdump: eth0: You don't have permission to capture on that device
(socket: Operation not permitted)
解决方案:
# 使用sudo
sudo tcpdump -i eth0
# 或添加用户到特定组
sudo usermod -aG wireshark $USER
# 注销重新登录后生效
tcpdump: eth0: No such device exists
(BIOCSETIF: No such device)
解决方案:
# 查看可用接口
tcpdump -D
ip addr show
# 使用正确的接口名
sudo tcpdump -i wlp3s0 # 无线接口示例
sudo tcpdump -i enp0s3 # 有线接口示例
# tcpdump运行但没有显示任何数据包
解决方案:
# 1. 检查接口是否正确
sudo tcpdump -i any # 捕获所有接口
# 2. 检查网络连接
ping 8.8.8.8
# 3. 检查防火墙设置
sudo iptables -L
# 4. 尝试更宽泛的过滤器
sudo tcpdump -i eth0 icmp
sudo tcpdump -i eth0 arp
#!/bin/bash
# monitor_http_post.sh - 监控HTTP POST请求
INTERFACE="eth0"
LOG_FILE="/var/log/http_post.log"
echo "开始监控HTTP POST请求..."
echo "接口: $INTERFACE"
echo "日志文件: $LOG_FILE"
echo "按Ctrl+C停止监控"
echo ""
# 清理旧日志
> "$LOG_FILE"
# 开始监控
sudo tcpdump -i "$INTERFACE" -A -s 0 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)' | \
while read line; do
if echo "$line" | grep -q "POST"; then
echo "$(date '+%Y-%m-%d %H:%M:%S') - 检测到POST请求:" >> "$LOG_FILE"
echo "$line" >> "$LOG_FILE"
echo "---" >> "$LOG_FILE"
fi
done
#!/bin/bash
# traffic_stats.sh - 网络流量统计
INTERFACE="eth0"
DURATION=60
OUTPUT_FILE="/tmp/traffic_stats.txt"
echo "开始捕获网络流量,持续时间: ${DURATION}秒"
echo "接口: $INTERFACE"
echo ""
# 捕获流量并统计
sudo timeout $DURATION tcpdump -i "$INTERFACE" -n -q 2>/dev/null | \
awk '{
if ($1 == "listening") next
# 提取协议
split($1, a, ".")
protocol = a[1]
# 提取源IP和目标IP
if (protocol == "IP") {
src_ip = $3
dst_ip = $5
# 清理端口号
sub(/\.[0-9]+$/, "", src_ip)
sub(/:[0-9]+$/, "", dst_ip)
# 统计
src_count[src_ip]++
dst_count[dst_ip]++
total_packets++
}
} END {
print "=== 流量统计报告 ==="
print "总数据包数: " total_packets
print "持续时间: '"$DURATION"' 秒"
print ""
print "=== 来源IP统计 (前10) ==="
for (ip in src_count) {
print ip ": " src_count[ip] " 个数据包"
}
print ""
print "=== 目标IP统计 (前10) ==="
for (ip in dst_count) {
print ip ": " dst_count[ip] " 个数据包"
}
}' > "$OUTPUT_FILE"
echo "统计完成,结果保存在: $OUTPUT_FILE"
cat "$OUTPUT_FILE"
(host 192.168.1.100 and port 80) or (host 192.168.1.200 and port 443)-C和-W选项轮转捕获文件-c限制捕获数量,避免系统过载-r读取保存的pcap文件进行离线分析# 1. 使用tcpdump捕获数据包
sudo tcpdump -i eth0 -w capture.pcap 'tcp port 80'
# 2. 使用Wireshark分析
wireshark capture.pcap
# 3. 或使用tshark(Wireshark命令行版本)分析
tshark -r capture.pcap
tshark -r capture.pcap -Y "http.request.method == GET"
# 4. 实时捕获并分析
sudo tcpdump -i eth0 -U -w - 'tcp port 80' | wireshark -k -i -
| 用途 | 命令 |
|---|---|
| 基本捕获 | sudo tcpdump -i eth0 |
| 捕获HTTP流量 | sudo tcpdump -i eth0 -A 'tcp port 80' |
| 捕获DNS查询 | sudo tcpdump -i eth0 -n 'udp port 53' |
| 捕获到特定主机的流量 | sudo tcpdump -i eth0 'host 192.168.1.100' |
| 捕获TCP SYN包 | sudo tcpdump 'tcp[tcpflags] & tcp-syn != 0' |
| 保存到文件 | sudo tcpdump -i eth0 -w capture.pcap |
| 从文件读取 | tcpdump -r capture.pcap |
| 显示详细输出 | sudo tcpdump -i eth0 -vvv |
| 禁用DNS解析 | sudo tcpdump -i eth0 -n |
| 捕获指定数量 | sudo tcpdump -i eth0 -c 100 |