已集成到 Core 侧边栏中,顺序为 Plugins → Server Diagnostics → Hash & Checksum。它不需要 SSH 会话,也不需要下载插件。所有运行时代码、测试和测试夹具都位于 app/ 中;该模块不依赖任何同级存储库。存储库中没有 doc.md,因此由本文档和两份 README 描述其实现。
用户工作流程
输入主机名、IPv4、IPv6 或 HTTP(S)/WS(S) URL。单独的主机名/IP 默认使用 HTTPS;显式给出的 URL 在请求过程中会保留其路径、查询参数和端口。URL 中的凭据、不受支持的协议方案、空白/控制字符以及类似 shell 的主机名都会被拒绝。IPv6 字面量会自动加上方括号;URL 解析器不支持带作用域/链路本地区域标识符的地址。
选择 Auto(优先 IPv4,否则使用 IPv6)、IPv4、IPv6 或 Both。使用“解析地址”可以选择某个特定的当前应答。概览会显示所有解析出的应答;探测会测试所选地址,或为每个请求的协议族各测试一个地址。两个协议族会分别独立测量。仅存在 AAAA 记录绝不意味着 IPv6 连接可用。
Run Diagnostics(运行诊断)会运行 DNS、ping、traceroute、HTTP、压缩、TLS 以及所选的 TCP 端口检测。WebSocket 需要手动选择启用。每个工具还有单独的运行/停止控件。同一时间只能有一次诊断运行处于活动状态。一次运行完成只表示各工具已经结束,并不表示每项探测都成功。不存在笼统的“服务器离线”结论。
超时、数据包数量、重复次数、最大跳数、DNS 解析器、协议选择、预热连接以及 HTTP/HTTPS 比较均可配置。更改目标会清除之前选定的 IP。历史记录支持重新打开、比较两份报告、删除、导入 JSON、复制,或通过原生 Core 对话框导出为 JSON/CSV/TXT。浅色/深色/跟随系统主题适用于诊断部分,并保存在现有的 UI 配置中。CZ/DE/EN 界面语言会立即跟随应用语言。
组件与协议行为
| 组件 | 实现与解读 |
|---|---|
common.js |
验证目标/选项、限制和枚举值;IDNA 转换;数值统计会排除未知值。 |
dnsDiagnostics.js |
系统地址解析使用 dns.lookup,以遵循操作系统配置和 hosts 文件。记录查询使用受限的 UDP DNS,并在响应被截断时回退到 TCP,查询对象为 dns.getServers() 或明确选择的自定义/公共解析器。不会隐式切换到公共 DNS。 |
processTools.js |
使用参数数组和 shell: false 执行操作系统的 ping/traceroute,限制输出,设置显式超时,并负责中止/终止清理。解析数据包回复和跳点,而不是把进程运行时长当作 RTT。 |
httpDiagnostics.js |
内置 curl 用于 HTTP/1.1、HTTP/2 和 HTTP/3;严格的证书验证和固定的 IP 协议族。每个版本单独请求,并记录实际使用的版本。 |
socketDiagnostics.js |
显式的 TLS 版本探测、受限的 TCP 连接/被动横幅读取、使用现有 ssh2 依赖在身份验证前观察 SSH 主机密钥,以及可选的 RFC 6455 Upgrade 验证。 |
diagnosticsService.js |
运行和取消工具,选择/验证地址,流式传输进度,保留部分测量结果,并负责运行的截止时间。 |
historyStore.js |
带版本、有容量上限的本地历史记录、数据遮盖、经结构检查的导入以及测量数据的导出。 |
ICMP 与路由
Ping 默认发送四个逐一执行的 ICMP echo 请求。结果包含每个数据包实测的 RTT、收到/发送数量、丢包、最小/平均/最大值、总体标准差、相邻两次实测 RTT 之差的平均绝对值(抖动)、在输出中给出时的 TTL/Hop Limit,以及时间戳。<1 ms 的回复会被计为已收到,并记录其上限,而不会编造一个具体的 RTT 数值。未知的 RTT 不计入延迟统计。统计使用保留窗口内最多 500 个数据包;发送/接收/丢包计数则覆盖整个运行过程。图表显示最近 200 次观测,并用不同的符号区分回复、低于分辨率的回复、缺失的回复以及明确的请求/进程超时。
缺失的回复可能反映 ICMP 过滤、丢包或超时;这些观测无法确凿地认定存在防火墙。缺少可执行文件、本地权限失败和无效的工具调用属于单独的工具错误,而不是丢包或服务器不可用。不会请求提升权限。
Traceroute 会流式显示跳点、地址、单次探测、平均值以及观测到的无应答探测百分比。反向 DNS 在路由完成后使用所选解析器进行解析。重复运行会比较观测到的跳点地址序列;差异可能反映负载均衡。中间跳点无应答并不能证明路由中断。原始探测元数据和方法显示在可展开的详情中。macOS 要求 traceroute 的等待时间为整数秒;实际生效的取整超时值会被记录下来。
DNS
十二种记录类型为 A、AAAA、CNAME、MX、NS、TXT、SOA、SRV、CAA、PTR、DS 和 DNSKEY。DNS 报文解析会检查事务/问题的一致性、记录大小、压缩指针循环以及消息限制。应答会保留记录的 TTL、查询耗时、解析器,以及 NXDOMAIN/NODATA/SERVFAIL/refused/timeout 状态。操作系统的地址查询无法提供 TTL;单独的记录查询则可以。
跟随 CNAME 最多八次,并带有循环检测。一致性检查会从所选解析器重复获取 A/AAAA 应答,并对 IP 字面量的 DNS 测试执行正向确认的 PTR 查询。应答发生变化只是一种观测结果,并不能证明 DNS 存在故障。SRV 查询按原样使用目标名称;需要时请输入服务名称,例如 _service._tcp.example.org。DNSSEC 始终未经验证。DS/DNSKEY 的存在,甚至解析器的 AD 标志,都绝不会被视为独立的验证。
HTTP、性能与压缩
只有当服务器实际返回 HTTP/1.1 时,才会认为该版本受支持。HTTPS 上的 HTTP/2 要求协商出 h2;任何回退都不会被重新标记。明文 HTTP/2 使用先验知识(prior knowledge),而不是 HTTP/1.1 Upgrade 探测。对于每个 HTTP/WebSocket 请求,TLS 验证始终保持严格。
手动重定向最多八次;循环、无效的目标和过多的重定向都会明确报告失败。完整的重定向链会记录跨域变化和 HTTPS 降级;协议方案和 www 的变化可从源/目标 URL 中看出。凭据和非 HTTP(S) 的重定向协议方案会被拒绝。每个跨主机重定向都会通过所选解析器和请求的 IP 协议族独立解析。
测量项包括 DNS(如果执行了)、TCP、TLS、最终响应的 TTFB、包含 DNS/重定向在内的总 TTFB、下载、重定向和总耗时、实际实体字节数、传输速度、状态、响应标头、实际服务器地址/端口、ALPN 以及经过验证的连接复用。在固定或复用的连接上未执行的 DNS/TCP/TLS 阶段显示为 N/A,而不是虚假的零值。QUIC 没有 TCP 阶段;其握手会单独记录。标头传输或完整的线路开销不会被当作实体字节测量结果。这些是服务器/网络的时间数据,而不是页面渲染时间或 Lighthouse 分数。
每个选定的协议都使用相同的目标和重复次数。IPv4/IPv6 以及 HTTP/HTTPS 是显式的比较选项。另一种协议方案使用其默认端口。每个协议在每次采样时都会启动一个独立的内置客户端进程。不声称存在连接复用。总耗时统计包括最小值/平均值/中位数/最大值/最近秩 P95,以及单独的传输/协议错误率;即使服务器成功返回 4xx/5xx 响应,HTTP 状态码也会保持可见。
压缩检测会分别以 identity、gzip、deflate、br 以及(在运行时支持时)zstd 作为 Accept-Encoding 发送请求。Content-Encoding 必须匹配,且有限制的解压必须成功。只有当解码后的正文哈希、最终 URL 和状态与 identity 基准一致时,才会计算压缩率。被忽略的编码视为不受支持;内容变化/动态的正文不计算压缩率。这只是针对该 URL/状态的观测结果,并不代表服务器的普遍支持情况。
安全标头检查会显示 HSTS、CSP、X-Content-Type-Options、Referrer-Policy、Permissions-Policy 和 X-Frame-Options 是否存在及其取值。CSP 的 frame-ancestors 指令可以取代后者。标头存在并不能证明策略配置正确,也不能证明网站是安全的。
HTTP/3 的要求与证明
HTTP/1.1、HTTP/2 和 HTTP/3 使用同一个内置 curl 客户端。macOS arm64 和 Linux x64 使用 curl 8.22.0、OpenSSL 3.5.9、nghttp2 1.70.0、ngtcp2 1.25.0 和 nghttp3 1.18.0。Windows x64 使用 curl.se 官方 curl-for-win 8.22.0_3 静态构建,搭配 LibreSSL 4.3.3 和相同的 HTTP 库。无需回退到系统 curl,无需在运行时下载,也无需管理员权限。Windows 上游的可复现构建配方位于 https://github.com/curl/curl-for-win/tree/9d77e31e 。
打包前请使用 python3 scripts/native/build.py 进行构建(Windows:python scripts/native/build.py)。macOS/Linux 需要 C/C++ 工具、CMake、Ninja、Perl、make 和 pkg-config。源代码按版本和上游 SHA-256 固定在 scripts/native/dependencies.lock.json 中。脚本会验证每一次下载,静态链接第三方传输库,并在缺少 HTTP2/HTTP3/SSL 功能时失败。只有操作系统库保持动态链接。Windows 使用固定的官方二进制压缩包,而不是在本地编译的 Windows 传输栈。内置 CA 文件有其单独固定的哈希;组件许可证和上游构建来源信息随运行时一同提供。
客户端和信任存储安装在 app.asar 之外的 resources/native-runtime/<platform>-<arch>/ 中。每次诊断前都会验证组件哈希、架构和可执行文件的能力。配置文件、代理、TLS 信任环境覆盖以及库注入变量都会被排除。curl 以绝对路径运行,禁用 shell,使用经过验证的 CA 信任、显式解析的 IP 协议族,不使用 Cookie,不自动跟随重定向,并限制输出和时间。重定向由应用验证并重新解析。支持 443 以外端口上的 HTTPS。
HTTP/3 使用 --http3-only,只有在完成一次报告 HTTP 版本 3 且证书验证成功的传输之后才会被确认。404 之类的 HTTP 错误响应也可以确认该协议。Alt-Svc 只是一种通告,而不是证明。QUIC 超时、证书失败、DNS 失败、连接被拒绝、协议不兼容以及组件故障会被分别区分。UDP 超时意味着服务器是否支持仍未得到验证。QUIC 握手时间不会被报告为 TCP 时间。
每次测量都会启动一个单独的进程/连接。warm 选项不会声称内置客户端复用了连接。这样可以保证协议比较的一致性。报告包含运行时版本、能力、TLS 验证和 QUIC 计时,而历史记录/导出会移除正文、URL 查询参数和身份验证标头。
更新传输栈或 CA 信任存储时,请更新这些固定值并为每个受支持的平台重新构建。已发布的构件和源代码快照不可更改。
Core IPC
Preload 只公开 window.chjCore.diagnostics;所有处理程序都保留现有的主窗口发送方检查,网络操作始终在主进程中进行。结果使用 { ok: true, value } 或 { ok: false, error: { code, message } }。
| 通道 / preload 方法 | 载荷 / 结果 |
|---|---|
diagnostics:resolve / resolve(options) |
经过验证的目标/设置 → 目标及解析出的地址。最多同时进行两个解析请求。 |
diagnostics:start / start(options) |
经过验证的目标/设置/工具选择 → 不透明的任务 ID 和初始报告。 |
diagnostics:cancel / cancel(id, tool?) |
取消一个活动中/排队中的工具或整次运行。 |
diagnostics:get / get(id) |
已知运行或已保存报告的快照。 |
diagnostics:history / history() |
本地历史记录摘要。 |
diagnostics:removeHistory / removeHistory(id) |
删除所选的历史记录项。 |
diagnostics:copy / copy(id, format) |
主进程将一份经过遮盖的已知报告写入剪贴板。 |
diagnostics:export / export(id, format) |
通过原生保存对话框导出 JSON/CSV/TXT;渲染器无法提供文件系统路径。 |
diagnostics:import / import() |
原生文件选择器,存储前进行大小/结构/深度验证和数据遮盖。 |
diagnostics:progress / onProgress(callback) |
解析出的地址、工具的启动/完成、数据包、跳点、HTTP 采样和完成情况;返回一个取消订阅的回调。 |
不公开任何通用的 shell、文件系统或网络 API。上下文隔离、沙盒、禁用的 Node 集成以及现有的渲染器 CSP 均保持启用。现有的插件约定以及更新程序的验证/例外均未更改。
资源预算与本地数据
- 一次运行,两个活动工具,每个工具最多探测两个 IP 协议族;TCP 还会将每个地址限制为四个连接。
- 每项操作的超时为 250–30000 ms;1–100 个数据包,1–20 次重复,1–40 个跳点,1–16 个端口。常规运行在五分钟后停止;持续 ping 在三十分钟后停止。traceroute 子进程另有 180 秒的上限。
- 进程输出通常为 256 KiB;HTTP 实体正文 2 MiB;解压后的正文 8 MiB;HTTP 标头有大小限制;响应正文不会进入历史记录。
- 最多保留 500 个数据包/进度事件、内存中的五次运行、三十份历史报告以及 10 MiB 的历史记录。历史记录使用现有的私有原子写入器,路径为
<userData>/diagnostics/history.json(模式 0600)。 - 导入的文件最大 2 MiB,结构版本为 1,嵌套层级受限,结果集合经过验证。CSV 单元格会被转义,公式前缀会被中和。URL 查询参数/片段、凭据、Cookie、身份验证标头和原始正文都会从存储/复制/导出的报告中排除。原始详情显示的是测得的结构化数据,而不是数据包捕获或保留的响应正文。
- 没有云同步、自动登录、服务器配置更改或激进/不受限制的扫描。目标/端口/解析器由用户明确选择。
平台要求与验证
| 平台 | ICMP | 路由 | 其他协议 |
|---|---|---|---|
| Windows 10/11 | ping.exe -4/-6 |
tracert.exe -4/-6,ICMP |
内置的 curl.exe,支持 HTTP/2 和 HTTP/3。本地化的 RTT 字段不依赖单词“time”。 |
| macOS | /sbin/ping、/sbin/ping6 |
/usr/sbin/traceroute、/usr/sbin/traceroute6,UDP;整数秒等待 |
内置 curl,支持 HTTP/2 和 HTTP/3。 |
| Ubuntu/Linux | iputils ping -4/-6 |
标准的 traceroute -4/-6,UDP |
内置 curl,支持 HTTP/2 和 HTTP/3;缺少 ICMP/路由工具时会单独报告。 |
没有添加新的 npm 依赖项。实现使用 Node 内置模块和应用现有的 ssh2。它既不安装系统工具,也不请求管理员权限。防火墙和 UDP 限制可能导致测试无法确认支持情况;仅凭一次超时无法推断出这些限制。
自动化测试覆盖位于 diagnosticsCore.test.js、diagnosticsNetwork.test.js、diagnosticsHttp.test.js 和 diagnosticsIpc.test.js 中:验证/IPv6 字面量、原生/本地 DNS UDP+TCP 测试夹具、缺失/双协议族应答与解析器错误、CNAME/一致性、操作系统参数/解析测试夹具、受限的真实子进程、被阻止的 ICMP 观测、真实的本地 HTTP/1.1 和 TLS h2、重定向/正文限制/超时/复用、启用/被忽略的压缩、HTTP3 能力/成功结果解析/拒绝回退、本地 CA 信任/不匹配/过期以及真实的 IPv6 HTTP/HTTPS、TCP 连接/拒绝/模拟超时、真实的 WebSocket 和 SSH 身份验证前握手、取消/清理/部分结果、离线状态、私有历史记录往返/导入拒绝/导出、受信任的 IPC 以及 preload 订阅。
npm test 运行确定性的测试,不依赖公共测试服务器。npm run test:diagnostics:ui 会在图形化 Electron 桌面中运行 scripts/smokeDiagnostics.js,使用生产环境的 UI/preload/IPC 以及真实的本地 HTTP/压缩探测。只有在这个测试工具中,无关的服务才会被替换为桩/离线状态。它会检查导航顺序、协议结果、持久化、CZ/DE/EN、两种主题、窄窗口溢出以及沙盒偏好设置。如果 shell 设置了 ELECTRON_RUN_AS_NODE,请在运行此命令时取消该设置。
当前的运行时验证涵盖受控的 QUIC 传输、IPv4/IPv6、非默认端口上的 HTTPS、404 响应、TLS 失败,以及一个通告 Alt-Svc 的纯 TCP 服务。每个构建版本的结果随相应版本一同提供。
明确的可选限制:不进行独立的 DNSSEC 验证(这需要完整的验证型解析器/信任锚生命周期),不进行 Lighthouse 审计(仅限服务器/网络计时),不进行已弃用 TLS 审计或吊销/CT 服务检查,不声称 HTTP3 预热复用,也不测量 HTTP/3 预热复用。不受支持的能力会如实显示,而不是被模拟。
本次更改涉及的文件
新建:src/main/diagnostics/ 中的七个服务文件;src/renderer/diagnostics.js、diagnosticsI18n.js、diagnostics.css;四个 test/diagnostics*.test.js 文件;test/fixtures/diagnostics/ 下的五个文件;scripts/smokeDiagnostics.js;本文档。
集成/更新:src/main/index.js、src/main/ipc/registerCoreIpc.js、src/preload/corePreload.js、src/renderer/index.html、app.js、i18n.js、package.json、app/README.md、根目录的 README.md、.gitignore(四个公开测试夹具例外),以及根目录的 gitleaks 允许列表——其中仅精确列出那个刻意公开的 TLS 测试密钥夹具。签名 CA 的私钥已被丢弃;该测试夹具永远不会被应用运行时使用。