把手机服务器接入 Tailscale、SSH 和监控

2026年8月30日| Ruichen Zhou| 约 10 分钟阅读

Ubuntu 安装完成后,还要让其他电脑能稳定找到这台手机,并把它加进已有的监控。我的做法是把 Tailscale 安装在 Android,Ubuntu 不再安装第二套。其他设备在各自的 SSH 配置里加上这台手机,Uptime Kuma 检查 22 端口,Beszel 收集 CPU、内存和磁盘数据。

手机的 Ubuntu 安装过程见把闲置小米手机改成 Ubuntu 服务器,清理后 App 无法打开和递归挂载的问题见事故记录

1. 为什么后来改用 Tailscale

最初这台手机使用 Cloudflare IPv6 DDNS。手动更新和 keeper 自动更新都成功过,外部设备可以通过域名找到手机的 IPv6 地址。

手机连接 Wi-Fi 后通常会得到多个 IPv6 地址,其中的临时地址还会变化。99-phone-server.sh 只负责启动 /data/local/wifi-keeper/wifi-keeper.sh;检查 Wi-Fi 和 IPv6、断线时重新连接、从多个地址中选择一个相对稳定地址的工作都由 wifi-keeper 完成。这个做法来自 Semmering 的手机搭建服务器第四期

后来,经常访问手机的香港 VPS、N1 和平板都已经加入 Headscale。让这些设备通过 Tailscale 访问手机后,SSH 配置不再需要跟随公网 IPv6 改动。Wi-Fi keeper 仍然保留,用来处理 Wi-Fi 和 IPv6 断线。DDNS 记录之后是否删除,我没有再确认。

附件中提供了 Wi-Fi 配置示例和可选的 Cloudflare DDNS 示例。完整的 Wi-Fi keeper 脚本仍需从 Semmering 的第四期文章取得,附件中的 config 示例对应其中的配置部分。

2. Tailscale 安装在 Android

我把 Tailscale App 安装在 Android,没有在 Ubuntu chroot 中再安装。这样 Headscale 中只出现一台 phone-server,Ubuntu 的 22 端口和 Termux 的 8022 端口都使用这个节点的 100.x 地址。

如果在 Ubuntu 中再装一套,会多出第二个节点,还要处理 chroot 中的 TUN 设备和权限。这台手机不需要第二个节点。

先在 Headscale 服务器上为手机生成一枚一次性密钥。Android App 中的操作顺序是:

  1. 打开右上角设置,进入 Accounts
  2. 打开三点菜单,选择 Use an alternate server
  3. 填入自己的 Headscale 地址;
  4. 回到 Accounts 的三点菜单,选择 Use an auth key
  5. 填入一次性密钥,回到首页连接。

连接成功后,在 Headscale 中把节点命名为 phone-server。Headscale 部署、一次性密钥生成和 Android、iPad 接入的完整过程见自建 Headscale 教程。本文与链接文章中的 Tailscale 地址均以 100.x 代替实际地址。

3. 在其他设备中加入 SSH 配置

这段配置由 chezmoi 同步到各客户端;手机本身的 Magisk 和 Ubuntu 配置不入 chezmoi。

在共享 SSH 配置中加入:

Host phone-server
  HostName 100.x
  User <Ubuntu 用户名>
  Port 22

之后在开发机上执行 ssh phone-server,默认进入 Ubuntu 的 22 端口。Termux 的 8022 不放进这段共享配置,它只在 Ubuntu 无法启动或需要修改 Android 文件时使用。

4. 检查 SSH 公钥登录

Ubuntu 用户、authorized_keys 和 sshd 的配置已经在搭建篇完成。加入 Tailscale 后,重新从开发机建立一次公钥连接:

ssh -o ControlMaster=no -o ControlPath=none phone-server

每台发起连接的设备生成自己的密钥,只把公钥加入手机用户的 authorized_keys。手机与香港 VPS 需要双向连接时,两边各自生成密钥并交换公钥,不复制同一把私钥。详细做法见SSH 密钥网格

这里禁用了 macOS 的 ControlMaster 连接复用,确保这次连接真的重新认证。测试机上公钥登录成功,密码登录被拒绝。

5. 用 Uptime Kuma 检查 SSH

Uptime Kuma 运行在香港 VPS。我增加了一条名为 SSH @phone-server 的 TCP 监控,目标填写手机的 100.x 地址,端口填写 22。

这项监控表示香港 VPS 能否通过 Tailscale 连接手机的 Ubuntu sshd。它适合发现 Tailscale 断线、手机离线或 22 端口没有监听;资源占用由下面的 Beszel 负责。

6. 用 Beszel 查看资源占用

Beszel Hub 运行在 N1,手机的 Ubuntu 中只安装 Agent。现场核实过当前连接方向:手机上的 Agent 主动通过 WebSocket 连接 N1 上 Hub 的 8090 端口,连上后把 CPU、内存和磁盘数据发到 N1。

Agent 通过 WebSocket 连上 Hub 后,手机本地不监听 45876。因此 45876 拒绝连接时,不要直接认定 Agent 已经停止;应在 Beszel Hub 中查看 phone-server 是否为 up,以及数据是否继续更新。

Hub 和 Agent 的部署见Beszel 轻量监控部署,这里只在现有 Hub 中新增 phone-server

附件中的 phone-server-services 默认 ENABLE_BESZEL=0,不包含任何凭据。复现这台手机的监控时,按下面的顺序操作:

  1. 在 Beszel Hub 中新增 phone-server,取得 Hub 生成的 /etc/default/beszel-agent
  2. 把该文件放入 Ubuntu 的 /etc/default/beszel-agent,不要把含有 token 或 key 的文件提交到公开仓库;
  3. 把设备上 /usr/local/sbin/phone-server-services 实际副本中的 ENABLE_BESZEL 改为 1,Agent 会由 supervisor 在下一轮检查时启动。

7. Tailscale 重装后要修改三处地址

手机发生清理事故后,Android 的软件包历史中出现了 Tailscale 卸载记录,应用数据目录也不在了。重新安装 App 后,按照自建 Headscale 教程生成一次性密钥并注册新节点。

我先确认新节点能够连接,再删除旧节点,并继续使用 phone-server 这个名称。因为重新注册后的 100.x 地址发生了变化,三处配置要一起修改:

  1. 共享 SSH 配置中 Host phone-serverHostName
  2. Uptime Kuma 中 SSH @phone-server 的目标地址;
  3. Beszel 中 phone-server 的连接配置。

修改地址不会改变手机上的监听端口,Ubuntu 仍然使用 22,Termux 仍然使用 8022。

8. Beszel 没恢复时检查 N1

这次改完地址后,SSH 和 Kuma 已经恢复,Beszel 一度仍然没有数据。检查时发现 N1 上的 tailscaled 还保留着旧手机节点的映射。

手机侧没有再改动;我通过局域网 SSH 登录 N1,重启 tailscaled。重启后,Beszel 中的手机记录恢复为 up。旧映射与无数据之间的具体关系没有进一步排查。

遇到类似情况时,可以分别检查:

  1. 开发机能否新建 ssh phone-server 连接;
  2. 香港 VPS 上的 Kuma 是否显示 22 端口为 UP
  3. N1 上的 Beszel 是否收到手机 Agent 的新数据。

三项检查分别从开发机、香港 VPS、N1 发起,一项正常不代表另外两项。

9. 遗留问题

最新一次检查中,Kuma 为 UP,Beszel 中的 phone-serverup。手机可以远程连接,监控也有数据。

Ubuntu 与 Android 显示的系统负载仍在 33 左右,来源没有查明。rsyslog 曾因为无法写入 /var/log/auth.log 报错,rsyslog 和 fail2ban 也没有完成长期运行检查。以上问题留待另行排查。

评论