斐讯 K2P 刷机记:SSH 都起不来的路由器,整个重刷

家里翻出一台斐讯 K2P,想让它当透明代理网关。结果第一步就卡死了:SSH 的 22 端口死活不通,LuCI 界面里把 SSH 配置翻了个遍,保存、重启、再保存,端口还是拒绝连接。

没有 SSH,还有 ubus

ping 通、80 通、22 拒绝。我想起 OpenWrt 的 LuCI 底下还挂着一个 ubus JSON-RPC 接口(POST /ubus),试了一下居然能用 root 登进去,而且权限大得惊人:能读写 UCI 配置、控制服务、甚至 opkg 装包。

检查发现 dropbear 的配置完全正常——端口 22、LAN、密码登录全开着。但再看 /etc/dropbear/ 下面的两个 host key 文件:全是 0 字节。空密钥,dropbear 一启动读到空文件就直接退出了。

越挖越深:overlay 坏了

host key 为什么是空的?密钥是首次开机时生成的,要写入 overlay 可写分区。我试着往 /etc 下写任何文件,全部报错;往 /tmp(内存盘)写,正常——jffs2 可写分区坏了。这一下全解释了:界面配 SSH 无效(写不进去)、密钥空(写到一半失败)、而且这类损坏基本没法修。

那就别修了,整个重刷。但这台是 16MB flash 的 K2P(MT7621 / 128MB 内存),官方 OpenWrt 是干净的,可它装不下 25MB 的 xray 内核。最后选了 Kwrt 的现成构建:passwall 和 sing-box 都编译进了 squashfs,16MB 刚好放得下。

没有 SSH 怎么刷固件

14.2MB 的固件要传上去。试了 JSON-RPC 直传,19MB 的报文直接被 uhttpd 掐断。正解是 LuCI 自带的 cgi-io 上传通道——multipart 表单带上 sessionid、目标路径和文件,走流式处理,响应里还会返回 sha256,跟本地比对一下,端到端完整性就有底了。接着用 ubus 调 validate_firmware_image,签名和设备匹配全绿,sysupgrade -n --force,两分钟后路由器带着新系统回来了,LAN 地址、账号密码跟原来习惯一致。

跟 OOM 杀手大战三百回合

装 passwall 的过程踩了三个 UCI 的坑:全局配置节是匿名的要用 @global[0] 引用;新版字段名叫 node 不叫 tcp_node;节点 section 类型必须是 nodes(复数)。代理通了一瞬,然后 sing-box 就开始被 OOM 杀手连杀十三次。

128MB 内存,基础占用就有 65MB,而内核默认的水位线 min_free_kbytes 是 16MB——对这台机器来说太奢侈了。三招下去:水位线降到 4MB、给 sing-box 的启动脚本注入 GOMEMLIMIT=16MiB 把 Go 堆封顶、zram 扩到 96MB 吸收峰值。稳态 RSS 从 34MB 压到了 7MB,从此再没被杀过。

结果

透明代理全通:被墙域名走美国 CN2 GIA,国内直连,飞书和智谱 API 安安稳稳。测速:直连 24 Mbps(家里宽带基线 25M,转发零损耗),走代理 12-14 Mbps——瓶颈在家宽和节点带宽,路由器本身一点没拖后腿。

一台快十年的百元矿渣,折腾两下午,又能再战几年。排查链上每一个"不可能"的背后,其实都有一个具体的坏东西:配置正常但密钥是空的、目录存在但写入是坏的、进程活着但内存是借的。挨个把它们找出来就行了。

← 返回首页