Android+Termux 当服务器有多难 (Android+Termux as a Server)
一台闲置安卓手机 + Termux 当免费服务器的幻想,死于六层错位。本文不谈内网穿透(那是大家最先记住的痛,却是最外层、最好解决的一层),专拆"设备本身"这一侧的每一道锁。
一句话结论
Android 的操作系统哲学是"每十秒问一次用户",服务器的哲学是"没人理它,它自己跑"。两套哲学互不兼容。Termux 只是把一个普通 app 的权限尽量放开,并没有把 Android 变成服务器。
第一层:权限模型,根上就错位
Termux 再怎么说,本质是一个普通 app:
- 进程挂在
u0_a91这样的 app UID,跑在 SELinux 的untrusted_app域 - 系统全局状态基本不可见:
cat /proc/loadavg、/proc/stat直接Permission denied(实测,SELinux 拒绝,非 root 无解) - 读不了 dmesg、调不了 CPU 频率、改不了系统设置
- 服务器运维第一件事——"看看机器状态"——在这里就做不到
抽象:服务器运维的"观测权"是地基,Termux 连地基都没有。
第二层:root 这扇门,被焊死
大量"服务器必备"能力只对 root 开放:
- 绑定 1024 以下端口(需 setcap 或
net.ipv4.ip_unprivileged_port_start) - iptables 转发、按进程 cgroup 限流
- 真正的 chroot、mount、mknod
- 加载内核模块
- 全局进程监控
这台机器(骁龙 778G+ / SM7325,内核 5.4.289-qgki)的实际处境:
- bootloader 锁定 → 无 TWRP → 无 Magisk → 无自定义内核/ROM → root 的标准路径全断
- 厂商 ROM 连刷机都锁,最后一条路也堵死
- 于是只能靠 proot-distro:那是 syscall 模拟的"假 root",能跑 apt、装包,但做不了真 root 的事,更装不了 systemd / Docker
抽象:root 在 Android 上不是"更多权限",是"入场券"。锁了 bootloader 等于永不上车。
第三层:进程生命周期站在对立面
服务器要 7×24 无人值守,Android 的一切设计都在消灭后台进程:
- 没有开机自启,没有真正的 init 服务管理;
termux-services(runit)是模拟,termux-boot要 ROM 放行,国产 ROM 的电池管家随时一刀切 - Doze、App Standby、厂商省电策略:进程被杀、调度被延迟是常态
termux-wakelock只能拿 wake lock 防 CPU 睡眠,防不了被杀- cron 不存在;AlarmManager 不是 crontab,定时任务会延迟、会丢
抽象:你没法承诺"这个进程明天还在"。而"明天还在"是服务器的底线。
第四层:内核与服务器需求错位
移动内核是为手机定制的,不是为服务端定制的:
- 大量 CONFIG 裁剪,缺模块
- Docker 需要的 overlayfs、netns、cgroup 挂载基本没有 → Docker 装不了
- zram swap 存在但不可控
- 负载完全不可解释(且 Termux 里根本观测不到):实测 load average 13+、三档齐平,但 CPU 800% idle、user 0%、sys 0%。后经 adb 全局视角定位:不是用户进程,是厂商 ROM 内核常年挂 D 状态的 kworker / kdmflush / loop[0-39] / ext4-rsv-conver 内核线程把 load 顶起来的正常基线。移动内核的 load 统计含"不可中断任务",而这些线程只是挂着等设备事件,不占 CPU、不干活。想在 Termux 里解释 load,连读
/proc/stat的权限都没有。 - 旗舰 SoC 持续负载 = 热降频 + 电池鼓包风险,越跑越糟
抽象:你不是在调优一台机器,是在一台"不允许你观察、也不允许你控制"的机器上调优。
第五层:网络控制权不在你手里
- 低端口要特权(见第二层)
- 系统"全局代理"覆盖不到 Termux:手机开代理,Termux 的
pkg update照样裸连报错,得自己export http_proxy - WiFi AP 隔离、运营商 CGNAT 都是外部变量(本文不展开,见相关笔记)
抽象:手机的网络栈是"为上网设计的",不是"为被访问设计的"。
第六层:维护是一场持续消耗战
- ROM 更新可能清空数据分区;bootloader 锁了,连系统级备份回滚都做不到
- 沙箱 + scoped storage 限制,Termux 数据目录备份迁移麻烦
- 每次系统升级都可能踩新坑,运维成本高于一台小主机
补充实战:内网穿透下的端口与服务联动(frpc 踩坑实录)
上面第五层说"低端口要特权",frp 实战就是它的直接投影。frp 把"外网→本机"打通后,困住你的往往是本地这一侧的端口错位。
场景:frps 服务端 103.224.80.31:7000(带 auth token),本地一条 HTTPS 隧道挂三个域名 api / vault / new.6767.chat。frpc 的 https 类型代理 = frps 在公网终止 TLS,把 HTTP 转发到 localIP:localPort。
- 坑 1:localPort 必须指到本地服务真实监听的端口。本地路由网关
ai-6767-gateway(node server.js)监听127.0.0.1:8443,反代到后端 new-api(127.0.0.1:3000)。为什么不是 443?因为 Termux 非 root 绑不了低端口(第五层),网关只能在 8443。若 frpclocalPort写成 443,公网 TLS 握手直接 Connection refused。 - 坑 2:判断"真通了"要看业务层。frpc 日志
start proxy success只代表隧道注册成功;验证方式是公网curl https://域名返回 HTTP 200。 - 坑 3:控制脚本硬编码配置格式。服务控制脚本
frpc-ctl内硬编码CONFIG_FILE="~/.config/frp/frpc.json"。新版 frpc 支持.toml,但直接替换会让启停脚本找不到文件、孤儿进程占住端口。改配置文件格式 = 控制脚本一起改。 - 坑 4:废弃域名残留。旧域名
ai.6767.chat在面板已删除,配置若残留,日志会反复报您的账号下不存在域名为 [ai.6767.chat] 的 HTTPS 隧道,proxy 一直 start error。域名以面板为准,别凭记忆写。
一句话规律:https 类型隧道的 localPort 指向的是"离 Termux 最近的那个 http(s) 服务"的实际端口,不是你想暴露的"理想端口"。Termux 侧凡是跟端口打交道的地方,默认先把"非 root 绑不了 1024 以下"记在心上。
判断框架
想把"能不能在这台安卓上干 X"问清楚,过三个问题:
- 需要 root 吗?需要 → 死(这台机器已焊死)
- 需要开机自启 / 长驻吗?需要 → 半死(有 hack,但不可靠)
- 需要全局状态 / 低端口 / 容器吗?需要 → 死(权限与内核都不给)
三个问题都过了,才轮到"网络通不通"。所以内网穿透反而是最外层的那个问题——它只是最后一道门,不是第一道。
什么能当,什么不能当
能当:
- 个人跳板:SSH 进来跑脚本、开内网小服务
- 轻量代理进程、agent 类任务(codex、node 代理这类"睡在那"的进程没问题)
- 当"客户端"很称职:接 API、手动触发的任务
不能当:
- 需要可靠自启、定时任务、低端口、Docker、全局监控的"真服务器"
- 需要长时间无人值守稳定运行的东西
平替:如果真想要个便宜服务器
- ARM 开发板 / 二手小主机(几十到几百元),是安卓这个坑的平替
- 或者让手机继续当"客户端",服务器交给真正的服务器
相关
- 用 SSH + Termux 玩旧手机——连接层面的 how-to
- SSH 协议
本文归档于个人知识库 · 领域:CS & AI · 模块:04 Project_CS_AI/Network