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 工具npingnmap 套件中的一部分,用于生成和发送自定义的网络数据包,包括 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. 资源消耗相对较高