1148 lines
44 KiB
Markdown
1148 lines
44 KiB
Markdown
<p align="center"><a href="USAGE.md">English</a> | <strong>简体中文</strong></p>
|
||
|
||
# 使用指南
|
||
|
||
本文档涵盖 RustNet 的详细使用说明,包括命令行选项、键盘控制、过滤、排序以及理解连接生命周期。
|
||
|
||
## 目录
|
||
|
||
- [运行 RustNet](#running-rustnet)
|
||
- [命令行选项](#command-line-options)
|
||
- [键盘控制](#keyboard-controls)
|
||
- [鼠标控制](#mouse-controls)
|
||
- [过滤](#filtering)
|
||
- [排序](#sorting)
|
||
- [进程分组](#process-grouping)
|
||
- [网络统计面板](#network-statistics-panel)
|
||
- [接口统计](#interface-statistics)
|
||
- [连接生命周期与视觉指示器](#connection-lifecycle--visual-indicators)
|
||
- [日志](#logging)
|
||
|
||
## 运行 RustNet<a id="running-rustnet"></a>
|
||
|
||
在大多数系统上,数据包捕获需要提升的特权。详细的权限配置说明参见 [INSTALL.zh-CN.md](INSTALL.zh-CN.md)。
|
||
|
||
**快速开始:**
|
||
|
||
```bash
|
||
# 使用 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
|
||
```
|
||
|
||
**基本使用示例:**
|
||
|
||
```bash
|
||
# 使用默认设置运行
|
||
# 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
|
||
|
||
# 恢复原始全彩调色板
|
||
rustnet --theme classic
|
||
|
||
# 禁用反向 DNS 查找(默认启用)
|
||
rustnet --no-resolve-dns
|
||
|
||
# 使用指定级别启用日志(选项:error、warn、info、debug、trace)
|
||
rustnet -l debug
|
||
rustnet --log-level info
|
||
|
||
# 查看帮助和所有选项
|
||
rustnet --help
|
||
```
|
||
|
||
## 命令行选项<a id="command-line-options"></a>
|
||
|
||
```
|
||
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 分析
|
||
--pcapng-export <FILE> 将捕获的数据包导出为带注释的 PCAPNG 文件供 Wireshark 分析
|
||
--no-color 禁用 UI 中的所有颜色(同时尊重 NO_COLOR 环境变量)
|
||
--theme <PRESET> 颜色主题预设:"muted"(单一强调色,颜色仅用于信号,默认)
|
||
或 "classic"(原始全彩调色板)
|
||
--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)
|
||
--no-uid-drop 初始化后保持 root 运行,不降权到
|
||
SUDO_UID/SUDO_GID(或 nobody)(仅限 Linux、macOS 和 FreeBSD)
|
||
-h, --help 打印帮助
|
||
-V, --version 打印版本
|
||
```
|
||
|
||
### 选项详情<a id="option-details"></a>
|
||
|
||
#### `-i, --interface <INTERFACE>`<a id="-i---interface-interface"></a>
|
||
|
||
指定要监控的网络接口。
|
||
|
||
**默认行为(无 `-i` 标志):**
|
||
- **macOS**:自动使用 PKTAP 获取增强型进程元数据(需要 sudo)
|
||
- **Linux/其他**:自动检测第一个可用的非回环接口
|
||
|
||
**示例:**
|
||
```bash
|
||
# 默认:自动检测接口(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 show` 或 `ifconfig`
|
||
- macOS:`ifconfig` 或 `networksetup -listallhardwareports`
|
||
- Windows:`ipconfig /all`
|
||
|
||
#### `--no-localhost` / `--show-localhost`<a id="--no-localhost--show-localhost"></a>
|
||
|
||
控制是否显示 localhost(127.0.0.1/::1)连接。
|
||
|
||
- **默认**:过滤掉 localhost 连接(`--no-localhost`)
|
||
- **覆盖**:使用 `--show-localhost` 查看 localhost 连接
|
||
|
||
这对于减少连接列表中的噪音很有用,因为大多数用户不需要监控本地 IPC 连接。
|
||
|
||
#### `-r, --refresh-interval <MILLISECONDS>`<a id="-r---refresh-interval-milliseconds"></a>
|
||
|
||
以毫秒为单位设置 UI 刷新率。较低的值提供更灵敏的更新,但会增加 CPU 使用率。
|
||
|
||
**建议:**
|
||
- **默认(1000ms)**:大多数用户的良好平衡
|
||
- **高流量网络(2000ms)**:在繁忙网络上降低 CPU 使用率
|
||
- **实时监控(500ms)**:更灵敏的更新,适合快速分析
|
||
- **低端系统(2000-3000ms)**:降低资源受限机器上的负载
|
||
|
||
#### `--no-dpi`<a id="--no-dpi"></a>
|
||
|
||
禁用深度包检测(DPI)。这在高流量网络上可降低 20-40% 的 CPU 使用率,但会禁用:
|
||
- HTTP 主机检测
|
||
- HTTPS/TLS SNI 提取
|
||
- DNS 查询/响应检测
|
||
- SSH 版本识别
|
||
- QUIC 协议检测
|
||
|
||
适用于性能受限的环境或不需要应用层详细信息时。
|
||
|
||
#### `--no-resolve-dns` / `--show-ptr-lookups`<a id="--no-resolve-dns--show-ptr-lookups"></a>
|
||
|
||
反向 DNS 查找**默认启用**:IP 地址在后台解析为主机名,并显示在连接列表中(按 `d` 键切换)和详情标签页中。
|
||
|
||
- **`--no-resolve-dns`**:完全禁用反向 DNS 解析。连接列表仅显示 IP 地址,不发起 PTR 查询。
|
||
- **`--show-ptr-lookups`**:PTR 查找流量默认隐藏。使用此标志显示解析器生成的 DNS PTR 查询。
|
||
|
||
**注意**:解析后的主机名也包含在 JSON 日志中(`destination_hostname`、`source_hostname` 字段)。
|
||
|
||
#### `--theme <PRESET>`<a id="--theme-preset"></a>
|
||
|
||
选择颜色主题预设:
|
||
|
||
- **`muted`**(默认):克制的调色板,只有一个青色强调色。地址保留柔和的颜色
|
||
(远程 = 蓝色,本地 = 青色);其他颜色仅用于*信号* —— 连接状态变化、
|
||
过期状态(黄色/红色行)以及实时带宽。
|
||
- **`classic`**:早期版本的原始全彩调色板,每列一种颜色。
|
||
|
||
```bash
|
||
# 恢复原始全彩外观
|
||
rustnet --theme classic
|
||
```
|
||
|
||
相关:`--no-color` 完全禁用所有颜色(同时尊重 `NO_COLOR` 环境变量)。
|
||
|
||
#### `-f, --bpf-filter <FILTER>`<a id="-f---bpf-filter-filter"></a>
|
||
|
||
应用 BPF(Berkeley Packet Filter)表达式在捕获时过滤数据包。这比应用层过滤更高效,因为数据包在到达 RustNet 之前在内核中被过滤。
|
||
|
||
**常见过滤器表达式:**
|
||
|
||
```bash
|
||
# 按端口过滤(匹配源 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>`<a id="-l---log-level-level"></a>
|
||
|
||
使用指定级别启用日志。**默认禁用**日志。
|
||
|
||
**可用级别:**
|
||
- `error` —— 仅错误(最小日志)
|
||
- `warn` —— 警告和错误
|
||
- `info` —— 一般信息(建议用于常规调试)
|
||
- `debug` —— 详细的调试信息
|
||
- `trace` —— 非常详细的输出(包含数据包级详情)
|
||
|
||
日志文件创建于 `logs/` 目录,带时间戳:`rustnet_YYYY-MM-DD_HH-MM-SS.log`
|
||
|
||
## 键盘控制<a id="keyboard-controls"></a>
|
||
|
||
### 导航<a id="navigation"></a>
|
||
|
||
- `↑` 或 `k` —— 在连接列表中向上导航
|
||
- `↓` 或 `j` —— 在连接列表中向下导航
|
||
- `g` —— 跳转到第一个连接(vim 风格)
|
||
- `G`(Shift+g)—— 跳转到最后一个连接(vim 风格)
|
||
- `PageUp` 或 `Ctrl+B` —— 向上翻一页
|
||
- `PageDown` 或 `Ctrl+F` —— 向下翻一页
|
||
|
||
### 视图与标签页<a id="views-and-tabs"></a>
|
||
|
||
- `Tab` 或 `]` —— 下一个标签页
|
||
- `Shift+Tab` 或 `[` —— 上一个标签页
|
||
- `1` / `2` / `3` / `4` / `5` —— 直接跳转到 概览 / 详情 / 接口 / 图表 / 帮助
|
||
- `Enter` —— 查看所选连接的详细信息
|
||
- `Esc` —— 返回上一个视图或清除活动过滤器
|
||
- `h` —— 切换帮助屏幕
|
||
|
||
### 操作<a id="actions"></a>
|
||
|
||
- `c` —— 将远程地址复制到剪贴板
|
||
- `p` —— 在服务名和端口号之间切换
|
||
- `d` —— 在主机名和 IP 地址之间切换(由 `--no-resolve-dns` 禁用)
|
||
- `/` —— 进入过滤模式(vim 风格搜索,实时结果)
|
||
- `x` —— 清除所有连接并重置统计(按两次确认)
|
||
- `t` —— 切换历史(已关闭)连接的显示
|
||
- `i` —— 切换 System 信息侧边栏
|
||
- `r` —— 将视图重置为默认值(清除分组、排序、过滤和历史)
|
||
|
||
### 进程分组<a id="process-grouping-1"></a>
|
||
|
||
- `a` —— 切换进程分组模式(按进程聚合连接)
|
||
- `Space` —— 展开/折叠所选进程分组
|
||
- `←` 或 `h` —— 折叠所选分组
|
||
- `→` 或 `l` —— 展开所选分组
|
||
|
||
### 排序<a id="sorting-1"></a>
|
||
|
||
- `s` —— 在可排序列之间循环切换(从左到右顺序)
|
||
- `S`(Shift+s)—— 切换排序方向(升序/降序)
|
||
|
||
### 退出<a id="exit"></a>
|
||
|
||
- `q` —— 退出应用(按两次确认)
|
||
- `Ctrl+C` —— 立即退出
|
||
|
||
## 鼠标控制<a id="mouse-controls"></a>
|
||
|
||
RustNet 具有完整的鼠标支持。鼠标捕获自动启用 —— 以下描述的所有交互均可开箱即用。
|
||
|
||
### 概览标签页<a id="overview-tab"></a>
|
||
|
||
| 操作 | 效果 |
|
||
|------|------|
|
||
| **单击** 连接行 | 选择该连接 |
|
||
| **双击** 连接行 | 打开该连接的详情标签页 |
|
||
| **滚轮** 在连接列表上 | 在连接中上下导航 |
|
||
| **单击** 标签页名称 | 切换到该标签页 |
|
||
|
||
### 分组视图(按 `a` 启用)<a id="grouped-view-press-a-to-enable"></a>
|
||
|
||
| 操作 | 效果 |
|
||
|------|------|
|
||
| **单击** 分组头部(`▸`/`▾`) | 选择该分组 |
|
||
| **双击** 分组头部 | 展开或折叠进程分组 |
|
||
| **单击** 展开分组内的连接 | 选择该连接 |
|
||
| **双击** 展开分组内的连接 | 打开该连接的详情标签页 |
|
||
| **滚轮** | 在分组和连接中导航 |
|
||
|
||
### 详情标签页<a id="details-tab"></a>
|
||
|
||
| 操作 | 效果 |
|
||
|------|------|
|
||
| **单击** 任意字段行 | 将字段值复制到系统剪贴板 |
|
||
|
||
单击字段仅复制值(不包括标签)。例如,单击 "Remote Address: 142.250.80.46:443" 行会将 `142.250.80.46:443` 复制到剪贴板。状态栏会显示 3 秒的确认消息。
|
||
|
||
"Connection Information" 和 "Traffic Statistics" 两个面板都支持点击复制。
|
||
|
||
## 过滤<a id="filtering"></a>
|
||
|
||
按 `/` 进入过滤模式。输入以实时过滤连接,输入时可用方向键导航。
|
||
|
||
### 基本搜索<a id="basic-search"></a>
|
||
|
||
直接输入任意文本即可在所有连接字段中搜索:
|
||
|
||
```
|
||
/google # 查找包含 "google" 的连接
|
||
/firefox # 查找 Firefox 连接
|
||
/192.168 # 查找 IP 以 192.168 开头的连接
|
||
```
|
||
|
||
### 关键字过滤器<a id="keyword-filters"></a>
|
||
|
||
使用关键字过滤器进行定向搜索:
|
||
|
||
| 关键字 | 别名 | 描述 | 示例 |
|
||
|---------|---------|-------------|---------|
|
||
| `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 连接 |
|
||
|
||
### 状态过滤<a id="state-filtering"></a>
|
||
|
||
按当前协议状态过滤连接(不区分大小写):
|
||
|
||
⚠️ **注意:** 状态追踪的准确性因协议而异。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_SENT`、`SYN_RECV`、`ESTABLISHED`、`FIN_WAIT1`、`FIN_WAIT2`、`TIME_WAIT`、`CLOSE_WAIT`、`LAST_ACK`、`CLOSING`、`CLOSED` |
|
||
| **QUIC** | `QUIC_INITIAL`、`QUIC_HANDSHAKE`、`QUIC_CONNECTED`、`QUIC_DRAINING`、`QUIC_CLOSED` ⚠️ *注意:可能不完整,因为握手已加密* |
|
||
| **UDP** | `UDP_ACTIVE`、`UDP_IDLE`、`UDP_STALE` |
|
||
| **DNS** | `DNS_QUERY`、`DNS_RESPONSE` |
|
||
| **SSH** | `BANNER`、`KEYEXCHANGE`、`AUTHENTICATION`、`ESTABLISHED` ⚠️ *注意:基于数据包检测* |
|
||
| **Other** | `ECHO_REQUEST`、`ECHO_REPLY`、`ARP_REQUEST`、`ARP_REPLY` |
|
||
|
||
### 正则过滤器<a id="regex-filters"></a>
|
||
|
||
将任何过滤值包裹在 `/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/`。
|
||
|
||
### 组合过滤器<a id="combining-filters"></a>
|
||
|
||
用空格组合多个过滤器(隐式 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 连接
|
||
```
|
||
|
||
### 清除过滤器<a id="clearing-filters"></a>
|
||
|
||
按 `Esc` 清除活动过滤器并返回完整连接列表。
|
||
|
||
## 排序<a id="sorting"></a>
|
||
|
||
RustNet 提供强大的表格排序功能来帮助你分析网络连接。按 `s` 按从左到右的视觉顺序在可排序列之间循环切换,按 `S`(Shift+s)在升序和降序之间切换。
|
||
|
||
### 快速开始<a id="quick-start"></a>
|
||
|
||
**找出带宽大户(上下行合计流量):**
|
||
```
|
||
反复按 's' 直到看到:Bandwidth Total ↓
|
||
总带宽最高的连接显示在顶部
|
||
```
|
||
|
||
**按进程名排序:**
|
||
```
|
||
反复按 's' 直到看到:Process ↑
|
||
连接按进程名字母顺序排序
|
||
```
|
||
|
||
### 可排序列<a id="sortable-columns"></a>
|
||
|
||
按 `s` 按从左到右顺序在列之间循环切换:
|
||
|
||
| 列 | 默认方向 | 描述 |
|
||
|--------|-------------------|-------------|
|
||
| **Process** | ↑ 升序 | 按进程名字母顺序排序 |
|
||
| **Remote Address** | ↑ 升序 | 按远程 IP:port 排序 |
|
||
| **Local Address** | ↑ 升序 | 按本地 IP:port 排序(适用于多接口系统) |
|
||
| **Location** | ↑ 升序 | 按国家代码排序(需要 GeoIP 数据库) |
|
||
| **Service** | ↑ 升序 | 按服务名或端口号排序 |
|
||
| **Application** | ↑ 升序 | 按检测到的应用协议排序(HTTP、DNS 等),以 TCP/UDP 作为同序比较 |
|
||
| **State** | ↑ 升序 | 按连接状态排序(ESTABLISHED 等) |
|
||
| **Bandwidth (Rx/Tx)** | ↓ 降序 | 按**上下行合计**带宽排序(默认最高优先) |
|
||
|
||
在窄终端下被隐藏的列仍留在循环中 —— 当前排序列始终显示在表格的区段标题中。
|
||
|
||
### 排序指示器<a id="sort-indicators"></a>
|
||
|
||
活动排序列通过以下方式高亮:
|
||
- **青色**和**下划线**样式
|
||
- 显示排序方向的**箭头符号**(↑ 或 ↓)
|
||
- 显示当前排序状态的**表格标题**
|
||
|
||
**视觉指示器:**
|
||
```
|
||
活动列头部以青色和下划线显示:
|
||
Process │ Remote ↑ │ Local │ Service │ App │ ...
|
||
^^^^^^^^
|
||
(青色、下划线、带箭头)
|
||
|
||
区段标题显示当前排序:
|
||
▎ Active Connections · 42 shown · sort Remote Addr ↑
|
||
```
|
||
|
||
### 排序行为<a id="sort-behavior"></a>
|
||
|
||
**按 `s`(小写)—— 循环列:**
|
||
- 移动到从左到右视觉顺序的下一列
|
||
- **重置为该列的默认方向**
|
||
- 带宽列默认降序(↓)以优先显示最高值
|
||
- 文本列默认升序(↑)以按字母顺序排列
|
||
|
||
**按 `S`(Shift+s)—— 切换方向:**
|
||
- **保持在当前列**
|
||
- 在升序(↑)和降序(↓)之间切换
|
||
- 可用于反转排序顺序(例如找出带宽最小的用户)
|
||
|
||
**多次按 `s` 返回默认:**
|
||
- 循环浏览所有列后返回默认按时间排序(按连接创建时间)
|
||
- 默认模式下不显示排序指示器
|
||
|
||
### 过滤时排序<a id="sorting-with-filtering"></a>
|
||
|
||
排序与过滤无缝配合:
|
||
1. **先过滤**:按 `/` 输入过滤条件
|
||
2. **再排序**:按 `s` 对过滤结果排序
|
||
3. **排序持续**:更改过滤器时保持排序顺序活动
|
||
|
||
示例工作流:
|
||
```
|
||
1. 按 '/' 并输入 'firefox' 过滤 Firefox 连接
|
||
2. 按 's' 直到看到 "Bandwidth Total ↓"
|
||
3. 现在查看按总带宽(上下行合计)排序的 Firefox 连接
|
||
```
|
||
|
||
### 示例<a id="examples"></a>
|
||
|
||
**找出哪个进程使用最多带宽:**
|
||
```
|
||
1. 按 's' 直到出现 "Bandwidth Total ↓"
|
||
2. 顶部连接显示最高总带宽(上下行合计)
|
||
3. 查看 "Process" 列以确定是哪个应用
|
||
```
|
||
|
||
**按远程目的地排序连接:**
|
||
```
|
||
1. 按 's' 直到出现 "Remote Address ↑"
|
||
2. 连接按远程 IP 地址分组
|
||
3. 如需,按 'S' 反转顺序
|
||
```
|
||
|
||
**找出空闲连接(最低带宽):**
|
||
```
|
||
1. 按 's' 循环到 "Bandwidth Total ↓"
|
||
2. 按 'S' 切换到 "Bandwidth Total ↑"(升序)
|
||
3. 总带宽最低的连接显示在最前面
|
||
```
|
||
|
||
**按应用协议排序:**
|
||
```
|
||
1. 按 's' 直到出现 "Application / Host ↑"
|
||
2. 所有 HTTPS 连接分组在一起,DNS 查询分组在一起,等等
|
||
3. 适合查找特定类型的所有连接
|
||
```
|
||
|
||
## 进程分组<a id="process-grouping"></a>
|
||
|
||
RustNet 可以按进程名分组连接,提供聚合视图,让你更容易看到哪些应用正在使用你的网络。
|
||
|
||
### 启用进程分组<a id="enabling-process-grouping"></a>
|
||
|
||
按 `a` 切换进程分组模式。启用时:
|
||
- 连接按进程名分组(按字母顺序排序)
|
||
- 每个分组显示聚合统计
|
||
- 分组可以展开/折叠以显示单个连接
|
||
|
||
再次按 `a` 返回扁平(未分组)连接列表。
|
||
|
||
### 分组视图显示<a id="grouped-view-display"></a>
|
||
|
||
启用分组时,连接列表显示进程分组:
|
||
|
||
```
|
||
▸ firefox (12) TCP:10 UDP:2 12.5K/1.2K
|
||
▾ chrome (8) TCP:8 UDP:0 45.2K/5.1K
|
||
├─ 4101 142.250.80.78:443 192.168.1.10:54321 ESTABLISHED 1.2K/0.3K
|
||
├─ 4101 142.250.80.78:443 192.168.1.10:54322 ESTABLISHED 0.8K/0.1K
|
||
└─ 4102 8.8.8.8:53 192.168.1.10:54323 UDP_ACTIVE 0.2K/0.1K
|
||
▸ systemd-resolved (3) TCP:0 UDP:3 0.2K/0.1K
|
||
▸ <unknown> (5) TCP:2 UDP:3 0.5K/0.2K
|
||
```
|
||
|
||
**分组头部格式:**
|
||
- `▸` / `▾` —— 折叠/展开指示器
|
||
- 进程名和连接数
|
||
- 协议细分(TCP/UDP 计数)
|
||
- 总带宽(rx/tx,位于 Bandwidth 列)
|
||
|
||
**展开的连接:**
|
||
- 树形前缀(`├─` / `└─`)加 PID(进程名由上方的分组头部承载)
|
||
- 单个连接详情(协议、地址、状态、应用)
|
||
|
||
### 展开和折叠分组<a id="expanding-and-collapsing-groups"></a>
|
||
|
||
| 按键 | 操作 |
|
||
|-----|--------|
|
||
| `Space` | 切换所选分组的展开/折叠 |
|
||
| `→` 或 `l` | 展开所选分组 |
|
||
| `←` 或 `h` | 折叠所选分组 |
|
||
|
||
### 分组视图中的导航<a id="navigation-in-grouped-view"></a>
|
||
|
||
导航方式与扁平视图相同:
|
||
- `↑`/`k` 和 `↓`/`j` 在可见行(分组和展开的连接)之间移动
|
||
- `g` 跳转到第一行
|
||
- `G` 跳转到最后一行
|
||
- `Enter` 在连接上打开详情视图
|
||
|
||
### 未知进程<a id="unknown-processes"></a>
|
||
|
||
没有进程信息的连接被分组到单个 `<unknown>` 分组中。这通常包括:
|
||
- 在进程查找完成前就已关闭的短寿命连接
|
||
- 某些平台上的系统级连接
|
||
- 来自受限进程的连接
|
||
|
||
### 分组时过滤<a id="filtering-with-grouping"></a>
|
||
|
||
过滤与分组无缝配合:
|
||
1. 按 `/` 输入你的过滤条件
|
||
2. 仅显示包含匹配连接的分组
|
||
3. 展开分组以查看哪些连接匹配
|
||
|
||
### 分组时排序<a id="sorting-in-grouped-view"></a>
|
||
|
||
启用分组时:
|
||
- 分组按进程名字母顺序排序(A-Z)
|
||
- 排序列指示器显示分组内连接的排序方式
|
||
- 按 `s` 更改展开分组内连接的排序方式
|
||
|
||
### 重置视图<a id="reset-view"></a>
|
||
|
||
按 `r` 一次性重置所有视图设置:
|
||
- 禁用进程分组
|
||
- 清除任何活动过滤器
|
||
- 将排序重置为默认(按时间顺序)
|
||
|
||
## 网络统计面板<a id="network-statistics-panel"></a>
|
||
|
||
网络统计面板显示在界面右侧,位于流量面板下方。它提供直接从数据包捕获分析中得出的实时 TCP 连接质量指标,使其在 Linux、macOS、Windows 和 FreeBSD 上跨平台一致。
|
||
|
||
### 可用指标<a id="available-metrics"></a>
|
||
|
||
**TCP 重传**
|
||
检测由于数据包丢失或超时而重新传输的 TCP 段。RustNet 通过分析 TCP 序列号来识别重传:当到达的数据包序列号低于预期时,表示原始数据包已丢失并正在重发。
|
||
|
||
**乱序包**
|
||
追踪到达顺序错误的入站 TCP 数据包,通常由网络拥塞或多条路由路径导致。这些数据包最终会到达,但顺序错误,需要接收方缓冲并重新排序。
|
||
|
||
**快速重传**
|
||
识别由收到三个重复确认(RFC 2581)触发的 TCP 快速重传事件。这种机制允许 TCP 比等待超时更快地从数据包丢失中恢复,从而提高连接性能。
|
||
|
||
### 统计显示格式<a id="statistics-display-format"></a>
|
||
|
||
面板为每个指标显示**活动**和**总计**计数:
|
||
|
||
```
|
||
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 连接数。
|
||
|
||
### 逐连接统计<a id="per-connection-statistics"></a>
|
||
|
||
查看连接详情时(在连接上按 `Enter`),显示该特定连接的 TCP 分析:
|
||
|
||
```
|
||
TCP Retransmits: 3
|
||
Out-of-Order: 1
|
||
Fast Retransmits: 0
|
||
```
|
||
|
||
这些计数器独立追踪每个连接,允许你识别遇到数据包丢失或网络问题的有问题连接。
|
||
|
||
### 使用场景<a id="use-cases"></a>
|
||
|
||
**网络质量监控**
|
||
重传或乱序包的突然增加表明网络拥塞、数据包丢失或路由问题。
|
||
|
||
**连接故障排查**
|
||
特定连接上的高重传计数可以识别:
|
||
- 到某些目的地的不可靠网络路径
|
||
- 带宽受限的链路
|
||
- 故障的网络硬件或驱动
|
||
|
||
**性能分析**
|
||
快速重传频率表明 TCP 在不等待超时的情况下从数据包丢失中恢复的情况。
|
||
|
||
### 技术说明<a id="technical-notes"></a>
|
||
|
||
- 统计源自 TCP 序列号分析,不需要数据包时间戳
|
||
- 分析适用于出站和入站数据包
|
||
- SYN 和 FIN 标志在序列号追踪中被正确计算(每个消耗 1 个序列号)
|
||
- 仅 TCP 连接显示分析指标;UDP、ICMP 和其他协议没有这些指标
|
||
|
||
## 接口统计<a id="interface-statistics"></a>
|
||
|
||
RustNet 在所有支持的平台上(Linux、macOS、FreeBSD、Windows)提供实时网络接口统计。接口统计显示在两个位置:
|
||
|
||
### 访问接口统计<a id="accessing-interface-statistics"></a>
|
||
|
||
**概览标签页(主屏幕):**
|
||
- 接口统计出现在右侧面板,位于网络统计下方
|
||
- 显示最多 3 个活跃接口及当前速率
|
||
- 显示:`InterfaceName: X KB/s ↓ / Y KB/s ↑`
|
||
- 显示累计总数:`Errors (Total): N Drops (Total): M`
|
||
|
||
**接口标签页(详细视图):**
|
||
- 按 `i` 切换接口统计视图
|
||
- 显示所有网络接口的详细表格
|
||
- 显示每个接口的综合指标
|
||
|
||
### 显示的统计<a id="statistics-displayed"></a>
|
||
|
||
| 指标 | 描述 | 说明 |
|
||
|--------|-------------|-------|
|
||
| **RX Rate** | 当前接收速率(字节/秒) | 根据近期活动计算 |
|
||
| **TX Rate** | 当前发送速率(字节/秒) | 根据近期活动计算 |
|
||
| **RX Packets** | 接收的总数据包数 | 自启动/接口上线以来累计 |
|
||
| **TX Packets** | 发送的总数据包数 | 自启动/接口上线以来累计 |
|
||
| **RX Err** | 接收错误 | 累计总数(非近期) |
|
||
| **TX Err** | 发送错误 | 累计总数(非近期) |
|
||
| **RX Drop** | 丢弃的入站数据包 | 累计总数(非近期) |
|
||
| **TX Drop** | 丢弃的出站数据包 | 累计总数(非近期) |
|
||
| **Collisions** | 网络冲突 | 平台相关的可用性 |
|
||
|
||
**重要**:错误和丢弃计数器是**自系统启动或接口上线以来的累计总数**,不是近期活动。这些有助于识别长期接口可靠性,但不会显示即时问题。
|
||
|
||
### 平台特定行为<a id="platform-specific-behavior"></a>
|
||
|
||
**所有平台:**
|
||
- 所有计数器(字节、数据包、错误、丢弃)自启动/接口上线以来累计
|
||
- 速率(字节/秒)根据每 2 秒采集的快照计算
|
||
- 包含回环接口用于监控本地流量
|
||
|
||
**Windows:**
|
||
- 过滤掉虚拟/过滤适配器,仅显示物理接口:
|
||
- 排除:`-Npcap`、`-WFP`、`-QoS`、`-Native`、`-Virtual`、`-Packet` 变体
|
||
- 排除:`Lightweight Filter`、`MAC 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` 读取统计
|
||
- 所有计数器通常可用且可靠
|
||
|
||
### 解读统计<a id="interpreting-the-statistics"></a>
|
||
|
||
**健康的接口:**
|
||
```
|
||
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)
|
||
- 网络拥塞
|
||
- 驱动或硬件问题
|
||
|
||
**注意**:由于错误/丢弃计数器是累计的,请相对于总数据包数来评估它们。数百万数据包中有少量错误是正常的;数据包数低但有数千错误则表明有问题。
|
||
|
||
### 接口过滤<a id="interface-filtering"></a>
|
||
|
||
**显示哪些接口:**
|
||
- 接口必须在操作上 "up" OR 拥有流量统计
|
||
- 包含回环接口(用于监控本地连接)
|
||
- Windows 上排除虚拟/过滤适配器(它们镜像物理接口)
|
||
|
||
**概览标签页过滤:**
|
||
- Windows:显示所有活跃接口(NPF 设备路径自动检测)
|
||
- macOS/Linux:显示有近期流量的接口(`rx_bytes > 0 || tx_bytes > 0 || rx_packets > 0 || tx_packets > 0`)
|
||
- 特殊接口(`any`、`pktap`):显示有任何活动的所有接口
|
||
|
||
**接口标签页:**
|
||
- 显示通过平台特定过滤的所有检测到的接口
|
||
- 排序将当前捕获的接口排在最前面(高亮)
|
||
- 其他接口按字母顺序出现
|
||
|
||
### 使用场景<a id="use-cases-1"></a>
|
||
|
||
**带宽监控:**
|
||
监控所有网络接口的实时带宽使用情况以识别:
|
||
- 哪个接口承载最多流量
|
||
- WiFi 与 Ethernet 之间的带宽分布
|
||
- 本地流量体积(回环接口)
|
||
|
||
**可靠性分析:**
|
||
检查累计错误和丢弃计数器以:
|
||
- 识别不可靠的网络接口
|
||
- 检测硬件或驱动问题
|
||
- 随时间比较接口质量
|
||
|
||
**多接口系统:**
|
||
在具有多个网络接口的系统上:
|
||
- 跨接口比较性能
|
||
- 监控 VPN 隧道统计
|
||
- 追踪接口故障转移行为
|
||
|
||
## 连接生命周期与视觉指示器<a id="connection-lifecycle--visual-indicators"></a>
|
||
|
||
RustNet 使用智能超时管理自动清理不活跃的连接,同时在移除前提供视觉警告。
|
||
|
||
### 视觉陈旧度指示器<a id="visual-staleness-indicators"></a>
|
||
|
||
连接根据距离被清理的接近程度改变颜色:
|
||
|
||
| 颜色 | 含义 | 陈旧度 |
|
||
|-------|---------|-----------|
|
||
| **白色**(默认) | 活跃连接 | < 75% 的超时时间 |
|
||
| **黄色** | 陈旧 - 接近超时 | 75-90% 的超时时间 |
|
||
| **红色** | 严重 - 即将被移除 | > 90% 的超时时间 |
|
||
|
||
**示例**:一条超时为 10 分钟的 HTTP 连接会:
|
||
- 前 7.5 分钟保持**白色**
|
||
- 7.5 到 9 分钟变为**黄色**(警告)
|
||
- 9 分钟后变为**红色**(严重)
|
||
- 10 分钟时被移除
|
||
|
||
这让你在连接即将从列表中消失前得到预警。
|
||
|
||
### 智能协议感知超时<a id="smart-protocol-aware-timeouts"></a>
|
||
|
||
RustNet 根据协议和检测到的应用调整连接超时:
|
||
|
||
#### TCP 连接<a id="tcp-connections"></a>
|
||
- **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 连接<a id="udp-connections"></a>
|
||
- **基于 UDP 的 SSH**:**30 分钟** —— 长会话
|
||
- **DNS**:**30 秒** —— 短查询
|
||
- **普通 UDP**:**60 秒** —— 标准超时
|
||
|
||
#### QUIC 连接(检测到的状态)<a id="quic-connections-detected-state"></a>
|
||
- **已连接**:**3 分钟** 默认(或当可用时使用来自传输参数的 idle timeout)
|
||
- **带 CONNECTION_CLOSE 帧**:1-10 秒(基于关闭类型)
|
||
- **Initial/Handshaking**:60 秒 —— 允许连接建立
|
||
- **Draining**:10 秒 —— RFC 9000 draining 周期
|
||
|
||
### 基于活动的调整<a id="activity-based-adjustment"></a>
|
||
|
||
显示近期数据包活动的连接获得更长的超时:
|
||
- **最近数据包 < 60 秒前**:使用"活跃"超时(更长)
|
||
- **最近数据包 > 60 秒前**:使用"空闲"超时(更短)
|
||
|
||
这确保活跃连接保持可见,而空闲连接更快被清理。
|
||
|
||
### 连接为什么消失<a id="why-connections-disappear"></a>
|
||
|
||
连接在以下情况下被移除:
|
||
1. **在超时期间内未收到数据包**
|
||
2. 连接进入**关闭状态**(TCP CLOSED、QUIC CLOSED)
|
||
3. 检测到**显式关闭帧**(QUIC CONNECTION_CLOSE)
|
||
|
||
**注意**:速率指示器(带宽显示)基于近期活动显示*衰减*的流量。连接可能显示带宽下降(黄色条),但在超过空闲超时前仍保留在列表中。这是有意设计的 —— 视觉衰减让你在连接被移除前有时间看到它逐渐结束。
|
||
|
||
### 历史连接<a id="historic-connections"></a>
|
||
|
||
默认情况下,连接在超时或关闭后从列表中消失。按 `t` 切换**历史连接**模式,使已关闭的连接与活跃连接一起保持可见。
|
||
|
||
**工作原理:**
|
||
|
||
当连接被清理时,它被归档到历史连接池中(最多 5,000 条;最旧的先被逐出)。按 `t` 切换它们的可见性:
|
||
|
||
- **活跃连接**以标准颜色指示器正常显示
|
||
- **历史连接**以**暗灰色**显示,以清楚区分于活跃连接
|
||
- 启用历史模式时,表格标题变为 **"Active + Historic Connections"**
|
||
|
||
**详情视图:**
|
||
|
||
选择历史连接并按 `Enter` 显示通常的连接详情,外加一个**Status**字段显示连接关闭多久前(例如 "Closed (5m ago)")。
|
||
|
||
**统计面板:**
|
||
|
||
当存在历史连接时,统计面板在总活跃连接数下方显示一个单独的 **"Historic: N"** 计数。
|
||
|
||
**分组视图:**
|
||
|
||
在进程分组模式(`a`)中,当启用历史模式时,分组头部将历史连接数与活跃计数分开显示。
|
||
|
||
**图表标签页:**
|
||
|
||
图表标签页始终只显示活跃连接,即使历史模式开启。
|
||
|
||
**重置:**
|
||
|
||
- 按 `r` 重置所有视图设置,这也会隐藏历史连接
|
||
- 按 `x` 两次清除所有连接,这也会清除历史池
|
||
|
||
## 日志<a id="logging"></a>
|
||
|
||
日志**默认禁用**。使用 `--log-level` 选项启用时,RustNet 在 `logs/` 目录中创建带时间戳的日志文件。每个会话生成一个新日志文件,格式为 `rustnet_YYYY-MM-DD_HH-MM-SS.log`。
|
||
|
||
### 日志文件内容<a id="log-file-contents"></a>
|
||
|
||
日志文件包含:
|
||
- 应用启动和关闭事件
|
||
- 网络接口信息
|
||
- 数据包捕获统计
|
||
- 连接状态变更
|
||
- 错误诊断
|
||
- DPI 检测结果(debug/trace 级别)
|
||
- 性能指标(trace 级别)
|
||
|
||
### 启用日志<a id="enabling-logging"></a>
|
||
|
||
使用 `--log-level` 选项启用日志:
|
||
|
||
```bash
|
||
# Info 级别日志(建议常规使用)
|
||
sudo rustnet --log-level info
|
||
|
||
# Debug 级别日志(详细故障排查)
|
||
sudo rustnet --log-level debug
|
||
|
||
# Trace 级别日志(非常详细,包含数据包级详情)
|
||
sudo rustnet --log-level trace
|
||
|
||
# 仅 Error 级别日志(最小日志)
|
||
sudo rustnet --log-level error
|
||
```
|
||
|
||
### 日志级别说明<a id="log-levels-explained"></a>
|
||
|
||
| 级别 | 记录内容 | 使用场景 |
|
||
|-------|------------------|----------|
|
||
| `error` | 仅错误和关键问题 | 生产监控 |
|
||
| `warn` | 警告和错误 | 带警告的正常运行 |
|
||
| `info` | 一般信息、启动/关闭 | 标准调试 |
|
||
| `debug` | 详细的调试信息 | 故障排查 |
|
||
| `trace` | 数据包级详情,非常详细 | 深度调试 |
|
||
|
||
### 管理日志文件<a id="managing-log-files"></a>
|
||
|
||
**日志清理脚本:**
|
||
|
||
提供了 `scripts/clear_old_logs.sh` 脚本用于日志清理:
|
||
|
||
```bash
|
||
# 删除 7 天前的日志
|
||
./scripts/clear_old_logs.sh
|
||
|
||
# 通过编辑脚本自定义保留期
|
||
```
|
||
|
||
**手动清理:**
|
||
|
||
```bash
|
||
# 删除所有日志
|
||
rm -rf logs/
|
||
|
||
# 删除 7 天前的日志(Linux/macOS)
|
||
find logs/ -name "rustnet_*.log" -mtime +7 -delete
|
||
|
||
# 查看日志文件大小
|
||
du -sh logs/
|
||
```
|
||
|
||
### 日志文件隐私<a id="log-file-privacy"></a>
|
||
|
||
⚠️ **警告**:日志文件可能包含敏感信息:
|
||
- IP 地址和端口
|
||
- 主机名和 SNI 数据(HTTPS)
|
||
- DNS 查询和响应
|
||
- 进程名和 PID
|
||
- 数据包内容(trace 级别)
|
||
|
||
**最佳实践:**
|
||
- 仅在需要调试时启用日志
|
||
- 保护日志目录权限:`chmod 700 logs/`
|
||
- 分享前检查日志中的敏感数据
|
||
- 实施日志轮转和保留策略
|
||
- 不再需要时删除日志
|
||
|
||
### 使用日志故障排查<a id="troubleshooting-with-logs"></a>
|
||
|
||
报告问题时:
|
||
1. 启用 debug 日志:`rustnet --log-level debug`
|
||
2. 重现问题
|
||
3. 在 `logs/` 中找到最新的日志文件
|
||
4. 查看错误或异常行为
|
||
5. 分享前脱敏敏感信息
|
||
|
||
对于性能问题,trace 级别日志提供最详细的细节,但会快速生成大量日志文件。
|
||
|
||
### JSON 日志<a id="json-logging"></a>
|
||
|
||
`--json-log` 选项启用将连接事件以结构化 JSON 格式记录到文件。每行是一个独立的 JSON 对象(JSONL 格式)。
|
||
|
||
```bash
|
||
# 启用 JSON 日志
|
||
sudo rustnet --json-log /tmp/connections.json
|
||
|
||
# 与其他选项组合
|
||
sudo rustnet -i eth0 --json-log ~/network-events.json
|
||
```
|
||
|
||
**事件类型:**<a id="event-types"></a>
|
||
- `new_connection` —— 首次检测到新连接时记录
|
||
- `connection_closed` —— 连接在变为不活跃后被清理时记录
|
||
|
||
**JSON 字段:**<a id="json-fields"></a>
|
||
|
||
| 字段 | 类型 | 描述 |
|
||
|-------|------|-------------|
|
||
| `timestamp` | string | RFC3339 UTC 时间戳 |
|
||
| `event` | string | 事件类型(`new_connection` 或 `connection_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 | 连接方向(`outgoing` 或 `incoming`),仅当观察到 TCP 握手时 |
|
||
| `dpi_protocol` | string | 检测到的应用协议(如果启用 DPI) |
|
||
| `dpi_domain` | string | 提取的域名/主机名(如果可用) |
|
||
| `bytes_sent` | number | 发送的总字节数(仅 connection_closed) |
|
||
| `bytes_received` | number | 接收的总字节数(仅 connection_closed) |
|
||
| `duration_secs` | number | 连接持续时间,单位为秒(仅 connection_closed) |
|
||
|
||
**示例输出:**<a id="example-output"></a>
|
||
|
||
```json
|
||
{"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 日志:**<a id="processing-json-logs"></a>
|
||
|
||
```bash
|
||
# 漂亮打印最新事件
|
||
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 导出<a id="pcap-export"></a>
|
||
|
||
`--pcap-export` 选项将原始数据包捕获到标准 PCAP 文件,供 Wireshark、tcpdump 或其他工具分析。
|
||
|
||
```bash
|
||
# 导出所有捕获的数据包
|
||
sudo rustnet -i eth0 --pcap-export capture.pcap
|
||
|
||
# 与 BPF 过滤器组合
|
||
sudo rustnet -i eth0 --bpf-filter "tcp port 443" --pcap-export https.pcap
|
||
```
|
||
|
||
**输出文件:**<a id="output-files"></a>
|
||
|
||
| 文件 | 描述 |
|
||
|------|-------------|
|
||
| `capture.pcap` | 标准 PCAP 格式的原始数据包 |
|
||
| `capture.pcap.connections.jsonl` | 流式连接元数据,带进程信息 |
|
||
|
||
**Sidecar JSONL 格式**(每行一个 JSON 对象,连接关闭时写入):<a id="sidecar-jsonl-format"></a>
|
||
|
||
```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<a id="enriching-pcap-with-process-information"></a>
|
||
|
||
标准 PCAP 文件不包含进程信息。使用附带的 `scripts/pcap_enrich.py` 脚本将数据包与进程关联:
|
||
|
||
```bash
|
||
# 安装 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 的数据包详情中可见。
|
||
|
||
#### 原生带注释 PCAPNG 导出<a id="native-annotated-pcapng-export"></a>
|
||
|
||
`--pcapng-export` 选项会直接写出带 RustNet 数据包注释的 PCAPNG 文件。想立即在 Wireshark 中打开捕获文件时,可以省去 Python 富化步骤:
|
||
|
||
```bash
|
||
sudo rustnet -i eth0 --pcapng-export capture.pcapng
|
||
```
|
||
|
||
数据包注释是实时的 best-effort 标注。RustNet 会短暂等待进程和 GeoIP 补全,然后即使归因仍不可用也会写出数据包;因此有些注释可能只有 DPI/SNI、方向或 GeoIP 字段,而没有 `process=`/`pid=`。高负载下,在处理器阶段之前丢弃的数据包或被有界 PCAPNG 导出队列丢弃的数据包不会出现在 PCAPNG 中,所以同时生成的 `--pcap-export` 文件可能包含 PCAPNG 中缺失的数据包。Enhanced Packet Block 可能不是按捕获时间顺序写入,但保留真实捕获时间戳,Wireshark 可以按时间排序/显示。
|
||
|
||
当清理阶段的元数据完整性比单个带注释文件更重要时,请使用 `--pcap-export` 加 `capture.pcap.connections.jsonl`。
|
||
|
||
**手动关联:**
|
||
|
||
```bash
|
||
# 查看数据包
|
||
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
|
||
```
|