portbug说明

它测什么,怎么测,为什么可信

网页测速回答「我有多快」。portbug 回答的是另一类问题:哪个端口、哪个方向、在第几跳被限住了 —— 并给出一份能拿去跟机房或运营商对质的记录。

浏览器做不到的六件事

本站首页那个测速页只能测 HTTPS/443,那不是偷懒,是沙箱的上限。下面这些必须用本地程序:

任意 TCP 端口

浏览器只能发起 80 / 443 的连接。8080、3389、5060、51820 一概碰不到。

裸 UDP 吞吐

WebRTC 之外发不出裸 UDP 包,RDP / 游戏 / 音视频的真实上限测不到。

端口整形检测

需要逐秒吞吐序列与同链路对照端口,JS 计时被缓冲和 TLS 层抹平。

逐跳归因

需要构造 TTL 递增的 SYN 包,浏览器碰不到 IP 层。

TCP 重传与 cwnd

rtt / retrans / snd_cwnd / delivery_rate 是内核态数据,JS 读不到。

MTU 黑洞探测

需要控制包长与 DF 标志位,浏览器无此能力。

四条不肯妥协的规矩

没有对照组,就不下判定

只测一个端口然后说它被限速,那是猜的。没有同节点、同时段、同方向的可用对照端口时,结论一律是「无法判定」,不管数据多难看。宁可不出结论,也不出一个错的。

按时长计时,不按字节

时长在握手里由两端协商,各自按自己的时钟停。按字节的测试在慢链路上要跑几分钟,在快链路上只采到三个点 —— 两头都测不准。

限额两端都知道

限速只有一端知道会死锁:发送方按限额节流,接收方在等永远不会被安排发出的字节。所以限额写在握手帧里。

整形检测宁可漏报

拐点用变点检测(对均值做 Fisher 式打分)而不是「第一个低于阈值的样本」,两段速率取中位数,还要求掉档后至少 85% 的样本维持低位。早期版本会把 TCP slow-start 的第一个尖峰报成「掉档」—— 对一份要拿去吵架的报告来说,虚报比漏报危害大得多

「所有端口」是怎么做到的

监听 65535 个 socket 是不现实的。真正的做法是内核重定向:Linux 上用 nftables 把 1–65535 全部 REDIRECT 到一个 socket,再用 SO_ORIGINAL_DST(TCP)和 IP_ORIGDSTADDR(UDP)把原始目的端口交还给进程。

用 REDIRECT 而不是 TPROXY 是刻意的:REDIRECT 是 NAT 规则,conntrack 会把回包的源端口改回客户端瞄准的那个端口,节点不需要 IP_TRANSPARENT 那一整套。

怎么证明它真的生效了

节点在每个 ack 里回传它实际收到的端口号。客户端拿它和自己请求的端口比对,不一致就判定本次测量作废并拒绝发布 —— 捕获规则写错时,报告上的端口号会是错的,而这种报告是要拿去对质的。

没有 root 或不在 Linux 上时,节点退化成显式端口段监听,并在节点列表里如实标成 range 模式,不假装支持全端口。

端口不通时,到底是谁挡的

失败有三种形态,含义完全不同,分开报比只说「不通」有用得多:

形态含义
RST(refused)主机在线但该端口没有监听,或被明确拒绝。通常不是中途丢包。
超时数据包被静默丢弃,常见于中途防火墙或对端安全组。
ICMP unreachable路径上有设备明确拒绝转发。

一次真实的判定长什么样

$ portbug port 8080 --to sh-01

   TCP/8080 下行 ▁▄███████▁▁▁▁▁▁▁▁▁▁▁   3.1 Mbps  掉档 @1.83s · 桶 ≈ 20.1 MB
   TCP/443  下行 ▁▄███████████████████  94.2 Mbps  对照 · 平稳

  判定  TCP/8080 存在端口级令牌桶整形,稳态 3.1 Mbps
        同时段同链路的对照端口未出现掉档,可排除总带宽受限与本机瓶颈。
        置信度 高

  报告  https://portbug.pckee.com/r/3F7A2C

报告页带编号、时间戳、方法学和原始逐秒数据的核对链接,可以直接打印成 A4 附进工单。方法学那一段从不折叠隐藏 —— 报告的可信度就来自那里。

退出码

退出码是接口的一部分,脚本和 CI 不用解析文本:

含义
0达标
1未达阈值 / 判定异常(整形、降级)
2端口不通
3节点不可达
4配额耗尽
5用法错误

风控与隐私

只能测到 portbug 自己的节点。 客户端不接受任意目标 IP —— 一个能对任意地址打流量的工具就是压测/攻击工具,这条是从架构上堵死的,不是靠提示语。

客户端会采集本机出口 IP、路由与 ISP,用于生成报告;不采集与测量无关的信息。发布报告始终是显式动作(--publish,或页面上点一下),报告可设为私有。