[!TIP] 受众:自己在家折腾网络、遇到过开 BT 全家断网却查不出原因的人。 核心目标:用抓到的现场数据说明运营商内网地址的连接数限制怎么把全家网络卡死,以及怎么在路由器上拦住它。 问题-方案映射:
- 重启路由器导致日志丢失、查不出原因 → 日志改写到盘上,每分钟记健康快照,断网自动抓现场
- BT 瞬间发起大量无效连接占满运营商名额 → 路由器对 BT 机器的 IPv4 新建连接限速,IPv6 不限
- 改 BT 软件连接设置仍压不住突发连接 → 在路由器出口直接拒绝超出限额的请求,不让连接出家门
平时我自己在家折腾网络和服务器,遇到麻烦事就拉上 AI 一起查。这次聊一件挺丢人的事:家里一开 BT 下载,全屋就断网,我前前后后栽了两次跟头,一开始完全猜错了方向,最后才发现罪魁祸首根本不在家里的设备上,是我家拨号拿到的 IPv4 地址压根就是运营商的内网地址,连接名额被 BT 瞬间打满了。
一开 BT 全屋瘫痪,重启路由器成了障眼法
事情发生在 10 月 10 日和 10 月 24 日。这两天家里都遇到了同一个怪事:只要把 BT 下载一打开,没过多久全屋就断网了。最让人摸不着头脑的是,这时候就算把 BT 软件彻底停掉,网络也恢复不了,全家还是连不上网。唯一管用的办法就是去重启路由器,只要一重启,网络立马就恢复正常。
如果你遇到“重启路由器就好”的毛病,第一反应肯定跟我当时一模一样:这破路由器又挂了,八成是性能不够,或者里面的连接表被 BT 撑爆了。
但我两次都没能定下原因,因为我犯了一个低级错误——路由器的日志默认只存在内存里。每次家里断网,为了赶紧恢复网络,我伸手就把路由器重启了;这一重启,内存里的日志被擦得干干净净,什么报错、什么状态全没了。
10 月 10 日第一次出事当晚,我抓过一次包。当时看到的数据很奇怪:往外发出了 471 个连接请求,只回来 2 个回应,但与此同时 ping 却是通的。当时没想明白这意味着什么,重启完网通了,这事也就糊里糊涂过去了,直到 10 月 24 日晚上又摔了一跤。
先把证据留住,再故意把网搞断一次
10 月 24 日晚上第二次断网后,我决定不再瞎猜,更不能再随手重启把证据毁了。我和 AI 商量了一下,当晚第一步什么都不改,专门做“留证据”的工作:
首先把路由器的日志改成直接写到盘上,这样就算后面被迫重启,记录也不会丢。接着加了一个定时任务,每分钟记一行网络健康快照,把当时的连接数、国内和国外网站通不通、ping 正不正常、DNS 正不正常全记下来。最后再配好自动触发的脚本,只要一检测到断网,就自动抓一份当时的现场数据存盘。
证据收集的笼子支好之后,同一晚 21:17,我故意再开了一次 BT,一口气恢复了 22 个种子,想亲眼看看网络到底是怎么死的。
结果来得非常快。恢复种子后的 10 秒内,跑 BT 的那台机器一下子冒出了 1552 个对外连接,其中有 1454 个根本没有回应。过了一两分钟,这台机器的对外连接涨到了 2400 多个,里头九成都没回应;这时候全屋的对外连接峰值冲到了 2792。
到了 21:21,熟悉的症状准时出现:全屋不管国内还是国外的网站全都打不开了。自动脚本抓下来的现场数据里,有三条关键的:
- 网页全挂了,但 ping 和 DNS 依然正常。
- 抓现场的 5 秒钟内,往外发出了 478 个连接请求,回来 0 个。
- 直接打我脸的一条:路由器自己的连接表只用了 6%,表项插入失败的计数是 0,丢弃计数也是 0。
看到这组数字,我就知道之前冤枉路由器了。路由器活得好好的,连接表空得很,连一个包都没丢,问题肯定出在出了家门之后的地方。
21:21:38,我手动停掉了全部种子。这次我没有去碰路由器的电源,就盯着监控看。停掉种子之后,大概过了 20 秒,全屋网络自己恢复了。
根因:100.64 开头的内网地址和连接名额
把现场证据摆在一起,根因就清楚了。
我仔细看了一眼家里路由器拨号拿到的 IPv4 地址,是以 100.64 开头的。稍微懂点网络的朋友看到这个网段就明白了,这不是真正的公网地址,而是运营商的内网地址(也就是常说的运营商级 NAT,CGNAT)。
这意味着很多户人家其实在共用运营商的公网出口,每一户能同时占的连接数有上限。
回头看 21:17 那几分钟发生的事:BT 软件一启动,在一两分钟里往外打出两千多个连接请求,而这些种子里绝大部分节点早就连不上了。虽然连不上,但每一个发出去的请求,都会在运营商的设备那边占掉一个连接名额,直到等待超时才会被回收。短短一两分钟,这 2000 多个没有回应的死连接就把我家在运营商那边的名额彻底占满了。名额一满,家里其他设备再想打开网页、建立新的连接,运营商那边直接就不给放行了。
用这个原因去套之前的三个怪现象,全都说得通:
- 为什么停了 BT 网络不会马上恢复? 那些已经发出去、没收到回应的连接,在运营商那边要等超时才释放名额,21:21:38 那次就是等了约 20 秒才缓过来。
- 为什么一重启路由器马上就好? 重启会重新拨号,运营商分了一个新的内网地址,名额自然清零(我核对过,重启之后拿到的地址确实变了)。
- 为什么网页打不开,但 ping 和 DNS 却正常? 受影响的是新建的 TCP 连接。
至于运营商给每一户的具体上限到底是多少,这次没有专门测出来,我只知道当天晚上全屋连接数涨到 2792 的时候,网就断了。
在路由器上动手:把废连接拦在家门里
原因查清楚了,思路就很明确:不能让 BT 机器在短时间内往外狂发 IPv4 新连接。
我最先想到的省事办法,是直接去 BT 软件的设置里把“连接速度”调低。结果改完一试,根本没压住——调低之后再恢复那 22 个种子,10 秒内它照样往外打出了大约 1500 个连接请求(相当于每秒 150 个)。指望 BT 软件自己守规矩是靠不住了。
既然软件管不住自己的手,那就只能在路由器上拿绳子捆住它。我在路由器上专门针对跑 BT 的那台机器,加了 IPv4 新建连接的限速规则:
- TCP:每秒最多新建 5 个连接(允许瞬间冲到 20 个)。超出限额的不偷偷丢掉,而是直接回一个“拒绝”给 BT 机器,这样 BT 软件立刻知道这个连接失败了,不会傻等或者反复重发。
- UDP:每秒最多新建 10 个连接(允许瞬间冲到 40 个),超出的直接丢弃。
这么一来,那些超标的连接请求在自家路由器这一关就被拦下来了,根本出不了家门,自然也就不会去占运营商那边的名额。另外,家里分到的 IPv6 是实打实的公网地址,不受这个内网名额的限制,所以规则里对 IPv6 完全不限。
当晚 22:06,规则生效后,我再一次打开全部 22 个种子做测试:
| 21:17(没限速) | 22:06(限速后) | |
|---|---|---|
| BT 机对外连接峰值 | 2429 | 约 500,之后 300–480 |
| 全屋对外连接峰值 | 2792 | 约 1100 |
| 全屋网络 | 约 3 分钟后断 | 5 分钟内全部正常 |
这 5 分钟里,路由器一共拒绝了 855 个 TCP 新连接,丢弃了 5943 个 UDP 新连接。
拦掉这么多连接,BT 还能不能下?这 5 分钟里下载在 1.5 到 5.7 MB/s 之间,上传大约 2.4 MB/s。限速前的速度我没留数,没法说掉了多少。不过连接统计里 BT 有 3/4 的连接走的是 IPv6——IPv4 被限住之后还能下,靠的就是公网 IPv6。
后续观察与还没查明的事
改完之后的这一周,10 月 25 日和 10 月 26 日两天,家里的 BT 一共挂了大约 35 个小时(全程开着上面的限速规则),期间再也没有出现过这种全屋断网的情况。不过 10 月 29 日以后我基本没怎么开 BT,所以如果连续挂上更长时间稳不稳,目前还没验证过。
另外,既然每分钟都在记健康快照,我也如实交代一个日志里记下来的小毛病:这一周里,监控抓到了 8 次国内网站探测失败,每次只持续一分钟就自己好了,而且当时 BT 根本没开。这 8 次抽风是什么原因引起的,我还没去查。
折腾完这一圈,我自己最大的教训就一条:下次家里网络再出怪事,先别手欠急着去重启路由器。一重启,现场和证据就全没了;先让机器把现场留下来,比什么都强。