- NO.
- 048
- DATE
- 更新于
- READ
- ~21 min
- KIND
- 教程
- STATUS
- 原文
用手机接着用电脑上的 Pi
不必先学内网穿透。按手机是否要同时开其他 VPN 应用,选 Tailscale 或 Cloudflare,只走一条路线;附 Windows/WSL 配置、验收、每次开机后的命令和远程桌面的区别。
离开电脑后,用手机看看回答,补一句要求,让电脑继续做事。先实现这个目标,不必先买服务器,也不用先弄懂路由器端口映射。
本文用 Pi Web 举例,方法也适用于其他已经在电脑上运行的网页工具。示例环境是 Windows + WSL2(Windows 中的 Linux 环境)、Android 手机;示例环境里,路线 A 已经走通:手机关掉 Wi-Fi、用蜂窝网络打开电脑上的 Pi Web,登录后能看到会话、收到回复。路线 B 还没有实测,只按官方文档整理,文中标明了需要自己核对的地方。
先选一条路,另一条不用读
只问一个问题:使用 Pi Web 时,手机是否必须同时开着另一个 VPN 类应用?
- 不需要,或可以暂时关掉它:走 A:Tailscale 私有连接。网页内容只在自己的电脑上解开,不用买域名。
- 必须同时开:走 B:Cloudflare 固定网址。手机只用浏览器,代价是网页内容会先在 Cloudflare 解开,再转给你的电脑。
如果“必须同时开着另一个 VPN 应用”和“不让第三方解开内容”都是硬要求,这两条入门路线不能同时满足。先不要配置 B;需要另评估只转发密文、本机负责 HTTPS 的中继方案。
示例环境里,手机另装有一个 VPN 类应用,但不常开。Android 同一用户资料同时只能有一个活动 VPN(Android 开发者文档),Tailscale 也说明了 它不能与其他 VPN 同时运行;所以先关掉它试 A,不必卸载,也不必换成别的软件。
自己的域名只在 B 中使用。A 用 Tailscale 分配的 *.ts.net 地址,不要把自己的域名硬填进去。
两条路线到底怎么连?谁能看到什么?
把 HTTPS 想成一个封好的信封:路上的人只看得到信封,看不到信。两条路线的区别,在于信封在哪里拆开。
A:手机和电脑之间先搭一条只属于自己设备的加密通道,开启它的钥匙只存在两台设备上。直连不上时,数据会借道 Tailscale 的中继服务器,但中继没有钥匙,只能原样转交(DERP 中继说明)。Tailscale 的登录服务器只帮设备互相“介绍”,交换的是公钥和设备信息(Tailscale 的工作原理)。信封在你电脑上的 Serve 这里拆开,再交给本机的 Pi Web。
B:电脑上的 cloudflared 主动连到 Cloudflare,路由器不用开任何端口(Cloudflare Tunnel 说明)。手机打开固定网址时,信封在 Cloudflare 拆开,Access 先核对是不是你本人,再装进另一个信封经隧道送到电脑。访客到 Cloudflare、Cloudflare 到你的电脑,是两段各自加密的连接(Cloudflare 加密模式)。
| A:Tailscale | B:Cloudflare | |
|---|---|---|
| 谁能打开 | 只有登录了你账号的设备 | 谁都能到门口,只有通过 Access 的本人能进 |
| 在哪解开 | 你的电脑 | 先在 Cloudflare,再到你的电脑 |
| 服务商知道 | 账号、设备和谁连了谁;记录里没有流量内容 | 账号、登录记录,以及经过它的网页内容 |
| 进门后 | 还要输 Pi Web 密码 | 还要输 Pi Web 密码 |
Pi Web 密码是第二道锁:设备被别人拿到、或访问规则配错时,还有它挡着。它本身不加密连接,Pi Web 的说明也要求远程使用放在 HTTPS 或可信 VPN 后面(Pi Web 中文说明),这两条路线都满足。
只想偶尔点一下电脑:向日葵、UU 远程也可以吗?
可以。电脑和手机安装相应客户端,绑定本人设备后,在手机里控制电脑上的 Pi Web。通常不用另外配置本文的网页入口,远程控制功能一般也不占用第二个系统 VPN;具体版本仍需检查,手机上其他 VPN 应用的分流规则也可能影响连接。
两种体验有区别:远程桌面传输电脑画面和操作,能处理桌面弹窗、重启应用;手机网页把聊天内容按手机宽度排版,更适合长时间阅读和输入。前者在高画质、画面持续变化时通常更耗带宽,还受电脑屏幕分辨率影响。
远程桌面授权通常覆盖整台电脑,需保护账号、开启可用的二次验证,不分享连接码;不用的文件传输、剪贴板同步和无人值守权限可以关闭。厂商页面上的“加密”“隐私屏”不足以证明中继无法解密,本文没有核实这两款产品的完整加密实现,也没有做延迟排名。
如果已经装有一个可信的远程桌面工具,可以把它留作恢复电脑服务的备用入口,不必再装多个。没有特殊唤醒条件时,电脑关机或断网,它也不能凭空连上。
出门前,只确认电脑能打开
在运行网页工具的电脑上打开它的本地地址。Pi Web 默认是:
http://127.0.0.1:30141
看到页面才继续。本地还打不开,先修本地服务;隧道不会把坏掉的应用修好。手机里的 127.0.0.1 指手机自己,不能直接复制这个地址到手机使用。
首次安装 Pi Web,先按官方说明检查 Node.js 版本,再全局安装发布包。日常远程使用不要用开发服务器替代正式运行方式。
首次安装/WSL 用户:展开这一步
本文实测用的 Pi Web 0.12.2 要求 Node.js 22.19.0 或更高版本:
node --version
npm install -g @agegr/pi-web@0.12.2
command -v pi-web
pi-web version
pi-web --hostname 127.0.0.1 --port 30141 --no-open
版本只写在安装命令里,用来复现本文;之后启动的都是已经安装的 pi-web,不会每次自动升级。command -v pi-web 应指向 npm 的全局安装目录,而不是 .npm/_npx/ 临时缓存。npm 提示有安装脚本尚未批准时,不要批量批准。已有 Pi Web 正在占用 30141 时,不再启动第二个实例。选择与原有 Pi 相同的系统用户和文件系统环境,避免打开一套空会话。
示例中的 Pi Web 跑在 WSL,Windows 也需要能访问它。用 Windows 浏览器打开上述地址;或者在 PowerShell 执行只读检查:
(Invoke-WebRequest -UseBasicParsing -Uri 'http://127.0.0.1:30141/' -TimeoutSec 10).StatusCode
预期为 200。示例机器的 WSL2 使用镜像网络,这一步已通过;其他机器以自己的结果为准。不通时先查 WSL 服务与本机访问,不要直接关防火墙或把监听地址改成 0.0.0.0。
macOS/Linux 原生运行时,后面的连接工具放在应用所在的同一台机器即可。
A:手机和电脑建立私有连接
这条路只做三件事:让设备互相看见 → 给本地网页一个 HTTPS 地址 → 手机打开。第一次不用处理开机自启。
A1 · 两台设备出现在同一个列表里
从 Tailscale 官方下载页安装 Windows 和 Android 客户端,用同一账号登录。点击登录后,浏览器可能要等几秒到十几秒才弹出登录页;先等一会儿,不要连续点击。手机先关掉其他 VPN 类应用,再开启 Tailscale。账号开启双重验证;这次不启用 Exit Node(让手机其他上网流量也从某台设备出去的功能)。
打开设备列表,确认手机与电脑都在线。刚连上时手机可能经中继(relay)连到电脑,能用就行,这一步不用处理。仅在自己的新网络里试验,不把电脑分享给其他人。已有团队网络的用户,先核对访问规则是否只允许预期的本人设备访问这台电脑的 HTTPS 端口。
到这里可以停一下。今天只做到设备在线,也是一项完整的小进展。
A2 · 让电脑提供 HTTPS 地址
首次配置按下面三步做。Windows 上运行 Serve,Pi Web 继续留在 WSL。先给 Pi Web 设置密码并核验,再打开远程入口;以后开机按后文的启动脚本恢复。
A2.1 · Windows:取得设备完整域名
在 Tailscale 管理控制台的 DNS 页面开启 MagicDNS(设备名称解析)与 HTTPS Certificates。示例环境里 MagicDNS 默认已开,HTTPS Certificates 要自己打开;在控制台里开,比等命令行临时申请更稳。开启后,设备的完整域名会写进任何人都能查的公开证书记录。别人能查到这个名字,但连不进来;先把带真名、公司名的设备名改掉。
在 Windows PowerShell 查看设备完整域名:
$ts = tailscale status --json | ConvertFrom-Json
$ts.Self.DNSName.TrimEnd('.')
记下输出,不带末尾的点、不带 https://。如果命令找不到,安装后重新打开 PowerShell,或使用安装目录里的 tailscale.exe。
A2.2 · WSL:保存启动脚本,带密码重启并检查
在 Pi Web 所在的 WSL Bash 中,先保存 A2.1 的完整域名。已有这个文件时命令会停下,不覆盖:
(
set -eu
umask 077
file="$HOME/.config/pi-web/allowed-hosts"
test ! -e "$file" || {
printf '文件已存在,未覆盖,请先核对。\n'
exit 1
}
read -r -p '粘贴完整设备域名(不含 https://):' host
[[ "$host" == *.ts.net && "$host" != *[[:space:]/:]* ]] || {
printf '域名格式不对,未保存。\n'
exit 1
}
mkdir -p "$HOME/.config/pi-web"
(set -C; printf '%s\n' "$host" > "$file")
printf '域名配置已保存。\n'
)
再创建启动脚本。它读取这个域名,启动时让你输入密码,密码不写入磁盘;最后调用已安装的 pi-web,脚本里不写版本:
(
set -eu
umask 077
script="$HOME/.local/bin/pi-web-start"
test ! -e "$script" || {
printf '启动脚本已存在,未覆盖。\n'
exit 1
}
mkdir -p "$HOME/.local/bin"
set -C
cat > "$script" <<'EOF'
#!/usr/bin/env bash
set -eu
PI_WEB_ALLOWED_HOSTS=$(cat "$HOME/.config/pi-web/allowed-hosts")
test -n "$PI_WEB_ALLOWED_HOSTS" || {
printf '域名配置为空,未启动。\n'
exit 1
}
export PI_WEB_ALLOWED_HOSTS
read -r -s -p 'Pi Web 密码:' PI_WEB_PASSWORD
printf '\n'
test -n "$PI_WEB_PASSWORD" || {
printf '密码为空,未启动。\n'
exit 1
}
export PI_WEB_PASSWORD
exec pi-web --hostname 127.0.0.1 --port 30141 --no-open
EOF
chmod u+x "$script"
bash -n "$script"
printf '启动脚本已准备好;尚未启动。\n'
)
接着停止旧实例,用脚本重新启动。停止会中断旧实例里正在运行的任务和网页终端,已保存的会话不会删除;先等回复结束。如果你正在 Pi Web 里看本文或和智能体对话,先把下面的命令记下来:
pi-web stop --port 30141 &&
"$HOME/.local/bin/pi-web-start"
前半段失败时不会继续启动;第一次安装后还没运行 Pi Web 的,只执行第二行。出现 Pi Web 密码: 时输入密码管理器里的密码,字符不显示是正常的。保持这个终端窗口打开;关窗口或按 Ctrl+C 都会停止 Pi Web。pi-web stop 找不到实例时,先运行 pi-web status 核对,不要用模糊的批量结束进程命令。
本机浏览器没有出现登录页,不一定说明密码没生效:之前用同一个密码登录过的话,30 天内的登录凭证仍然有效。示例环境里,本机浏览器直接进入了会话,下面两项检查都通过,手机无痕窗口则先出现了登录页。浏览器若弹出自带的“用户名 + 密码”框,点取消,关掉旧标签页再重新打开,在 Pi Web 自己的登录页只输密码。
验证的是正在运行的服务,不是终端里还留着一个变量。新开一个 WSL 终端,执行下面的只读检查;它不带浏览器的登录状态,也不调用模型:
curl -q --noproxy '*' --fail --silent --show-error --max-time 10 \
http://127.0.0.1:30141/api/web-auth
预期返回:
{"enabled":true,"authenticated":false}
enabled: true 才表示当前服务已开启密码;authenticated: false 表示这次检查没有登录,正是预期结果。再确认未登录请求拿不到会话:
curl -q --noproxy '*' --silent --show-error --max-time 10 \
--output /dev/null --write-out 'HTTP %{http_code}\n' \
http://127.0.0.1:30141/api/sessions
预期是 HTTP 401(需要认证),不是 HTTP 200。若 enabled 是 false、会话接口没有拒绝未登录请求,或者检查失败,先不要开启 Serve;在启动窗口按 Ctrl+C 停止这次启动,再核对域名文件和脚本。已经有远程入口的,先按文末停用步骤关闭本教程那一条 Serve,再处理密码。终端的 Ready 和浏览器能打开页面,都不能替代这一步。
A2.3 · Windows:开启并核对 Serve
回到 Windows PowerShell:
tailscale serve status
如果已有其他 Serve 服务,先停在这里,避免占用其端口或覆盖路由。没有冲突再开启:
tailscale serve --bg --https=443 http://127.0.0.1:30141
tailscale serve status
按提示完成 HTTPS 授权。报 error enabling https feature … context deadline exceeded 时,是命令行连 Tailscale 服务器超时,重试多半一样;去控制台 DNS 页面开启 HTTPS Certificates,等一两分钟再运行上面的命令。记录命令打印的完整 https://…ts.net 地址。使用的是 serve,只对自己的设备开放;不是面向公网的 funnel。也不需要单独管理证书文件。
A3 · 手机关掉 Wi-Fi,打开刚才的网址
用蜂窝网络,保持 Tailscale 开启、其他 VPN 应用关闭,在 Chrome 打开 Serve 打印的 HTTPS 地址。关 Wi-Fi 只是为了这次验收:手机和电脑在同一个 Wi-Fi 里时,连上不能证明出门也能用。验收通过后,日常开着 Wi-Fi 照常使用。能看到 Pi Web 登录页、输入密码后看到自己的会话,才算跨网访问成功。浏览器若提示证书错误,先停下排查地址,不点击忽略。
第一次只查看会话。准备好承担模型调用费用后,再发送一句“只回复连接成功,不使用工具”,观察回复是否逐步出现。暂时关闭手机 Tailscale,用新开的无痕窗口重试:应无法连接。这验证的是私有入口,不是页面缓存。
在 Chrome 菜单选择“安装应用”或“添加到主屏幕”。这个 PWA(Progressive Web App,可安装的网页应用,安装说明)只是更方便的入口,电脑仍需开机,手机仍需联网并连接 Tailscale。
部分 Android 手机要先在系统设置里给 Chrome 开启“创建桌面快捷方式”权限,否则添加会失败。提示安装成功却在桌面上找不到时,去应用抽屉或全局搜索里找“Pi Web”。各家系统在这里的表现不一致,快捷方式能打开就够用。
这条路线走通就结束。下面的 B 不用配置。
B:手机 VPN 不能关时,用固定网址访问
手机必须同时开着另一个 VPN 类应用时,可以用 Cloudflare 的固定隧道加一道登录门(Tunnel + Access)。它不占手机的 VPN 名额,但网页内容会在 Cloudflare 解开;如果你要的是“只在自己电脑上解开”,这条不是同等的替代。
这条路线也是三件事:先限制谁能进 → 连接本地服务 → 用手机验收。
B1 · 先为网址加一道只允许本人的门
准备一个由 Cloudflare 托管的域名。下文用 pi.example.com 代表你的子域名;换成自己的,选一个还没有 DNS 记录的子域名,不修改根域名或已有网站的解析。
有多个 CF 账号时,在浏览器中选择包含目标域名的账号,确认 Zone(域名区域)、Tunnel 和 Access 的归属。Windows/WSL 中已有的 cert.pem、Wrangler 登录或环境变量,不证明当前属于正确账号。
在该账号创建或进入 Zero Trust,选择适用套餐,确认结算金额;单人试验先看 Free,不顺手开启付费增值项。管理账号开启双重验证。
在 Access → Applications 新建自托管 Web 应用,覆盖整个 pi.example.com,不要只保护首页。Allow 策略用 Emails 精确填写本人邮箱,未匹配者保持拒绝。不要选 Everyone,也不要把“使用邮箱验证码登录”本身当成授权名单;不要添加 Bypass。官方把“包含所有人”“包含所有有效邮箱”列为常见误配置,这样设等于谁都能进(Access 策略说明)。
登录方式可用本人身份提供商或邮箱验证码;敏感入口进一步开启可用的多因素认证。可以先从 24 小时会话有效期开始,之后按实际需求调整。手机无需安装 WARP。
保存 Access 后再创建公开路由。这个顺序能避免“隧道已经连通,登录保护还没建”的空档。
B2 · 独立隧道连接电脑,不动旧账号凭据
在 Pi Web 所在的 WSL 中,按 Cloudflare 官方下载说明安装 cloudflared。本例把它与 Pi Web 放在同一个环境,不依赖 Windows 到 WSL 的转发。
先给 Pi Web 配置 PI_WEB_ALLOWED_HOSTS=pi.example.com 和非空 PI_WEB_PASSWORD,保留 127.0.0.1:30141 监听。密码可使用 A2 中的静默输入方法;先等任务结束,停止原实例,再以相同用户和确认过的版本重启。不要把网站密码和模型 API Key 混用。
在已确认的 CF 账号中创建控制台管理的 Tunnel,取名如 pi-web。运行它只需要该隧道的专用 Token(运行凭据),不需要执行 cloudflared tunnel login,也不用替换旧 ~/.cloudflared/cert.pem。
先以前台进程验证,不直接复制 service install 覆盖已有服务。以下是 WSL Bash 的独立凭据保存方式;目录已存在就停下核对,不覆盖它:
(
set -eu
umask 077
mkdir -p "$HOME/.config"
mkdir "$HOME/.config/pi-web-tunnel"
read -r -s -p '粘贴这条 Tunnel 的 Token:' TOKEN
printf '\n'
test -n "$TOKEN" || { printf 'Token 为空,已停止。\n'; exit 1; }
printf '%s' "$TOKEN" > "$HOME/.config/pi-web-tunnel/token"
unset TOKEN
)
不要在录屏时粘贴 Token;终端静默输入不能防止录到控制台原文、剪贴板历史或密码管理器。
用独立配置路径避免误读旧的默认配置。下面第一行只在第一次运行时创建空配置,之后重复执行也不会改动它;Token 不出现在命令参数里:
test -e "$HOME/.config/pi-web-tunnel/empty.yml" || printf '{}\n' > "$HOME/.config/pi-web-tunnel/empty.yml"
env -u TUNNEL_TOKEN -u TUNNEL_ORIGIN_CERT \
cloudflared tunnel \
--config "$HOME/.config/pi-web-tunnel/empty.yml" \
run --token-file "$HOME/.config/pi-web-tunnel/token"
--token-file 需要 cloudflared 2025.4.0 或更新版本;其他旧的 TUNNEL_* 配置也应在专用进程环境中核对,不打印含秘密的完整环境变量。按控制台显示确认新隧道在线。
为这条隧道添加 Published application 路由:
| 配置项 | 本文例子 |
|---|---|
| Hostname | pi.example.com |
| Service URL | http://127.0.0.1:30141 |
| Protect with Access | 开启,选择刚才的 Access 应用及其 Audience |
开启 Protect with Access 后,cloudflared 会再核对一次 Access 发的登录凭证。就算 Access 应用哪里配错,或者有别的路由也指向这条隧道,没有有效凭证的请求也到不了 Pi Web(校验 Access 凭证)。
保留公开 Host,不把 HTTP Host Header 强制改成 localhost。Pi Web 会核对请求上的地址是不是它认可的,对不上就拒绝发消息等操作。表里的 http:// 只是电脑内部的最后一段;手机到 Cloudflare、Cloudflare 到电脑都是加密的。
不要使用临时 Quick Tunnel(随机 trycloudflare.com 地址)。官方文档说明它不支持 SSE(Server-Sent Events,Pi Web 流式回复与终端使用的事件流)。也不用增加 Worker、Nginx 或路由器端口映射。
Token 是这条隧道的钥匙,拿到它就能运行这条隧道(Tunnel Token 说明)。单独的目录防止和别的账号混用,0600 让电脑上其他系统用户读不到;但同一用户下运行的智能体仍能读到它。长期运行前,应考虑独立服务身份/凭据隔离,权限和已有服务核对后再配置自启。
B3 · 用一次拒绝和一次成功验收
先开无痕窗口访问 https://pi.example.com/,预期是 Access 登录页;在未登录窗口直接访问 /api/sessions 也不能得到会话数据。非授权身份应被拒绝。只有账号没有密码并不安全,不能因首页出现登录页就省掉 API 验收。
本人通过 Access 后,还需通过 Pi Web 密码。先查看会话,再按 A3 的方式做一次非敏感、小成本回复测试。
在手机上分别测试其他 VPN 应用关闭与开启,再切换 Wi-Fi/蜂窝网络。两种状态用同一网址,但实际走的网络不同;若直连 CF 不畅,应记录具体网络,不把“开着 VPN 应用能用”写成“随时稳定”。
Chrome 安装到桌面后再测试一次登录返回,以及锁屏后重新打开。Access 到期时先重新访问首页完成登录;不要为修登录问题放行 /api/*。首次成功后即可停下,不急着配置通知和自启动。
以后每次开机,怎么重新用起来
第一次配好之后,电脑重启或关机再开,大部分东西会自己回来,只有 Pi Web 要手动启动。下面按路线 A 写。示例环境已用 A2.2 的脚本完成一次手动切换,手机无痕窗口验证过登录;Windows 重启后的完整恢复,还没有在示例环境里按这一节走过一遍。
| 开机后 | 会不会自己回来 |
|---|---|
| Windows 上的 Tailscale | 会,但默认要等你登录 Windows 才连上(无人值守模式说明) |
| Serve 的 HTTPS 地址 | 会。用 --bg 开启的 Serve 在重启后自动恢复(Serve 文档) |
| WSL 和 Pi Web | 不会。Pi Web 每次都要在 WSL 里手动启动 |
| 手机上 Pi Web 的登录 | 只要启动时用同一个密码,30 天内不用重新登录 |
最后一行来自 Pi Web 0.12.0 和 0.12.2 的源码:登录凭证用 Pi Web 密码签名,有效期 30 天。所以每次启动都输入同一个密码;换了密码,所有已登录的设备都要重新登录。
每次开机后
-
登录 Windows。PowerShell 里不用做任何事;想确认的话,运行
tailscale serve status,应该仍然显示那个https://…ts.net地址指向http://127.0.0.1:30141。 -
打开 WSL 终端,运行 A2.2 创建的启动脚本,输入 Pi Web 密码:
pi-web-start提示找不到命令时,用完整路径
~/.local/bin/pi-web-start。在电脑浏览器里打开http://127.0.0.1:30141,并按 A2.2 的两项只读检查确认enabled: true和HTTP 401,才继续用手机访问。这个终端窗口可以最小化,不要关:关掉窗口或按Ctrl+C,Pi Web 就停了。 -
手机上打开 Tailscale,确认已连接,再点桌面上的 Pi Web 图标。
关机前不用做额外的事。Pi Web 正在回复时,等它答完再关机:重启会打断正在进行的回复,会话记录还在。
升级 Pi Web 单独做,不放进每次开机:先运行 pi-web update --check 查看是否有新版本。要升级时等任务结束,依次执行 pi-web stop --port 30141、pi-web update,用 pi-web version 确认版本,再运行 pi-web-start 和 A2.2 的检查。本文没有实测升级过程。
路线 B 多一步:在另一个 WSL 终端里重新运行 B2 中那条 cloudflared tunnel … run --token-file … 命令。它也是前台进程,窗口关了,隧道就断。
人在外面时,电脑如果被系统更新重启,Pi Web 不会自己回来,只能等你回到电脑前。出门久的话,提前在 Windows 更新里设好使用时段,或者暂停更新。在 Tailscale 托盘菜单的 Preferences 里勾选 Run unattended,能让 Tailscale 在没人登录 Windows 时也保持在线,但它只管 Tailscale,Pi Web 仍要手动启动。让 Pi Web 开机全自动启动,就得把密码存在磁盘上,同一用户下运行的智能体也能读到它,本文不展开。
隔一段时间要重新登录的几样东西
| 什么 | 多久 | 到期时 | 怎么办 |
|---|---|---|---|
| Tailscale 设备密钥 | 默认 180 天 | 这台设备掉线 | 在那台设备上重新登录 Tailscale |
| Pi Web 登录 | 30 天,或换了密码 | 回到登录页 | 输入 Pi Web 密码 |
| 模型账号(订阅登录或 API Key) | 看提供商 | Pi Web 回复时报认证错误 | 在电脑上打开 Pi Web 的 Models 面板,重新登录或重填 Key |
| HTTPS 证书 | Let's Encrypt 证书 90 天到期 | 手机提示证书错误 | 见下文 |
| B:Access 登录 | 你设的会话时长 | 跳到 Access 登录页 | 重新登录 |
电脑的密钥到期时,人在外面修不了:电脑已经掉线,手机连不上它。可以在 Tailscale 控制台的 Machines 页,从电脑那一行的菜单里选 Disable Key Expiry,让它不再到期(密钥过期说明)。代价是这台电脑的密钥不再自动作废,Tailscale 账号本身的安全就更要紧。不关的话,到期前回到电脑前重新登录一次。官方提醒,用 tailscale up --force-reauth 续期会短暂断线,不要隔着远程连接执行。
模型凭据和终端里的 Pi 共用,默认存在电脑的 ~/.pi/agent 下(Pi Web 中文说明),在 Pi Web 或终端里重新登录都可以。
证书由 Serve 自动签发,不用自己管理证书文件;官方文档没有写明 Serve 怎样续期,示例环境也还没用满 90 天。手机若提示证书错误,不要点忽略,先在电脑上运行 tailscale serve status,确认地址和服务都还在。
手机丢了、忘了密码、电脑重装:从哪一步重新开始
- 忘了 Pi Web 密码:Pi Web 不保存密码。先运行
pi-web stop --port 30141,再运行pi-web-start输入新密码;所有设备都要用新密码重新登录。 - 手机丢了:先在 Tailscale 控制台的 Machines 页删除这部手机,它就连不进你的网络了;再用新密码重启 Pi Web,旧手机上的登录随即失效,因为它的凭证是用旧密码签的。走路线 B 的,还要在 Cloudflare Zero Trust 里撤销这个用户的登录会话。
- 换了新手机:装 Tailscale、登录同一账号,打开电脑的
ts.net地址登录 Pi Web,再到控制台删掉旧手机。 - 电脑重装系统,或 Tailscale 被登出:重新登录后,电脑在控制台里可能算一台新设备,名字也可能变,
ts.net地址就跟着变。把新地址写进~/.config/pi-web/allowed-hosts,重新执行 A2 里开启 Serve 的那两条命令,再删掉控制台里的旧设备。 ~/.pi/agent丢了:模型要重新登录或重填 Key。会话记录也存在这个目录里(Pi Web 说明),所以它值得备份;备份里有凭据,要像密码一样保管。
连上以后,再解决这些事
组网就不受网络影响了吗?
仍然受影响。Tailscale 会先试着让两台设备直连;网络限制让直连不成时,改走加密中继(连接类型说明)。中继打不开内容,但可能更慢;直连也受手机信号、运营商线路和家里上行带宽影响。
手机保持在线,从电脑执行 tailscale status,或对手机设备名执行 tailscale ping。direct 表示直连,relay/peer-relay 表示经过中继。刚开始先经过中继、随后转直连是正常现象。先看真实路径,不先关防火墙、开路由器端口或购买服务器。
在国内用,经过中继时常常更慢:截至 2026 年 10 月,Tailscale 的默认中继没有设在大陆,最近的在香港、东京和新加坡(中继说明)。tailscale status 里中继后面跟着区域代码,比如 hkg 是香港、tok 是东京。长期走中继又嫌慢,有两个方向,本文都没有实测:
- Tailscale 的 Peer Relay:让你网络里一台网络条件好、常开的设备当中继。它不能是手机,要 Tailscale 1.86 以上,并开放一个其他设备能访问的 UDP 端口。连接仍在同一个账号和访问规则里,本文的安全说法不变。
- 换用能走国内共享节点的组网工具,比如国内开发者做的开源工具 EasyTier。代价不小:安卓不 root 时,它也要通过系统 VPN 接口工作,同样占 VPN 名额;没有现成的 HTTPS 地址,Pi Web 要改监听地址,PWA 安装和推送通知也用不了;知道网络名和密钥的设备都能进这个网络。用别人提供的共享节点时,要开启它的安全模式并锁定节点公钥,否则文档没有保证中继看不到内容。
临时关掉手机上的 VPN 应用,和手机完全没有互联网,是两回事。前者 A 仍可能连上;后者任何远程方案都不能用。CF、向日葵、UU 远程也没有免于网络影响。
电脑休眠、手机锁屏、任务会怎样?
电脑、WSL、Pi Web 都需要继续运行;锁屏与睡眠不同。日常使用前核对插电时的睡眠策略,不必把屏幕一直点亮。重启以后哪些会自己回来、哪些要手动启动,见上面「以后每次开机,怎么重新用起来」。
Pi Web 已被服务端接收的智能体任务不要求手机一直亮屏,返回后有状态恢复机制;这不代表重启 Pi Web 进程后任务也能无损继续。
网页终端另有生命周期:本文核对版本中,最后一个客户端断开约 120 秒后会回收。长时间终端工作可用 tmux(保持终端会话的工具),不要靠手机永不锁屏维持任务。
用哪种方式,费用和隐私更合适?
Tailscale 的 Personal 计划免费,官方写明只适合非商业用途(价格页);Serve 提供设备域名,不需要购买自有域名,工作用途按实际套餐条款确认。CF 个人规模可先用 Free,已有域名时不必买服务器,域名续费和模型调用费仍然存在。免费套餐不是无限资源或可用性承诺。
A 的网页内容在自己的电脑上解开;Tailscale 仍知道账号、设备和连接记录。B 的网页内容先在 CF 解开;应用密码和 Access 管的是谁能进,不会让 CF 看不到经过它的内容。需要公司或客户数据授权时,先走组织审批,不能把“只有我用”当成合规结论。
通知可以晚点开。Pi Web 完成推送可能把会话标题显示在手机锁屏上,避免在标题里写客户名或敏感内容。使用云模型还需单独考虑模型提供商的数据政策;换一种接入方式不会改变模型拿到的输入。
打不开时,按这个顺序查;想停用也很简单
先查电脑本地地址,再查连接工具是否在线,最后查手机网络和浏览器登录,不一次改三层配置。
| 现象 | 先做什么 |
|---|---|
| 电脑本地地址打不开 | 检查原 Pi Web 进程,先不改隧道 |
| Windows 点登录后没反应 | 等十几秒看浏览器是否弹出;仍没有,再点一次 |
| A 在打开其他 VPN 应用后失联 | 关掉那个应用,重新连接 Tailscale |
| 重启 Pi Web 后弹出用户名和密码框 | 点取消,关掉旧标签页,重新打开 Pi Web 地址只输密码 |
Serve 报 error enabling https feature | 在控制台 DNS 页面开启 HTTPS Certificates,稍等再运行 Serve |
电脑上打开 ts.net 地址提示连接被重置 | 电脑开着系统代理时,把 *.ts.net 加入代理绕过列表;手机不受影响 |
| A 设备在线但 HTTPS 拒绝 | 核对完整设备域名、Serve 状态、访问规则与 Pi Web 允许主机名 |
| B 返回 403 | 区分 Access 拒绝还是 Pi Web 的 Untrusted request,检查本人名单与 Host |
| B 返回 502/隧道离线 | 在 cloudflared 所在环境访问本机服务;确认隧道出站网络通畅 |
| 回复一次性出现或长操作超时 | 检查 SSE 是否被缓冲,单独测试手动压缩等长 POST,不反复重发有副作用的操作 |
| 登录后突然变成 HTML 错误 | 回首页重新完成 Access 登录,不取消 API 保护 |
停用 A 时,先看 tailscale serve status,确认 443 确实是本教程的服务,再关闭这一条:
tailscale serve --https=443 off
不要用全局 reset 误删其他路由。停用 B 时,在自己的前台 cloudflared 窗口按 Ctrl+C,然后移除该子域名的隧道路由;保留 Access 到公开路由移除后,避免先撤门禁。Token 泄露需轮换并断开旧连接,不只是删除本地文件。
第一轮的完成标准很小:手机换到蜂窝网络后能登录、读到会话,且不该进入的人进不来。做到这里,再决定是否需要自启、通知和备用远程桌面。
写作说明:gpt-6-astra 起草、修订并绘制示意图;Claude Opus 5.5 补写开机恢复。
评论
评论由 GitHub Discussions 提供。登录 GitHub 后即可评论。 前往对应 Discussion