Skip to content

Latest commit

 

History

History
1109 lines (811 loc) · 41.8 KB

File metadata and controls

1109 lines (811 loc) · 41.8 KB

English | 简体中文

使用指南

本文档涵盖 RustNet 的详细使用说明,包括命令行选项、键盘控制、过滤、排序以及理解连接生命周期。

目录

运行 RustNet

在大多数系统上,数据包捕获需要提升的特权。详细的权限配置说明参见 INSTALL.zh-CN.md

快速开始:

# 使用 sudo 运行(适用于所有平台)
sudo rustnet

# 或授予 Linux capabilities 以无需 sudo 运行(详情参见 INSTALL.md)
# Linux 示例(现代内核 5.8+):
sudo setcap 'cap_net_raw,cap_bpf,cap_perfmon+eip' /path/to/rustnet
rustnet

基本使用示例:

# 使用默认设置运行
# macOS:使用 PKTAP 获取进程元数据
# Linux/其他:自动检测活动接口
rustnet

# 指定网络接口
rustnet -i eth0
rustnet --interface wlan0

# Linux:同时监控所有接口
rustnet -i any

# 过滤掉 localhost 连接(默认已过滤)
rustnet --no-localhost

# 显示 localhost 连接(覆盖默认过滤)
rustnet --show-localhost

# 设置 UI 刷新间隔(毫秒)
rustnet -r 500
rustnet --refresh-interval 2000

# 禁用深度包检测
rustnet --no-dpi

# 禁用反向 DNS 查找(默认启用)
rustnet --no-resolve-dns

# 使用指定级别启用日志(选项:error、warn、info、debug、trace)
rustnet -l debug
rustnet --log-level info

# 查看帮助和所有选项
rustnet --help

命令行选项

Usage: rustnet [OPTIONS]

Options:
  -i, --interface <INTERFACE>            要监控的网络接口
      --no-localhost                     过滤掉 localhost 连接(默认:已过滤)
      --show-localhost                   显示 localhost 连接(覆盖默认过滤)
  -r, --refresh-interval <MILLISECONDS>  UI 刷新间隔,单位为毫秒 [默认:1000]
      --no-dpi                           禁用深度包检测
      --no-resolve-dns                   禁用反向 DNS 查找(默认启用)
      --show-ptr-lookups                 显示 PTR 查找连接(默认隐藏)
  -l, --log-level <LEVEL>                设置日志级别(如果未提供,则不启用日志)
      --json-log <FILE>                  将连接事件以 JSON 格式记录到指定文件
      --pcap-export <FILE>               将捕获的数据包导出到 PCAP 文件供 Wireshark 分析
      --no-color                         禁用 UI 中的所有颜色(同时尊重 NO_COLOR 环境变量)
      --geoip-country <PATH>             GeoLite2-Country.mmdb 的路径(未指定时自动发现)
      --geoip-asn <PATH>                 GeoLite2-ASN.mmdb 的路径(未指定时自动发现)
      --geoip-city <PATH>                GeoLite2-City.mmdb 的路径(未指定时自动发现)
      --no-geoip                         完全禁用 GeoIP 查询
  -f, --bpf-filter <FILTER>              用于数据包捕获的 BPF 过滤器表达式
      --no-sandbox                       禁用 Landlock 沙箱(仅限 Linux)
      --sandbox-strict                   要求完整沙箱强制执行,否则退出(仅限 Linux)
  -h, --help                             打印帮助
  -V, --version                          打印版本

选项详情

-i, --interface <INTERFACE>

指定要监控的网络接口。

默认行为(无 -i 标志):

  • macOS:自动使用 PKTAP 获取增强型进程元数据(需要 sudo)
  • Linux/其他:自动检测第一个可用的非回环接口

示例:

# 默认:自动检测接口(macOS 上使用 PKTAP)
rustnet

# Linux:使用特殊的 "any" 伪接口监控所有接口
rustnet -i any

# 监控特定接口
rustnet -i eth0          # 监控以太网接口
rustnet -i wlan0         # 监控 WiFi 接口
rustnet -i en0           # 监控 macOS 主接口

# 监控 VPN 和隧道接口(TUN/TAP 支持)
rustnet -i utun0         # macOS VPN 隧道(TUN,Layer 3)
rustnet -i tun0          # Linux/BSD VPN 隧道(TUN,Layer 3)
rustnet -i tap0          # TAP 接口(Layer 2,包含 Ethernet)

TUN/TAP 接口支持:

RustNet 完全支持监控 VPN 和虚拟网络接口:

  • TUN 接口(Layer 3):直接承载 IP 数据包,不含 Ethernet 头部

    • VPN 常见:WireGuard、OpenVPN(tun 模式)、Tailscale
    • 示例:utun0-utun9(macOS)、tun0-tun9(Linux/BSD)
  • TAP 接口(Layer 2):包含完整的 Ethernet 帧

    • 用于:OpenVPN(tap 模式)、QEMU/KVM 虚拟网络、Docker
    • 示例:tap0-tap9(Linux/BSD)

RustNet 自动检测 TUN/TAP 接口并相应调整数据包解析。接口类型显示在 UI 状态区域。

平台特定说明:

  • macOS:不使用 -i 时自动使用 PKTAP 以获得更好的进程检测。使用 -i <interface> 来监控特定接口
  • Linux:使用 -i any 同时在所有接口上捕获(其他平台不可用)
  • TUN/TAP:所有平台均完全支持 —— RustNet 通过名称检测接口类型并调整解析
  • 所有平台:如果指定了不存在的接口,会显示错误并列出可用接口

查找你的接口:

  • Linux:ip link showifconfig
  • macOS:ifconfignetworksetup -listallhardwareports
  • Windows:ipconfig /all

--no-localhost / --show-localhost

控制是否显示 localhost(127.0.0.1/::1)连接。

  • 默认:过滤掉 localhost 连接(--no-localhost
  • 覆盖:使用 --show-localhost 查看 localhost 连接

这对于减少连接列表中的噪音很有用,因为大多数用户不需要监控本地 IPC 连接。

-r, --refresh-interval <MILLISECONDS>

以毫秒为单位设置 UI 刷新率。较低的值提供更灵敏的更新,但会增加 CPU 使用率。

建议:

  • 默认(1000ms):大多数用户的良好平衡
  • 高流量网络(2000ms):在繁忙网络上降低 CPU 使用率
  • 实时监控(500ms):更灵敏的更新,适合快速分析
  • 低端系统(2000-3000ms):降低资源受限机器上的负载

--no-dpi

禁用深度包检测(DPI)。这在高流量网络上可降低 20-40% 的 CPU 使用率,但会禁用:

  • HTTP 主机检测
  • HTTPS/TLS SNI 提取
  • DNS 查询/响应检测
  • SSH 版本识别
  • QUIC 协议检测

适用于性能受限的环境或不需要应用层详细信息时。

--no-resolve-dns / --show-ptr-lookups

反向 DNS 查找默认启用:IP 地址在后台解析为主机名,并显示在连接列表中(按 d 键切换)和详情标签页中。

  • --no-resolve-dns:完全禁用反向 DNS 解析。连接列表仅显示 IP 地址,不发起 PTR 查询。
  • --show-ptr-lookups:PTR 查找流量默认隐藏。使用此标志显示解析器生成的 DNS PTR 查询。

注意:解析后的主机名也包含在 JSON 日志中(destination_hostnamesource_hostname 字段)。

-f, --bpf-filter <FILTER>

应用 BPF(Berkeley Packet Filter)表达式在捕获时过滤数据包。这比应用层过滤更高效,因为数据包在到达 RustNet 之前在内核中被过滤。

常见过滤器表达式:

# 按端口过滤(匹配源 OR 目的)
rustnet --bpf-filter "port 443"
rustnet --bpf-filter "port 80 or port 8080"

# 按目的端口过滤
rustnet --bpf-filter "dst port 443"
rustnet --bpf-filter "tcp dst port 80"

# 按源端口过滤
rustnet --bpf-filter "src port 443"

# 按主机过滤
rustnet --bpf-filter "host 192.168.1.1"
rustnet --bpf-filter "net 10.0.0.0/8"

# 按协议过滤
rustnet --bpf-filter "tcp"
rustnet --bpf-filter "udp port 53"

# 组合过滤器
rustnet --bpf-filter "tcp port 443 and host github.com"

# 排除流量
rustnet --bpf-filter "not port 22"

注意:

  • BPF 过滤器语法遵循 pcap-filter(7) 格式。无效过滤器会导致 RustNet 退出并报错。使用 man pcap-filter 查看完整语法文档。
  • macOS 限制: BPF 过滤器与 PKTAP(linktype 149)不兼容。在 macOS 上指定 BPF 过滤器时,RustNet 自动回退到常规接口捕获。这意味着进程识别使用 lsof 而非 PKTAP 的直接进程元数据,对于短寿命连接可能略不准确。

-l, --log-level <LEVEL>

使用指定级别启用日志。默认禁用日志。

可用级别:

  • error —— 仅错误(最小日志)
  • warn —— 警告和错误
  • info —— 一般信息(建议用于常规调试)
  • debug —— 详细的调试信息
  • trace —— 非常详细的输出(包含数据包级详情)

日志文件创建于 logs/ 目录,带时间戳:rustnet_YYYY-MM-DD_HH-MM-SS.log

键盘控制

导航

  • k —— 在连接列表中向上导航
  • j —— 在连接列表中向下导航
  • g —— 跳转到第一个连接(vim 风格)
  • G(Shift+g)—— 跳转到最后一个连接(vim 风格)
  • PageUpCtrl+B —— 向上翻一页
  • PageDownCtrl+F —— 向下翻一页

视图与标签页

  • Tab] —— 下一个标签页
  • Shift+Tab[ —— 上一个标签页
  • 1 / 2 / 3 / 4 / 5 —— 直接跳转到 概览 / 详情 / 接口 / 图表 / 帮助
  • Enter —— 查看所选连接的详细信息
  • Esc —— 返回上一个视图或清除活动过滤器
  • h —— 切换帮助屏幕

操作

  • c —— 将远程地址复制到剪贴板
  • p —— 在服务名和端口号之间切换
  • d —— 在主机名和 IP 地址之间切换(由 --no-resolve-dns 禁用)
  • / —— 进入过滤模式(vim 风格搜索,实时结果)
  • x —— 清除所有连接并重置统计(按两次确认)
  • t —— 切换历史(已关闭)连接的显示
  • r —— 将视图重置为默认值(清除分组、排序、过滤和历史)

进程分组

  • a —— 切换进程分组模式(按进程聚合连接)
  • Space —— 展开/折叠所选进程分组
  • h —— 折叠所选分组
  • l —— 展开所选分组

排序

  • s —— 在可排序列之间循环切换(从左到右顺序)
  • S(Shift+s)—— 切换排序方向(升序/降序)

退出

  • q —— 退出应用(按两次确认)
  • Ctrl+C —— 立即退出

鼠标控制

RustNet 具有完整的鼠标支持。鼠标捕获自动启用 —— 以下描述的所有交互均可开箱即用。

概览标签页

操作 效果
单击 连接行 选择该连接
双击 连接行 打开该连接的详情标签页
滚轮 在连接列表上 在连接中上下导航
单击 标签页名称 切换到该标签页

分组视图(按 a 启用)

操作 效果
单击 分组头部([+]/[-] 选择该分组
双击 分组头部 展开或折叠进程分组
单击 展开分组内的连接 选择该连接
双击 展开分组内的连接 打开该连接的详情标签页
滚轮 在分组和连接中导航

详情标签页

操作 效果
单击 任意字段行 将字段值复制到系统剪贴板

单击字段仅复制值(不包括标签)。例如,单击 "Remote Address: 142.250.80.46:443" 行会将 142.250.80.46:443 复制到剪贴板。状态栏会显示 3 秒的确认消息。

"Connection Information" 和 "Traffic Statistics" 两个面板都支持点击复制。

过滤

/ 进入过滤模式。输入以实时过滤连接,输入时可用方向键导航。

基本搜索

直接输入任意文本即可在所有连接字段中搜索:

/google        # 查找包含 "google" 的连接
/firefox       # 查找 Firefox 连接
/192.168       # 查找 IP 以 192.168 开头的连接

关键字过滤器

使用关键字过滤器进行定向搜索:

关键字 别名 描述 示例
port: 精确端口匹配;使用 /pattern/ 进行正则 port:22 仅匹配 22;port:/22/ 匹配 22、220、5522
sport: srcport:source-port: 源端口(精确或正则) sport:80 仅匹配源端口 80
dport: dstport:dest-port:destination-port: 目的端口(精确或正则) dport:443 仅匹配目的端口 443
src: source: 源 IP/主机名 src:192.168 匹配 192.168.x.x
dst: dest:destination: 目的地址 dst:github.com 匹配 github.com
process: proc: 进程名 process:ssh 匹配 ssh、sshd
sni: host:hostname: SNI 主机名(HTTPS) sni:api 匹配 api.example.com
service: svc: 服务名 service:https 匹配 HTTPS 服务
app: application: 检测到的应用协议 app:ssh 匹配 SSH 连接
state: 协议状态 state:established 匹配已建立的连接
proto: protocol: 协议类型 proto:tcp 匹配 TCP 连接

状态过滤

按当前协议状态过滤连接(不区分大小写):

⚠️ 注意: 状态追踪的准确性因协议而异。TCP 状态最可靠,而 UDP、QUIC 和其他协议的状态来自数据包检测,可能并不总是反映真实的连接状态。

示例:

state:syn_recv       # 显示半开连接(可用于检测 SYN flood)
state:established    # 仅显示已建立的连接
state:fin_wait       # 显示处于关闭状态的连接
state:quic_handshake # 显示握手期间的 QUIC 连接
state:dns_query      # 显示 DNS 查询连接
state:udp_active     # 显示活跃的 UDP 连接

可用状态:

协议 状态
TCP SYN_SENTSYN_RECVESTABLISHEDFIN_WAIT1FIN_WAIT2TIME_WAITCLOSE_WAITLAST_ACKCLOSINGCLOSED
QUIC QUIC_INITIALQUIC_HANDSHAKEQUIC_CONNECTEDQUIC_DRAININGQUIC_CLOSED ⚠️ 注意:可能不完整,因为握手已加密
UDP UDP_ACTIVEUDP_IDLEUDP_STALE
DNS DNS_QUERYDNS_RESPONSE
SSH BANNERKEYEXCHANGEAUTHENTICATIONESTABLISHED ⚠️ 注意:基于数据包检测
Other ECHO_REQUESTECHO_REPLYARP_REQUESTARP_REPLY

正则过滤器

将任何过滤值包裹在 /pattern/ 中以使用正则表达式(不区分大小写)。正则使用 regex-lite crate 支持的标准语法。

/192\.168\.[0-9]+/         # 在所有字段中通用正则
port:/22/                  # 端口包含 "22"(22、220、2200、5522 …)
sni:/.*github\..*/         # SNI 匹配 github.com、api.github.com 等
process:/chrom(e|ium)/     # Chrome 或 Chromium

端口匹配port:443精确匹配(仅端口 443)。如需子串/正则行为,请使用 port:/443/

组合过滤器

用空格组合多个过滤器(隐式 AND):

sport:80 process:nginx              # Nginx 从 80 端口发出的连接
dport:443 sni:google.com            # 到 Google 的 HTTPS 连接
sport:443 state:syn_recv            # 到 443 端口的半开连接(SYN flood 检测)
proto:tcp state:established         # 所有已建立的 TCP 连接
process:firefox state:quic_connected # Firefox 的活跃 QUIC 连接
dport:22 app:openssh                # 使用 OpenSSH 的 SSH 连接
state:established app:ssh           # 已建立的 SSH 连接

清除过滤器

Esc 清除活动过滤器并返回完整连接列表。

排序

RustNet 提供强大的表格排序功能来帮助你分析网络连接。按 s 按从左到右的视觉顺序在可排序列之间循环切换,按 S(Shift+s)在升序和降序之间切换。

快速开始

找出带宽大户(上下行合计流量):

反复按 's' 直到看到:Down/Up ↓
总带宽最高的连接显示在顶部

按进程名排序:

反复按 's' 直到看到:Process ↑
连接按进程名字母顺序排序

可排序列

s 按从左到右顺序在列之间循环切换:

默认方向 描述
Protocol ↑ 升序 按协议类型排序(TCP、UDP、ICMP 等)
Local Address ↑ 升序 按本地 IP:port 排序(适用于多接口系统)
Remote Address ↑ 升序 按远程 IP:port 排序
Location ↑ 升序 按国家代码排序(需要 GeoIP 数据库)
State ↑ 升序 按连接状态排序(ESTABLISHED 等)
Service ↑ 升序 按服务名或端口号排序
Application ↑ 升序 按检测到的应用协议排序(HTTP、DNS 等)
Bandwidth (Down/Up) ↓ 降序 上下行合计带宽排序(默认最高优先)
Process ↑ 升序 按进程名字母顺序排序

排序指示器

活动排序列通过以下方式高亮:

  • 青色下划线样式
  • 显示排序方向的箭头符号(↑ 或 ↓)
  • 显示当前排序状态的表格标题

视觉指示器:

活动列头部以青色和下划线显示:
Pro │ Local Address │ Remote Address ↑│ State │ ...
                      ^^^^^^^^^^^^^^^^
                      (青色、下划线、带箭头)

表格标题显示当前排序:
┌─ Active Connections (Sort: Remote Addr ↑) ──┐

排序行为

s(小写)—— 循环列:

  • 移动到从左到右视觉顺序的下一列
  • 重置为该列的默认方向
  • 带宽列默认降序(↓)以优先显示最高值
  • 文本列默认升序(↑)以按字母顺序排列

S(Shift+s)—— 切换方向:

  • 保持在当前列
  • 在升序(↑)和降序(↓)之间切换
  • 可用于反转排序顺序(例如找出带宽最小的用户)

多次按 s 返回默认:

  • 循环浏览所有列后返回默认按时间排序(按连接创建时间)
  • 默认模式下不显示排序指示器

过滤时排序

排序与过滤无缝配合:

  1. 先过滤:按 / 输入过滤条件
  2. 再排序:按 s 对过滤结果排序
  3. 排序持续:更改过滤器时保持排序顺序活动

示例工作流:

1. 按 '/' 并输入 'firefox' 过滤 Firefox 连接
2. 按 's' 直到看到 "Down/Up ↓"
3. 现在查看按总带宽(上下行合计)排序的 Firefox 连接

示例

找出哪个进程使用最多带宽:

1. 按 's' 直到出现 "Down/Up ↓"
2. 顶部连接显示最高总带宽(上下行合计)
3. 查看 "Process" 列以确定是哪个应用

按远程目的地排序连接:

1. 按 's' 直到出现 "Remote Address ↑"
2. 连接按远程 IP 地址分组
3. 如需,按 'S' 反转顺序

找出空闲连接(最低带宽):

1. 按 's' 循环到 "Down/Up ↓"
2. 按 'S' 切换到 "Down/Up ↑"(升序)
3. 总带宽最低的连接显示在最前面

按应用协议排序:

1. 按 's' 直到出现 "Application / Host ↑"
2. 所有 HTTPS 连接分组在一起,DNS 查询分组在一起,等等
3. 适合查找特定类型的所有连接

进程分组

RustNet 可以按进程名分组连接,提供聚合视图,让你更容易看到哪些应用正在使用你的网络。

启用进程分组

a 切换进程分组模式。启用时:

  • 连接按进程名分组(按字母顺序排序)
  • 每个分组显示聚合统计
  • 分组可以展开/折叠以显示单个连接

再次按 a 返回扁平(未分组)连接列表。

分组视图显示

启用分组时,连接列表显示进程分组:

[+] firefox (12)              TCP: 10 UDP: 2     12.5K↓/1.2K↑
[-] chrome (8)                TCP: 8  UDP: 0     45.2K↓/5.1K↑
  ├── TCP  192.168.1.10:54321  142.250.80.78:443    ESTABLISHED  HTTPS
  ├── TCP  192.168.1.10:54322  142.250.80.78:443    ESTABLISHED  HTTPS
  └── UDP  192.168.1.10:54323  8.8.8.8:53           -            DNS
[+] systemd-resolved (3)      TCP: 0  UDP: 3     0.2K↓/0.1K↑
[+] <unknown> (5)             TCP: 2  UDP: 3     0.5K↓/0.2K↑

分组头部格式:

  • [+] / [-] —— 折叠/展开指示器
  • 进程名和连接数
  • 协议细分(TCP/UDP 计数)
  • 总带宽(下载↓/上传↑)

展开的连接:

  • 树形前缀(├── / └──)显示层级
  • 单个连接详情(协议、地址、状态、应用)

展开和折叠分组

按键 操作
Space 切换所选分组的展开/折叠
l 展开所选分组
h 折叠所选分组

分组视图中的导航

导航方式与扁平视图相同:

  • /k/j 在可见行(分组和展开的连接)之间移动
  • g 跳转到第一行
  • G 跳转到最后一行
  • Enter 在连接上打开详情视图

未知进程

没有进程信息的连接被分组到单个 <unknown> 分组中。这通常包括:

  • 在进程查找完成前就已关闭的短寿命连接
  • 某些平台上的系统级连接
  • 来自受限进程的连接

分组时过滤

过滤与分组无缝配合:

  1. / 输入你的过滤条件
  2. 仅显示包含匹配连接的分组
  3. 展开分组以查看哪些连接匹配

分组时排序

启用分组时:

  • 分组按进程名字母顺序排序(A-Z)
  • 排序列指示器显示分组内连接的排序方式
  • s 更改展开分组内连接的排序方式

重置视图

r 一次性重置所有视图设置:

  • 禁用进程分组
  • 清除任何活动过滤器
  • 将排序重置为默认(按时间顺序)

网络统计面板

网络统计面板显示在界面右侧,位于流量面板下方。它提供直接从数据包捕获分析中得出的实时 TCP 连接质量指标,使其在 Linux、macOS、Windows 和 FreeBSD 上跨平台一致。

可用指标

TCP 重传 检测由于数据包丢失或超时而重新传输的 TCP 段。RustNet 通过分析 TCP 序列号来识别重传:当到达的数据包序列号低于预期时,表示原始数据包已丢失并正在重发。

乱序包 追踪到达顺序错误的入站 TCP 数据包,通常由网络拥塞或多条路由路径导致。这些数据包最终会到达,但顺序错误,需要接收方缓冲并重新排序。

快速重传 识别由收到三个重复确认(RFC 2581)触发的 TCP 快速重传事件。这种机制允许 TCP 比等待超时更快地从数据包丢失中恢复,从而提高连接性能。

统计显示格式

面板为每个指标显示活动总计计数:

TCP Retransmits: 5 / 142 total
Out-of-Order: 2 / 89 total
Fast Retransmits: 1 / 23 total
Active TCP Flows: 18
  • 活动计数(左侧数字):当前追踪连接的各事件总和。这个数字随着连接的建立和清理而上下波动。
  • 总计计数(右侧数字):自 RustNet 启动以来的累积计数。这个数字只增不减,提供历史背景。
  • Active TCP Flows:具有分析数据的活跃 TCP 连接数。

逐连接统计

查看连接详情时(在连接上按 Enter),显示该特定连接的 TCP 分析:

TCP Retransmits: 3
Out-of-Order: 1
Fast Retransmits: 0

这些计数器独立追踪每个连接,允许你识别遇到数据包丢失或网络问题的有问题连接。

使用场景

网络质量监控 重传或乱序包的突然增加表明网络拥塞、数据包丢失或路由问题。

连接故障排查 特定连接上的高重传计数可以识别:

  • 到某些目的地的不可靠网络路径
  • 带宽受限的链路
  • 故障的网络硬件或驱动

性能分析 快速重传频率表明 TCP 在不等待超时的情况下从数据包丢失中恢复的情况。

技术说明

  • 统计源自 TCP 序列号分析,不需要数据包时间戳
  • 分析适用于出站和入站数据包
  • SYN 和 FIN 标志在序列号追踪中被正确计算(每个消耗 1 个序列号)
  • 仅 TCP 连接显示分析指标;UDP、ICMP 和其他协议没有这些指标

接口统计

RustNet 在所有支持的平台上(Linux、macOS、FreeBSD、Windows)提供实时网络接口统计。接口统计显示在两个位置:

访问接口统计

概览标签页(主屏幕):

  • 接口统计出现在右侧面板,位于网络统计下方
  • 显示最多 3 个活跃接口及当前速率
  • 显示:InterfaceName: X KB/s ↓ / Y KB/s ↑
  • 显示累计总数:Errors (Total): N Drops (Total): M

接口标签页(详细视图):

  • i 切换接口统计视图
  • 显示所有网络接口的详细表格
  • 显示每个接口的综合指标

显示的统计

指标 描述 说明
RX Rate 当前接收速率(字节/秒) 根据近期活动计算
TX Rate 当前发送速率(字节/秒) 根据近期活动计算
RX Packets 接收的总数据包数 自启动/接口上线以来累计
TX Packets 发送的总数据包数 自启动/接口上线以来累计
RX Err 接收错误 累计总数(非近期)
TX Err 发送错误 累计总数(非近期)
RX Drop 丢弃的入站数据包 累计总数(非近期)
TX Drop 丢弃的出站数据包 累计总数(非近期)
Collisions 网络冲突 平台相关的可用性

重要:错误和丢弃计数器是自系统启动或接口上线以来的累计总数,不是近期活动。这些有助于识别长期接口可靠性,但不会显示即时问题。

平台特定行为

所有平台:

  • 所有计数器(字节、数据包、错误、丢弃)自启动/接口上线以来累计
  • 速率(字节/秒)根据每 2 秒采集的快照计算
  • 包含回环接口用于监控本地流量

Windows:

  • 过滤掉虚拟/过滤适配器,仅显示物理接口:
    • 排除:-Npcap-WFP-QoS-Native-Virtual-Packet 变体
    • 排除:Lightweight FilterMAC Layer 接口
    • 排除:已断开的 "Local Area Connection" 适配器
  • 使用基于 LUID 的去重防止重复的接口条目
  • Collisions:始终为 0(现代 Windows 接口上不可用)

macOS:

  • 包含数据验证以检测虚拟接口上的损坏计数器
  • TX Drops:始终为 0(macOS 上可用性有限)
  • 如果错误/丢弃计数器值看起来损坏(>2^31 或 errors>packets),则进行清理

FreeBSD:

  • TX Drops:始终为 0(FreeBSD 上通常不可用)
  • 使用 BSD getifaddrs API 配合 AF_LINK 过滤

Linux:

  • /sys/class/net/{interface}/statistics 读取统计
  • 所有计数器通常可用且可靠

解读统计

健康的接口:

Ethernet: 2.40 KB/s ↓ / 1.96 KB/s ↑
  Errors (Total): 0  Drops (Total): 0

零或极低的错误/丢弃计数表明可靠的网络连接。

有问题的接口:

WiFi: 150 KB/s ↓ / 45 KB/s ↑
  Errors (Total): 1089  Drops (Total): 2178

高错误/丢弃计数可能表明:

  • 信号干扰(WiFi)
  • 线缆问题(Ethernet)
  • 网络拥塞
  • 驱动或硬件问题

注意:由于错误/丢弃计数器是累计的,请相对于总数据包数来评估它们。数百万数据包中有少量错误是正常的;数据包数低但有数千错误则表明有问题。

接口过滤

显示哪些接口:

  • 接口必须在操作上 "up" OR 拥有流量统计
  • 包含回环接口(用于监控本地连接)
  • Windows 上排除虚拟/过滤适配器(它们镜像物理接口)

概览标签页过滤:

  • Windows:显示所有活跃接口(NPF 设备路径自动检测)
  • macOS/Linux:显示有近期流量的接口(rx_bytes > 0 || tx_bytes > 0 || rx_packets > 0 || tx_packets > 0
  • 特殊接口(anypktap):显示有任何活动的所有接口

接口标签页:

  • 显示通过平台特定过滤的所有检测到的接口
  • 排序将当前捕获的接口排在最前面(高亮)
  • 其他接口按字母顺序出现

使用场景

带宽监控: 监控所有网络接口的实时带宽使用情况以识别:

  • 哪个接口承载最多流量
  • WiFi 与 Ethernet 之间的带宽分布
  • 本地流量体积(回环接口)

可靠性分析: 检查累计错误和丢弃计数器以:

  • 识别不可靠的网络接口
  • 检测硬件或驱动问题
  • 随时间比较接口质量

多接口系统: 在具有多个网络接口的系统上:

  • 跨接口比较性能
  • 监控 VPN 隧道统计
  • 追踪接口故障转移行为

连接生命周期与视觉指示器

RustNet 使用智能超时管理自动清理不活跃的连接,同时在移除前提供视觉警告。

视觉陈旧度指示器

连接根据距离被清理的接近程度改变颜色:

颜色 含义 陈旧度
白色(默认) 活跃连接 < 75% 的超时时间
黄色 陈旧 - 接近超时 75-90% 的超时时间
红色 严重 - 即将被移除 > 90% 的超时时间

示例:一条超时为 10 分钟的 HTTP 连接会:

  • 前 7.5 分钟保持白色
  • 7.5 到 9 分钟变为黄色(警告)
  • 9 分钟后变为红色(严重)
  • 10 分钟时被移除

这让你在连接即将从列表中消失前得到预警。

智能协议感知超时

RustNet 根据协议和检测到的应用调整连接超时:

TCP 连接

  • HTTP/HTTPS(通过 DPI 检测):10 分钟 —— 支持 HTTP keep-alive
  • SSH(通过 DPI 检测):30 分钟 —— 适应长交互会话
  • 活跃已建立(< 1 分钟空闲):10 分钟
  • 空闲已建立(> 1 分钟空闲):5 分钟
  • TIME_WAIT:30 秒 —— 标准 TCP 超时
  • CLOSED:5 秒 —— 快速清理
  • SYN_SENT、FIN_WAIT 等:30-60 秒

UDP 连接

  • 基于 UDP 的 SSH30 分钟 —— 长会话
  • DNS30 秒 —— 短查询
  • 普通 UDP60 秒 —— 标准超时

QUIC 连接(检测到的状态)

  • 已连接3 分钟 默认(或当可用时使用来自传输参数的 idle timeout)
  • 带 CONNECTION_CLOSE 帧:1-10 秒(基于关闭类型)
  • Initial/Handshaking:60 秒 —— 允许连接建立
  • Draining:10 秒 —— RFC 9000 draining 周期

基于活动的调整

显示近期数据包活动的连接获得更长的超时:

  • 最近数据包 < 60 秒前:使用"活跃"超时(更长)
  • 最近数据包 > 60 秒前:使用"空闲"超时(更短)

这确保活跃连接保持可见,而空闲连接更快被清理。

连接为什么消失

连接在以下情况下被移除:

  1. 在超时期间内未收到数据包
  2. 连接进入关闭状态(TCP CLOSED、QUIC CLOSED)
  3. 检测到显式关闭帧(QUIC CONNECTION_CLOSE)

注意:速率指示器(带宽显示)基于近期活动显示衰减的流量。连接可能显示带宽下降(黄色条),但在超过空闲超时前仍保留在列表中。这是有意设计的 —— 视觉衰减让你在连接被移除前有时间看到它逐渐结束。

历史连接

默认情况下,连接在超时或关闭后从列表中消失。按 t 切换历史连接模式,使已关闭的连接与活跃连接一起保持可见。

工作原理:

当连接被清理时,它被归档到历史连接池中(最多 5,000 条;最旧的先被逐出)。按 t 切换它们的可见性:

  • 活跃连接以标准颜色指示器正常显示
  • 历史连接暗灰色显示,以清楚区分于活跃连接
  • 启用历史模式时,表格标题变为 "Active + Historic Connections"

详情视图:

选择历史连接并按 Enter 显示通常的连接详情,外加一个Status字段显示连接关闭多久前(例如 "Closed (5m ago)")。

统计面板:

当存在历史连接时,统计面板在总活跃连接数下方显示一个单独的 "Historic: N" 计数。

分组视图:

在进程分组模式(a)中,当启用历史模式时,分组头部将历史连接数与活跃计数分开显示。

图表标签页:

图表标签页始终只显示活跃连接,即使历史模式开启。

重置:

  • r 重置所有视图设置,这也会隐藏历史连接
  • x 两次清除所有连接,这也会清除历史池

日志

日志默认禁用。使用 --log-level 选项启用时,RustNet 在 logs/ 目录中创建带时间戳的日志文件。每个会话生成一个新日志文件,格式为 rustnet_YYYY-MM-DD_HH-MM-SS.log

日志文件内容

日志文件包含:

  • 应用启动和关闭事件
  • 网络接口信息
  • 数据包捕获统计
  • 连接状态变更
  • 错误诊断
  • DPI 检测结果(debug/trace 级别)
  • 性能指标(trace 级别)

启用日志

使用 --log-level 选项启用日志:

# Info 级别日志(建议常规使用)
sudo rustnet --log-level info

# Debug 级别日志(详细故障排查)
sudo rustnet --log-level debug

# Trace 级别日志(非常详细,包含数据包级详情)
sudo rustnet --log-level trace

# 仅 Error 级别日志(最小日志)
sudo rustnet --log-level error

日志级别说明

级别 记录内容 使用场景
error 仅错误和关键问题 生产监控
warn 警告和错误 带警告的正常运行
info 一般信息、启动/关闭 标准调试
debug 详细的调试信息 故障排查
trace 数据包级详情,非常详细 深度调试

管理日志文件

日志清理脚本:

提供了 scripts/clear_old_logs.sh 脚本用于日志清理:

# 删除 7 天前的日志
./scripts/clear_old_logs.sh

# 通过编辑脚本自定义保留期

手动清理:

# 删除所有日志
rm -rf logs/

# 删除 7 天前的日志(Linux/macOS)
find logs/ -name "rustnet_*.log" -mtime +7 -delete

# 查看日志文件大小
du -sh logs/

日志文件隐私

⚠️ 警告:日志文件可能包含敏感信息:

  • IP 地址和端口
  • 主机名和 SNI 数据(HTTPS)
  • DNS 查询和响应
  • 进程名和 PID
  • 数据包内容(trace 级别)

最佳实践:

  • 仅在需要调试时启用日志
  • 保护日志目录权限:chmod 700 logs/
  • 分享前检查日志中的敏感数据
  • 实施日志轮转和保留策略
  • 不再需要时删除日志

使用日志故障排查

报告问题时:

  1. 启用 debug 日志:rustnet --log-level debug
  2. 重现问题
  3. logs/ 中找到最新的日志文件
  4. 查看错误或异常行为
  5. 分享前脱敏敏感信息

对于性能问题,trace 级别日志提供最详细的细节,但会快速生成大量日志文件。

JSON 日志

--json-log 选项启用将连接事件以结构化 JSON 格式记录到文件。每行是一个独立的 JSON 对象(JSONL 格式)。

# 启用 JSON 日志
sudo rustnet --json-log /tmp/connections.json

# 与其他选项组合
sudo rustnet -i eth0 --json-log ~/network-events.json

事件类型:

  • new_connection —— 首次检测到新连接时记录
  • connection_closed —— 连接在变为不活跃后被清理时记录

JSON 字段:

字段 类型 描述
timestamp string RFC3339 UTC 时间戳
event string 事件类型(new_connectionconnection_closed
protocol string 协议(TCP、UDP 等)
source_ip string 本地 IP 地址
source_port number 本地端口号
destination_ip string 远程 IP 地址
destination_port number 远程端口号
pid number 进程 ID(如果可用)
process_name string 进程名(如果可用)
service_name string 端口查找的服务名(如果可用)
direction string 连接方向(outgoingincoming),仅当观察到 TCP 握手时
dpi_protocol string 检测到的应用协议(如果启用 DPI)
dpi_domain string 提取的域名/主机名(如果可用)
bytes_sent number 发送的总字节数(仅 connection_closed)
bytes_received number 接收的总字节数(仅 connection_closed)
duration_secs number 连接持续时间,单位为秒(仅 connection_closed)

示例输出:

{"timestamp":"2025-01-15T10:30:00Z","event":"new_connection","protocol":"TCP","source_ip":"192.168.1.100","source_port":54321,"destination_ip":"93.184.216.34","destination_port":443,"pid":1234,"process_name":"curl","service_name":"https","direction":"outgoing","dpi_protocol":"HTTPS","dpi_domain":"example.com"}
{"timestamp":"2025-01-15T10:30:05Z","event":"connection_closed","protocol":"TCP","source_ip":"192.168.1.100","source_port":54321,"destination_ip":"93.184.216.34","destination_port":443,"pid":1234,"process_name":"curl","service_name":"https","direction":"outgoing","bytes_sent":1024,"bytes_received":4096,"duration_secs":5}

处理 JSON 日志:

# 漂亮打印最新事件
tail -f /tmp/connections.json | jq .

# 按进程过滤
cat /tmp/connections.json | jq 'select(.process_name == "firefox")'

# 按目的地统计连接数
cat /tmp/connections.json | jq -s 'group_by(.destination_ip) | map({ip: .[0].destination_ip, count: length})'

PCAP 导出

--pcap-export 选项将原始数据包捕获到标准 PCAP 文件,供 Wireshark、tcpdump 或其他工具分析。

# 导出所有捕获的数据包
sudo rustnet -i eth0 --pcap-export capture.pcap

# 与 BPF 过滤器组合
sudo rustnet -i eth0 --bpf-filter "tcp port 443" --pcap-export https.pcap

输出文件:

文件 描述
capture.pcap 标准 PCAP 格式的原始数据包
capture.pcap.connections.jsonl 流式连接元数据,带进程信息

Sidecar JSONL 格式(每行一个 JSON 对象,连接关闭时写入):

{"timestamp":"2026-01-17T10:30:00Z","protocol":"TCP","local_addr":"192.168.1.100:54321","remote_addr":"142.250.80.46:443","pid":1234,"process_name":"firefox","first_seen":"...","last_seen":"...","bytes_sent":1024,"bytes_received":8192,"state":"ESTABLISHED"}
字段 描述
timestamp 连接记录写入时间
protocol TCP、UDP、ICMP 等
local_addr / remote_addr 连接端点
pid / process_name 进程信息(如果已识别)
first_seen / last_seen 连接时间戳
bytes_sent / bytes_received 流量总计
state 最终连接状态

用进程信息富化 PCAP

标准 PCAP 文件不包含进程信息。使用附带的 scripts/pcap_enrich.py 脚本将数据包与进程关联:

# 安装 scapy(必需)
pip install scapy

# 显示带进程信息的数据包
python scripts/pcap_enrich.py capture.pcap

# 输出为 TSV 以便进一步处理
python scripts/pcap_enrich.py capture.pcap --format tsv > report.tsv

# 创建带进程注释的注释 PCAPNG(需要 Wireshark 的 editcap)
python scripts/pcap_enrich.py capture.pcap -o annotated.pcapng

注释 PCAPNG 将进程信息嵌入为数据包注释,在 Wireshark 的数据包详情中可见。

手动关联:

# 查看数据包
wireshark capture.pcap

# 查看进程映射
cat capture.pcap.connections.jsonl | jq -r '[.protocol, .local_addr, .remote_addr, .pid, .process_name] | @tsv'

# 在 Wireshark 中按连接元组过滤
# ip.addr == 142.250.80.46 && tcp.port == 443