logo

网络协议流量捕获和压力测试工具比较

Published on

引言

在网络分析和调试中,捕获和分析 网络 流量是非常重要的。本文将比较三种常用的方法来捕获各种网络协议流量,包括 Python 的 scapy 库、Wireshark 的 tshark 命令、tcpdump 命令。我们将通过各种压力测试工具来评估这些方法的性能,并比较它们在捕获流量方面的优劣。

介绍

网络流量捕获工具可以帮助开发人员和网络管理员分析网络活动。本文将对以下工具进行比较:

  • scapy:一个 Python 网络包操作库。
  • tshark:Wireshark 的命令行版本。
  • tcpdump:一个命令行网络流量分析工具。

我们将通过 JMeter 生成 HTTP 流量,并比较这些工具在五秒钟内的性能表现。

工具

安装 tcpdump

在 Debian/Ubuntu 系统上:

sudo apt-get install tcpdump

安装 tshark

在 Debian/Ubuntu 系统上:

sudo apt-get install tshark

安装 scapy

使用 pip 安装:

pip install scapy

HTTP协议

使用 scapy 捕获 HTTP 流量

scapy 是一个功能强大的 Python 网络包处理库,可以用于捕获和分析网络数据包。下面的 Python 脚本展示了如何使用 scapy 捕获 HTTP 流量:

import time
import psutil
from scapy.all import *

# 用于存储捕获到的HTTP包
packets_counts = 0

# 定义数据包回调函数
def packet_callback(packet):
    if packet.haslayer(TCP) and packet.haslayer(Raw):
        raw_data = packet[Raw].load.decode(errors='ignore')
        if "HTTP" in raw_data:
            packets_counts += 1

# 获取当前进程的psutil.Process对象
process = psutil.Process()

# 捕获前的CPU和内存使用情况
cpu_usage_start = process.cpu_percent(interval=1)
memory_usage_start = process.memory_info().rss / (1024 * 1024)

# 捕获开始时间
start_time = time.time()

# 开始捕获HTTP流量
sniff(filter="tcp port 8080", prn=packet_callback, timeout=5, store=0)

# 捕获后的CPU和内存使用情况
cpu_usage_end = process.cpu_percent(interval=1)
memory_usage_end = process.memory_info().rss / (1024 * 1024)

# 捕获结束时间
end_time = time.time()

# 计算总的CPU使用率和内存占用
cpu_usage_total = cpu_usage_end - cpu_usage_start
memory_usage_total = memory_usage_end - memory_usage_start

print(f"Scapy captured {packets_counts} HTTP packets")
print(f"Total CPU usage during capture: {cpu_usage_total}%")
print(f"Total memory usage during capture: {memory_usage_total} MB")
print(f"Total time taken for capture: {end_time - start_time} seconds")

使用 tshark 捕获 HTTP 流量

tshark 是 Wireshark 的命令行版本,可以高效地捕获和分析网络流量。以下命令捕获五秒钟内的 HTTP 流量:

tshark -i <interface> -f "tcp port 80" -a duration:5 -Y "http" -w tshark_output.pcap

在运行此命令时,还需要获取 CPU使用率和内存占用率,因此改写代码如下:

import time
import psutil
import subprocess

# 启动 tshark 进程捕获 HTTP 流量
tshark_command = ["tshark", "-i", "eth0", "-f", "tcp port 8080", "-a", "duration:5", "-w", "tshark_output.pcap"]
tshark_process = subprocess.Popen(tshark_command)

# 等待 tshark 进程启动
time.sleep(1)

# 获取 tshark 进程的 psutil.Process 对象
tshark_pid = tshark_process.pid
tshark_psutil_process = psutil.Process(tshark_pid)

# 捕获期间的CPU和内存使用情况
cpu_usage_start = tshark_psutil_process.cpu_percent(interval=1)
memory_usage_start = tshark_psutil_process.memory_info().rss / (1024 * 1024)

# 记录捕获开始时间
start_time = time.time()

# 监控 tshark 进程持续时间
capture_duration = 5
while time.time() - start_time < capture_duration:
    cpu_usage_current = tshark_psutil_process.cpu_percent(interval=1)
    memory_usage_current = tshark_psutil_process.memory_info().rss / (1024 * 1024)
    print(f"Current CPU usage: {cpu_usage_current}%")
    print(f"Current memory usage: {memory_usage_current} MB")
    time.sleep(1)

# 捕获结束后的CPU和内存使用情况
cpu_usage_end = tshark_psutil_process.cpu_percent(interval=1)
memory_usage_end = tshark_psutil_process.memory_info().rss / (1024 * 1024)

# 记录捕获结束时间
end_time = time.time()

# 计算总的CPU使用率和内存占用
cpu_usage_total = cpu_usage_end - cpu_usage_start
memory_usage_total = memory_usage_end - memory_usage_start

# 打印结果
print(f"Tshark captured packets for {capture_duration} seconds")
print(f"Total CPU usage during capture: {cpu_usage_total}%")
print(f"Total memory usage during capture: {memory_usage_total} MB")
print(f"Total time taken for capture: {end_time - start_time} seconds")

使用 tcpdump 捕获 HTTP 流量

tcpdump 是一个命令行工具,用于捕获和分析网络数据包。以下命令将捕获五秒钟内的 HTTP 流量:

tcpdump -i <interface> 'tcp port 80' -G 5 -w tcpdump_output.pcap

tcpdump 命令同理

import time
import psutil
import subprocess

# 启动 tcpdump 进程捕获 HTTP 流量
tcpdump_command = ["tcpdump", "-i", "eth0", "tcp port 80", "-w", "tcpdump_output.pcap"]
tcpdump_process = subprocess.Popen(tcpdump_command)

# 等待 tcpdump 进程启动
time.sleep(1)

# 获取 tcpdump 进程的 psutil.Process 对象
tcpdump_pid = tcpdump_process.pid
tcpdump_psutil_process = psutil.Process(tcpdump_pid)

# 捕获期间的CPU和内存使用情况
cpu_usage_start = tcpdump_psutil_process.cpu_percent(interval=1)
memory_usage_start = tcpdump_psutil_process.memory_info().rss / (1024 * 1024)

# 记录捕获开始时间
start_time = time.time()

# 监控 tcpdump 进程持续时间
capture_duration = 5
while time.time() - start_time < capture_duration:
    cpu_usage_current = tcpdump_psutil_process.cpu_percent(interval=1)
    memory_usage_current = tcpdump_psutil_process.memory_info().rss / (1024 * 1024)
    print(f"Current CPU usage: {cpu_usage_current}%")
    print(f"Current memory usage: {memory_usage_current} MB")
    time.sleep(1)

# 捕获结束后的CPU和内存使用情况
cpu_usage_end = tcpdump_psutil_process.cpu_percent(interval=1)
memory_usage_end = tcpdump_psutil_process.memory_info().rss / (1024 * 1024)

# 记录捕获结束时间
end_time = time.time()

# 终止 tcpdump 进程
tcpdump_process.terminate()

# 计算总的CPU使用率和内存占用
cpu_usage_total = cpu_usage_end - cpu_usage_start
memory_usage_total = memory_usage_end - memory_usage_start

# 打印结果
print(f"tcpdump captured packets for {capture_duration} seconds")
print(f"Total CPU usage during capture: {cpu_usage_total}%")
print(f"Total memory usage during capture: {memory_usage_total} MB")
print(f"Total time taken for capture: {end_time - start_time} seconds")

DNS协议

安装工具

安装 dnsperf

  1. 下载源码:

    wget https://www.dns-oarc.net/files/dnsperf/dnsperf-2.14.0.tar.gz
    tar -xzvf dnsperf-2.14.0.tar.gz
     cd dnsperf-2.14.0/
    
  2. 编译和安装:

    ./configure
    make
    sudo make install
    

使用 scapy 捕获 DNS 流量

创建一个名为 scapy_dns_capture.py 的 Python 脚本:

import time
import psutil
from scapy.all import *

packets_count = 0

def packet_callback(packet):
    global packets_count
    if packet.haslayer(DNS):
        packets_count += 1

process = psutil.Process()

cpu_usage_start = process.cpu_percent(interval=1)
memory_usage_start = process.memory_info().rss / (1024 * 1024)

start_time = time.time()

sniff(filter="udp port 53", prn=packet_callback, timeout=60, store=0)

cpu_usage_end = process.cpu_percent(interval=1)
memory_usage_end = process.memory_info().rss / (1024 * 1024)

end_time = time.time()

cpu_usage_total = cpu_usage_end - cpu_usage_start
memory_usage_total = memory_usage_end - memory_usage_start

print(f"Scapy captured {packets_count} DNS packets")
print(f"Total CPU usage: {cpu_usage_total}%")
print(f"Total memory usage: {memory_usage_total:.2f} MB")
print(f"Total time: {end_time - start_time:.2f} seconds")

运行脚本:

sudo python3 scapy_dns_capture.py

使用 tshark 捕获 DNS 流量

创建一个名为 tshark_dns_capture.py 的 Python 脚本:

import time
import psutil
import subprocess

tshark_command = ["tshark", "-i", "eth0", "-f", "udp port 53", "-a", "duration:60", "-w", "tshark_dns_output.pcap"]
tshark_process = subprocess.Popen(tshark_command)

time.sleep(1)

tshark_pid = tshark_process.pid
tshark_psutil_process = psutil.Process(tshark_pid)

cpu_usage_start = tshark_psutil_process.cpu_percent(interval=1)
memory_usage_start = tshark_psutil_process.memory_info().rss / (1024 * 1024)

start_time = time.time()

capture_duration = 60
while time.time() - start_time < capture_duration:
    cpu_usage_current = tshark_psutil_process.cpu_percent(interval=1)
    memory_usage_current = tshark_psutil_process.memory_info().rss / (1024 * 1024)
    print(f"Current CPU usage: {cpu_usage_current}%")
    print(f"Current memory usage: {memory_usage_current:.2f} MB")
    time.sleep(5)

cpu_usage_end = tshark_psutil_process.cpu_percent(interval=1)
memory_usage_end = tshark_psutil_process.memory_info().rss / (1024 * 1024)

end_time = time.time()

cpu_usage_total = cpu_usage_end - cpu_usage_start
memory_usage_total = memory_usage_end - memory_usage_start

print(f"Tshark captured packets for {capture_duration} seconds")
print(f"Total CPU usage: {cpu_usage_total}%")
print(f"Total memory usage: {memory_usage_total:.2f} MB")
print(f"Total time: {end_time - start_time:.2f} seconds")

# 使用 tshark 分析捕获的文件
packets_count = subprocess.check_output(["tshark", "-r", "tshark_dns_output.pcap", "-Y", "dns", "-c", "1"]).decode().strip().split()[0]
print(f"Tshark captured {packets_count} DNS packets")

运行脚本:

sudo python3 tshark_dns_capture.py

使用 tcpdump 捕获 DNS 流量

创建一个名为 tcpdump_dns_capture.py 的 Python 脚本:

import time
import psutil
import subprocess

tcpdump_command = ["tcpdump", "-i", "eth0", "udp port 53", "-w", "tcpdump_dns_output.pcap"]
tcpdump_process = subprocess.Popen(tcpdump_command)

time.sleep(1)

tcpdump_pid = tcpdump_process.pid
tcpdump_psutil_process = psutil.Process(tcpdump_pid)

cpu_usage_start = tcpdump_psutil_process.cpu_percent(interval=1)
memory_usage_start = tcpdump_psutil_process.memory_info().rss / (1024 * 1024)

start_time = time.time()

capture_duration = 60
while time.time() - start_time < capture_duration:
    cpu_usage_current = tcpdump_psutil_process.cpu_percent(interval=1)
    memory_usage_current = tcpdump_psutil_process.memory_info().rss / (1024 * 1024)
    print(f"Current CPU usage: {cpu_usage_current}%")
    print(f"Current memory usage: {memory_usage_current:.2f} MB")
    time.sleep(5)

tcpdump_process.terminate()

cpu_usage_end = tcpdump_psutil_process.cpu_percent(interval=1)
memory_usage_end = tcpdump_psutil_process.memory_info().rss / (1024 * 1024)

end_time = time.time()

cpu_usage_total = cpu_usage_end - cpu_usage_start
memory_usage_total = memory_usage_end - memory_usage_start

print(f"tcpdump captured packets for {capture_duration} seconds")
print(f"Total CPU usage: {cpu_usage_total}%")
print(f"Total memory usage: {memory_usage_total:.2f} MB")
print(f"Total time: {end_time - start_time:.2f} seconds")

# 使用 tcpdump 分析捕获的文件
packets_count = subprocess.check_output(["tcpdump", "-r", "tcpdump_dns_output.pcap", "udp port 53", "-c", "1"]).decode().strip().split()[0]
print(f"tcpdump captured {packets_count} DNS packets")

运行脚本:

sudo python3 tcpdump_dns_capture.py

ICMP协议

对 ICMP(Internet Control Message Protocol)进行压力测试可以帮助评估网络设备或网络链路在接收大量 ICMP 请求时的性能和稳定性。常见的 ICMP 请求是 ping 命令,它发送 ICMP Echo 请求以检查目标主机是否可达及其响应时间。

压力测试工具

  1. ping 命令: ping 可以用于简单的 ICMP 压力测试。通过不断发送 ping 请求来模拟负载。

  2. fping 工具: fping 是一个高效的 ping 工具,支持同时对多个主机进行 ICMP 请求,非常适合进行压力测试。

  3. hping 工具: hping 是一个强大的网络工具,可以生成自定义的 ICMP 请求,并进行复杂的网络测试。

  4. nping 工具: nping 是 nmap 套件中的一部分,用于生成和发送自定义的网络数据包,包括 ICMP 数据包。

使用

使用 ping 进行压力测试

ping 命令可以用来简单的 ICMP 压力测试:

ping -f -i 0.1 <target-ip>
  • -f:快速发送 ICMP 请求。
  • -i:设置发送间隔(单位为秒),这里设置为 0.1 秒。

注意:快速发送 ICMP 请求可能会导致目标主机或网络设备的负载增加,因此请确保你有权限进行这种测试,以避免对目标设备造成过度负荷。

使用 fping 进行压力测试

fping 支持同时对多个主机发送 ICMP 请求,非常适合进行大规模测试:

fping -f hosts.txt -p 10 -c 100
  • -f hosts.txt:指定包含要测试的主机 IP 地址的文件。
  • -p 10:设置发送间隔为 10 毫秒。
  • -c 100:发送 100 个 ICMP 请求。

使用 hping 进行压力测试

hping 可以发送自定义的 ICMP 请求,进行更复杂的压力测试:

hping3 --icmp -i u1000 -c 1000 <target-ip>
  • --icmp:发送 ICMP 请求。
  • -i u1000:设置发送间隔为 1000 微秒(1 毫秒)。
  • -c 1000:发送 1000 个请求。

使用 nping 进行压力测试

nping 可以生成和发送 ICMP 请求:

nping --icmp -c 1000 --rate 100 <target-ip>
  • --icmp:发送 ICMP 请求。
  • -c 1000:发送 1000 个请求。
  • --rate 100:每秒发送 100 个请求。
工具名称主要语言支持平台主要特性GitHub 链接优点缺点
tsharkC跨平台 (Windows, Linux, macOS)1. 命令行版的 Wireshark
2. 强大的过滤和分析功能
3. 支持多种协议
tshark1. 功能全面
2. 高度可定制
3. 强大的社区支持
1. 学习曲线较陡
2. 命令行操作可能不够直观
tcpdumpC主要用于 Unix-like 系统1. 轻量级数据包分析器
2. 强大的过滤语法
3. 可以保存捕获的数据包
tcpdump1. 简单快速
2. 资源消耗低
3. 广泛应用于脚本和自动化
1. 功能相对基础
2. 不支持图形界面
3. 在 Windows 上需要额外配置
scapyPython跨平台 (Windows, Linux, macOS)1. 数据包操作库
2. 可以发送、嗅探、解析和伪造网络数据包
3. 交互式界面
scapy1. 高度灵活和可编程
2. Python 生态系统集成
3. 适合快速原型开发
1. 性能可能不如 C 语言工具
2. 需要 Python 知识
3. documentation可能不够全面
snortC跨平台 (主要用于 Unix-like 系统, 也支持 Windows)1. 实时流量分析
2. 数据包日志记录
3. 协议分析
snort1. 强大的入侵检测系统
2. 大型规则库
3. 活跃的社区支持
1. 配置复杂
2. 可能产生误报
3. 高流量下性能可能下降
arkime (原 Moloch)Node.js, C++主要用于 Linux1. 大规模全数据包捕获
2. 索引和搜索
3. 可视化界面
arkime1. 适合大规模数据分析
2. 强大的搜索功能
3. 友好的 Web 界面
1. 安装和配置复杂
2. 资源需求高
3. 主要针对大型网络
zeek (原 Bro)C++, 自定义脚本语言主要用于 Unix-like 系统1. 网络安全监控
2. 流量分析
3. 高度可定制的脚本系统
zeek1. 深度包检测能力强
2. 灵活的事件驱动编程
3. 适合复杂的网络分析任务
1. 学习曲线陡峭
2. 配置复杂
3. 资源消耗相对较高