手机 SSH 不断线:mosh 与 tmux 配置指南
手机上 SSH 断线,要分两件事解决:tmux 让程序在服务器上继续运行,断线后重新附着就能回到原来的界面;mosh 用 UDP 代替 TCP 传输终端,手机换 IP、锁屏几分钟回来都不用重新登录。只装 tmux,任务不会丢,但每次断线要重新连一次;两个都装,体验最接近“从没断过”。
本文按 mosh 1.4.0、tmux 3.x 核对,命令以 Ubuntu / Debian 为例。
为什么手机上 SSH 总断
- 换网络:SSH 跑在 TCP 上,一条连接绑定手机当时的 IP。从 Wi-Fi 走到蜂窝网络,IP 一变,连接就失效了。
- 锁屏和后台:iPhone 会在应用进入后台后很快暂停它的网络;Android 的省电策略也会冻结后台应用。连接空闲太久,中间的 NAT 或防火墙还会悄悄丢掉它。
- 程序跟着连接一起结束:在普通 SSH 里直接运行的程序,是这条连接的子进程。连接断了,服务器发出 SIGHUP,程序通常随之退出。
前两条是连接的问题,mosh 解决;第三条是进程的问题,tmux 解决。
第一步:用 tmux 保住任务
sudo apt install tmux
每次登录后都进同一个会话,有就附着,没有就新建:
tmux new -A -s main
在里面运行编译、测试或 AI Agent。断线后重新登录,再执行同一条命令,就回到断开前的屏幕。想主动离开、让任务继续跑,按 Ctrl+B 再按 D。
适合手机的 tmux 设置
写入 ~/.tmux.conf,然后运行 tmux source ~/.tmux.conf 生效:
set -g mouse on # 手指上下滑动滚动 tmux 的历史
set -g history-limit 50000 # 多留一些历史,Agent 的输出很长
set -g status off # 手机屏幕小,不要状态栏(需要时再打开)
set -s escape-time 10 # 按 Esc 不延迟,Claude Code 等 TUI 更跟手
登录后自动进入 tmux
只想从手机登录时自动进入,可以在手机端的 SSH 客户端里把“登录后执行的命令”设成 tmux new -A -s main。不建议在 ~/.bashrc 里无条件启动 tmux,会影响 scp、rsync 和电脑上的登录。
第二步:用 mosh 跟着手机换网络
mosh 先用一次普通 SSH 登录,在服务器上启动 mosh-server,之后终端改走加密的 UDP。客户端每隔几秒发一次心跳,服务器总是把数据回给最近一次收到合法数据包的地址,所以手机换了 IP 也能继续,不用重新登录。网速慢时,mosh 会先在本地显示你输入的字符(带下划线),不用等服务器回显。mosh 为什么换网络不断线,原理见图解 mosh。
服务器配置
# Ubuntu / Debian
sudo apt install mosh
# macOS(Homebrew)
brew install mosh
还要放行 UDP 端口。mosh 从 60001 开始找空闲端口,同时连接的会话不多时,放行一小段就够了:
# ufw
sudo ufw allow 60000:61000/udp
云服务器还要在安全组里放行同样的 UDP 端口。服务器在家里的路由器后面时,与其在路由器上做端口转发,不如用 Tailscale:手机和服务器在同一个虚拟内网里,UDP 不用暴露到公网。
两者一起用
mosh 只同步“当前这一屏”,不保留终端自己的滚动历史,回看历史要靠 tmux。命令行客户端可以这样连:
mosh user@server -- tmux new -A -s main
这样一来,换网络和锁屏由 mosh 处理;mosh 也断了(比如手机关机一晚),tmux 里的任务还在,重新连上即可。
别让 mosh-server 越积越多
默认情况下,客户端消失后 mosh-server 会永远等下去,手机上每次“断开”都可能在服务器上留下一个。在服务器的 ~/.bashrc 或 /etc/environment 里设置超时:
export MOSH_SERVER_NETWORK_TMOUT=3600 # 一小时收不到客户端就退出
任务在 tmux 里,mosh-server 退出不影响任务。已经堆积的可以用 pkill -u "$USER" mosh-server 清掉(会断开你自己当前所有的 mosh 连接)。
常见报错
| 现象 | 原因与处理 |
|---|---|
mosh-server needs a UTF-8 native locale to run | 服务器缺 UTF-8 语言环境。运行 sudo locale-gen en_US.UTF-8,或在连接时指定 LANG=C.UTF-8 |
连不上,提示 Please verify that UDP port 60001 is not firewalled and can reach the server. | UDP 不通:检查 ufw、云安全组和路由器;手机上开着代理或 VPN App 时,它可能不转发 UDP |
mosh-server: command not found | 非登录 shell 找不到它,macOS 上常见。用 mosh --server=/opt/homebrew/bin/mosh-server user@host 指定路径 |
| macOS 弹窗询问是否允许 mosh-server 接收连接 | 在系统设置的防火墙里允许它,否则 UDP 进不来 |
| 手指滑动不能回看历史 | mosh 没有滚动历史。在 tmux 里开启 set -g mouse on,或用 Ctrl+B [ 进入复制模式翻页 |
| 端口转发、X11、ssh-agent 转发不起作用 | mosh 不支持这些功能,需要时另开一个普通 SSH 连接 |
Android 和 iPhone 上的 mosh 客户端
mosh 要求客户端自己实现 mosh 协议,只支持 SSH 的 App 用不了。截至 2026 年 10 月的情况:
| 客户端 | 平台 | mosh | 说明 |
|---|---|---|---|
| Blink Shell | iPhone、iPad | 支持 | mosh 官网列出的 iOS 客户端,命令行风格,适合熟悉终端的人 |
| Termius | Android、iPhone、桌面 | 支持 | 图形界面,免费版即可用 mosh;跨设备同步主机需要账号 |
| Termux | Android | 支持 | 手机上的 Linux 环境,pkg install mosh 后用命令行连接 |
| JuiceSSH | Android | 支持 | mosh 官网仍列出它,但 Google Play 上已经找不到,多年没有更新 |
| Roamtty | Android、iPhone | 支持 | 自动配合 tmux,详见下一节 |
Roamtty 怎么做
Roamtty 把上面的步骤做成了默认行为,添加主机时会话模式保持 tmux 即可:
- 一键安装:主机菜单的“安装插件”用服务器的包管理器装 tmux 和 mosh(Linux 用 apt、dnf、pacman 等并需要 sudo,macOS 用 Homebrew,Windows 用 winget 装 psmux),也能找到 Homebrew、MacPorts 和 snap 装在非标准路径的 mosh-server。
- mosh 里直接是 tmux:每个会话是服务器上独立的 tmux 会话,mosh-server 启动时就附着进去,开启 tmux 鼠标模式,上下滑动回看的是 tmux 的历史。
- 自动处理语言环境:依次尝试
en_US.UTF-8和C.UTF-8,服务器没生成语言包也能用上 mosh。 - 自动回退:8 秒收不到 UDP 回应就改走 SSH,并提示可能是 UDP 60000–61000 没放行。
- 不留残余进程:tmux 模式下 mosh-server 15 分钟收不到手机的数据就退出;手机睡得更久,回来时自动重新登录并附着 tmux。
- 文件仍走 SSH:终端走 mosh 时,SFTP 文件浏览和上传仍用 SSH,断了会在后台重新登录。
Roamtty 即将开源;iPhone 版已在 App Store 上架(中国大陆区暂未提供),Android 版即将上架 Google Play。配置细节见使用文档;在外面连回家里的服务器,见Tailscale 一节和自建 DERP 中继。
常见问题
| 问题 | 回答 |
|---|---|
| 只用 tmux、不装 mosh 可以吗? | 可以。任务不会丢,只是每次换网络或锁屏回来都要重新登录一次,通常几秒钟。 |
| 只用 mosh、不装 tmux 呢? | 短时间断网没问题,但 mosh-server 一旦退出(超时、服务器重启、手机关机一晚),里面的程序也随之结束,而且没有滚动历史。建议两个都装。 |
| mosh 安全吗? | 登录仍走 SSH,之后每个 UDP 数据包都用 AES-128 OCB 加密和认证,密钥通过 SSH 交给客户端。 |
| iPhone 锁屏后 mosh 也会断吗? | iOS 会暂停后台应用的网络,mosh 期间收不到数据,但 mosh-server 还在等;解锁回到应用后,mosh 接着同步屏幕,不用重新登录。 |
| mosh 能穿过 Tailscale 吗? | 能。mosh 走的是普通 UDP,连服务器的 100.x.y.z 地址即可,服务器防火墙要允许 tailscale0 网卡上的这些端口。 |