Skip to content

Commit 19fddfc

Browse files
xkcodingclaude
andcommitted
feat: 新增博客文章「用 Tailscale + Terminus 在 iPad 上远程操控 Claude Code」
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent b363ac5 commit 19fddfc

1 file changed

Lines changed: 216 additions & 0 deletions

File tree

Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
---
2+
title: "用 Tailscale + Terminus 在 iPad 上远程操控 Claude Code"
3+
author: xkcoding
4+
pubDatetime: 2026-02-17T00:00:00.000Z
5+
slug: remote-claude-code-with-tailscale-terminus
6+
featured: true
7+
draft: false
8+
ogImage: https://cdn.xkcoding.com/blog/2026-02-16-remote-claude-code-tailscale-cover-16x9.webp?x-oss-process=style/tag_compress
9+
tags:
10+
- ai
11+
- claude-code
12+
- tailscale
13+
description: "Claude Code 驱动的工作流用得越深,越离不开那台 Mac。上下文、笔记、项目全在上面,出门就接不上。本文对比了 frp、Cloudflare Tunnel、Happy Coder、Tailscale 几种远程方案,最后用 Tailscale 组网加 Terminus 做移动端 SSH,iPad 和手机随时能连回 Mac 用 Claude Code。也记录了搭建 Tailscale 过程中踩的坑:GUI 版锁屏断连、国内 DNS 污染、SSH 读不到 macOS 钥匙串,以及自己的排查思路。"
14+
---
15+
16+
## 写在前面
17+
18+
我的第二大脑是 Obsidian + Claude Code 搭的 [Claudesidian](https://github.com/heyitsnoah/claudesidian) 方案。它在 Obsidian 里预设了一套 PARA 结构的知识库,然后通过 Slash Command 和 MCP 让 Claude Code 来驱动整个工作流:日常写笔记、整理收藏、做 daily review,甚至研究一个新话题,都是在跟 Claude Code 对话中完成的。它不只是个工具,更像一个长期协作伙伴。
19+
20+
问题是,我不可能随时坐在电脑前。春节假期躺沙发上突然冒出个想法,陪娃逛街时脑子里闪过一个 bug 的解法。偏偏这种碎片化的瞬间,最想随手跟 AI 聊两句。
21+
22+
折腾了一番,我使用 Tailscale 组网 + Terminus 做移动终端,现在在 iPad 上打开 Terminus 就能直接跟 Mac 上的 Claude Code 对话。
23+
24+
![工作流从 Mac 延伸到移动端](https://cdn.xkcoding.com/blog/2026-02-16-illustration-overview-architecture.webp?x-oss-process=style/tag_compress)
25+
26+
## 为什么选 Tailscale
27+
28+
想要从外面连回家里的 Mac,核心问题是组网。常见方案有几种:
29+
30+
- **frp / ngrok**:需要一台有公网 IP 的服务器做中转,不是每个人都有
31+
- **Cloudflare Tunnel**:免费,不需要公网 IP,但需要一个托管在 Cloudflare 的域名。SSH 场景下客户端也得装 `cloudflared` 做代理,配置链路比较长(建 Tunnel、配公共主机名、改本地 SSH config、加 Access 策略),更适合暴露 Web 服务
32+
- **[Happy Coder](https://happy.engineering/)**:专门为 Claude Code 设计的移动端方案,扫码配对就能用。它通过中继服务器转发加密消息,你的代码和对话会经过第三方服务。如果你只需要在手机上操控 Claude Code,这是最轻量的选择
33+
- **Tailscale**:注册一个账号(支持 GitHub 登录),各设备装上客户端,自动组成虚拟局域网,设备之间点对点直连,不经过第三方
34+
35+
我选 Tailscale,原因很简单:零配置门槛,装上就能用。我平时有在家折腾 homelab,用闲置硬件搭了一套自己的开发和存储环境,这些设备本来就跑在 Tailscale 网络里,iPad 和手机加进来只是顺手的事。
36+
37+
没了解过 Tailscale 的同学,这里简单说一下它的原理:它基于 WireGuard 协议,在你的设备之间建立点对点的加密隧道。大部分情况下设备之间直连,不经过中转服务器,延迟很低。每台设备会分配一个固定的 `100.x.x.x` 内网 IP,你用这个 IP 就能像在同一个局域网一样互相访问。
38+
39+
![四种远程方案对比](https://cdn.xkcoding.com/blog/2026-02-16-illustration-solution-comparison.webp?x-oss-process=style/tag_compress)
40+
41+
## 前置准备
42+
43+
### Mac 保持在线
44+
45+
整个方案的前提是 Mac 不能休眠断网。接上电源,然后打开「系统设置」→「显示器」→「高级」,开启"当显示器关闭时,防止自动休眠";再到「电池」→「选项」,把"唤醒以供网络访问"设为"始终"。
46+
47+
### Mac 开启远程登录
48+
49+
「系统设置」→「通用」→「共享」→ 打开"远程登录"。这一步开启的就是 SSH 服务。
50+
51+
### 移动端安装 Terminus
52+
53+
[Terminus](https://termius.com/) 是一个跨平台的 SSH 客户端,支持 iOS、iPadOS 和 Android,免费版功能足够用了。
54+
55+
> [!TIP]
56+
> iPad 强烈建议配一个键盘外设,体验会好很多。
57+
58+
## Mac 端 Tailscale 配置
59+
60+
### 安装 Tailscale
61+
62+
Tailscale 在 Mac 上有两种安装方式:App Store 的图形界面版本,和 Homebrew 的命令行守护进程版本。
63+
64+
我一开始装的是 GUI 版,用着没问题,但合上盖子或者锁屏关闭显示器之后,iPad 就连不上了。换成 Homebrew 版就没这个问题,它作为系统守护进程运行,锁屏也不会断。
65+
66+
```bash
67+
brew install tailscale
68+
sudo brew services start tailscale
69+
sudo tailscale up
70+
```
71+
72+
运行 `tailscale up` 后终端会打印一个认证链接,复制到浏览器打开完成登录就行。
73+
74+
如果一切顺利,到这里就结束了。但我遇到了两个坑。
75+
76+
### 踩坑 1:GUI 版残留导致命令失效
77+
78+
如果你之前装过 GUI 版,`/usr/local/bin/tailscale` 可能还指向旧的应用路径,执行时会报 `No such file or directory`
79+
80+
```bash
81+
# 删掉失效的旧链接
82+
sudo rm /usr/local/bin/tailscale
83+
84+
# 让 Homebrew 接管
85+
brew link --overwrite tailscale
86+
```
87+
88+
确认一下新路径:
89+
90+
```bash
91+
which tailscale
92+
# Apple Silicon: /opt/homebrew/bin/tailscale
93+
# Intel Mac: /usr/local/bin/tailscale
94+
```
95+
96+
如果看到 `/opt/homebrew/bin/tailscale``/usr/local/bin/tailscale`,说明链接修复成功。
97+
98+
### 踩坑 2:DNS 污染导致连不上服务器
99+
100+
> [!NOTE]
101+
> 这个问题卡了我最久。国内使用代理工具的用户大概率会遇到,网络环境没问题的可以跳过这段。
102+
103+
`tailscale up` 之后一直卡着没反应,手动启动守护进程看日志,发现:
104+
105+
```
106+
logtail: dial "log.tailscale.com:443" failed: dial tcp 11.0.0.1:443: i/o timeout
107+
```
108+
109+
`log.tailscale.com` 被解析到了 `11.0.0.1`,这是典型的 DNS 污染。解法是让 Tailscale 走代理启动。
110+
111+
先手动验证代理能不能通:
112+
113+
```bash
114+
# 杀掉残留进程
115+
sudo pkill tailscaled
116+
117+
# 带代理启动守护进程(替换成你自己的代理端口)
118+
sudo env http_proxy=http://127.0.0.1:10080 \
119+
https_proxy=http://127.0.0.1:10080 \
120+
all_proxy=socks5://127.0.0.1:10081 \
121+
/opt/homebrew/bin/tailscaled
122+
```
123+
124+
如果日志正常滚动没报错,开一个新终端窗口执行 `tailscale up` 完成登录。
125+
126+
验证通过后,把代理配置写进 Homebrew 的服务配置文件里,这样重启也能自动生效:
127+
128+
```bash
129+
sudo nano /opt/homebrew/Cellar/tailscale/$(tailscale version | head -1)/homebrew.mxcl.tailscale.plist
130+
```
131+
132+
`<dict>` 内添加:
133+
134+
```xml
135+
<key>EnvironmentVariables</key>
136+
<dict>
137+
<key>http_proxy</key>
138+
<string>http://127.0.0.1:10080</string>
139+
<key>https_proxy</key>
140+
<string>http://127.0.0.1:10080</string>
141+
<key>all_proxy</key>
142+
<string>socks5://127.0.0.1:10081</string>
143+
</dict>
144+
```
145+
146+
保存后重启服务:
147+
148+
```bash
149+
sudo brew services restart tailscale
150+
```
151+
152+
运行 `tailscale status`,如果能看到你的设备列表,说明配置生效了。
153+
154+
### 补充:macOS Screen Time 可能拦截网络
155+
156+
> [!NOTE]
157+
> 这个坑我没遇到,但排查过程中发现有人踩过。macOS 的「屏幕使用时间」里「内容与隐私」默认是关闭的,大部分人不会遇到。但如果你开启过网页内容限制(或者家里小孩用过你的电脑),它会在系统底层拦截网络流量,导致 Tailscale 怎么配都连不上。
158+
>
159+
> 如果你排查了代理和 DNS 都没问题,检查一下「系统设置」→「屏幕使用时间」→「内容与隐私」,把「访问网页内容」设为"无限制",或者直接关掉「内容与隐私」的总开关。改完之后 `sudo brew services restart tailscale`,再用 `tailscale status` 确认一下。
160+
161+
## 移动端连接 Claude Code
162+
163+
Tailscale 配好之后,iPad 和手机上装好 Tailscale 客户端并登录同一个账号,就能拿到 Mac 的 Tailscale IP(`100.x.x.x`)。
164+
165+
在 Terminus 里新建一个 Host,地址填 Mac 的 Tailscale IP,用户名填 Mac 的登录用户名,连接方式选 SSH。连上之后就是一个标准的终端环境,直接敲 `claude` 就能启动 Claude Code。
166+
167+
但第一次连大概率会遇到这个提示:
168+
169+
```
170+
run in another terminal: security unlock-keychain
171+
```
172+
173+
这是因为 Claude Code 把登录凭证存在 macOS 的钥匙串(Keychain)里。你坐在 Mac 前面用的时候,系统会自动解锁钥匙串;但通过 SSH 远程连接时,macOS 出于安全考虑不会自动解锁,Claude Code 读不到凭证就会报错。
174+
175+
手动解锁:
176+
177+
```bash
178+
security unlock-keychain ~/Library/Keychains/login.keychain-db
179+
```
180+
181+
输入 Mac 的登录密码就行。
182+
183+
每次 SSH 连接都手动敲这行命令有点烦,在 `.zshrc` 里加一段自动判断:
184+
185+
```bash
186+
if [ -n "$SSH_CONNECTION" ]; then
187+
echo "🔓 unlocking Keychain for Claude Code..."
188+
security unlock-keychain ~/Library/Keychains/login.keychain-db
189+
fi
190+
```
191+
192+
这样每次通过 SSH 登录时会自动触发解锁,只需要输一次密码。看似每次都要输密码,但实际用下来完全可以接受。
193+
194+
到这里,整个链路就通了。Mac 锁屏挂着,iPad 或手机随时打开 Terminus 就能接入 Claude Code。
195+
196+
## 日常使用效果
197+
198+
用手机备忘录也能记想法,但事后还得手动整理到 Obsidian 里,自己补上下文、打标签、关联已有笔记。Obsidian 虽然有移动端,但我的工作流是 Claude Code 驱动的,笔记的创建、归档、关联都是 Claude 在做,直接用 Obsidian App 反而对不上。
199+
200+
用 Terminus 连上 Claude Code 之后,移动端也能用完整的工作流。记录灵感、改点代码,都能直接上手。
201+
202+
**捕捉灵感**:假期窝在沙发上突然想到一个点子,拿起 iPad 跟 Claude 说两句,它知道我的笔记结构,会自动归档到对应目录、补上 frontmatter。陪娃在外面逛也一样,掏出手机打开 Terminus 快速记一笔。手机上打长命令确实不太舒服,但记个灵感够用了。
203+
204+
**出门也能改代码**:刚发完一篇博客发现导出格式有个小问题,手边没电脑,iPad 上跟 Claude Code 描述一下,它自己找到导出脚本改好。不用看代码,不用等回家。
205+
206+
**灵感趁热落地**:跟朋友聊天聊到一个好用的工作流,当场让 Claude 起一个新 Skill 的骨架,回家再细调。想法热乎的时候直接落地,比事后回忆靠谱得多。
207+
208+
![随时随地接入 Claude Code](https://cdn.xkcoding.com/blog/2026-02-16-illustration-daily-usage.webp?x-oss-process=style/tag_compress)
209+
210+
## 最后
211+
212+
这套方案用起来比预想的简单,搭完之后基本没折腾过。Tailscale 组网的能力也不止于此,有需要的时候可以把更多设备加进来。
213+
214+
搭建过程踩的坑,基本都是把报错丢给 AI 一轮轮排查解决的。给足上下文,试错成本很低。
215+
216+
希望这篇文章对你有帮助,有更好的方案欢迎留言讨论。

0 commit comments

Comments
 (0)