Tailscale+SSH 指南 v3.2:新增双端开发工作流(第九部分)
记录 2026-04-23 新落地的「Mac 本地写代码 + 虚拟机编译」方案: - 9.1 背景:虚拟机内装 Claude CLI 因 Anthropic 对机场 IP 的 API 级风控不可行 - 9.2 Mac 端环境:case-sensitive APFS 卷(避免 Linux 内核大小写冲突)+ HTTPS+PAT+Keychain - 9.3 虚拟机端延续 SSH ed25519 over 443 - 9.4 Claude 自动化闭环:Mac 改 → push → SSH 虚拟机编译 → 看错误自修 → 循环 - 9.5 分支策略:main / dev/mac / feature/* - 9.6 项目级 CLAUDE.md 机制(新对话零摩擦接手) - 9.7 全部踩坑:ClashX SSH 劫持、7890 代理端口不实际转发、APFS 大小写、mihomo 绕不过 Anthropic 风控等 - 9.8 实测性能数据
This commit is contained in:
parent
d6a1e28975
commit
6517805884
@ -1842,10 +1842,250 @@ git push -u origin main
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
文档版本: 3.1
|
# 第九部分:Mac 本地 + 虚拟机编译 的双端开发工作流(2026-04-23 落地,推荐)
|
||||||
最后更新: 2026-04-22
|
|
||||||
|
## 9.1 为什么采用这种方案
|
||||||
|
|
||||||
|
### 背景:虚拟机内用 Claude CLI 不可行
|
||||||
|
|
||||||
|
实测发现(2026-04-23):
|
||||||
|
- **Anthropic 对中国机场 IP 做了 API 级风控**,`api.anthropic.com` 对机场 IP 返回 ECONNRESET 或静默丢包(但 HTTPS 握手能成功、`console.anthropic.com` 也能通,仅 `/v1/messages` 被精准拉黑)
|
||||||
|
- 尝试过多种节点(美国 IEPL / 香港 / 新加坡),机场共享 IP 段都被 Ban
|
||||||
|
- 虚拟机内装 Claude CLI(Node 20 + `@anthropic-ai/claude-code` 2.1.118)后,启动永远卡在 "Checking connectivity..." 或 ECONNRESET
|
||||||
|
- 新版 Claude CLI(2.1.118+)打包成独立二进制,屏蔽 `NODE_OPTIONS` 等代理注入手段
|
||||||
|
|
||||||
|
### 解决方向
|
||||||
|
|
||||||
|
**Mac 能连 Anthropic(你已在用),Linux 虚拟机保留编译能力。让两边各司其职**:
|
||||||
|
|
||||||
|
```
|
||||||
|
Mac GitHub Linux 虚拟机
|
||||||
|
Claude Code + 代码仓库 ──push──▶ dev/mac ◀──pull── 完整 SDK + 编译工具链
|
||||||
|
(读写/改/grep/Edit) 分支 (./make.sh 编译)
|
||||||
|
▲ │
|
||||||
|
└─────────── Claude 通过 SSH 直接操作虚拟机编译 ────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
Claude 可以**通过 Bash 工具 SSH 到虚拟机自动编译**,实现全自动闭环,**不需要用户在两端手动搬运错误信息**。
|
||||||
|
|
||||||
|
## 9.2 Mac 端一次性环境配置
|
||||||
|
|
||||||
|
### 9.2.1 创建 case-sensitive APFS 卷(关键,否则会踩大坑)
|
||||||
|
|
||||||
|
Linux 内核源码含**同名但大小写不同的文件**(如 `xt_CONNMARK.h` / `xt_connmark.h`),macOS 默认 APFS 是 case-insensitive,会把这些文件合并成一个,导致 `git status` 永远脏且无法还原。
|
||||||
|
|
||||||
|
**解决**:建一个专门的 case-sensitive 卷放 Linux 项目。
|
||||||
|
|
||||||
|
1. 打开 **磁盘工具**
|
||||||
|
2. 左侧选 **Container disk3**(Macintosh HD 的父容器)
|
||||||
|
3. 菜单「编辑 → 添加 APFS 卷...」
|
||||||
|
4. 弹窗中:
|
||||||
|
- 名称:`LinuxDev`
|
||||||
|
- **格式:APFS(区分大小写)** ← 关键
|
||||||
|
- 大小:不限制(APFS 容器自动共享空间)
|
||||||
|
5. 确认 / 添加
|
||||||
|
|
||||||
|
验证成功:
|
||||||
|
```bash
|
||||||
|
diskutil info /Volumes/LinuxDev | grep Personality
|
||||||
|
# 应输出: File System Personality: Case-sensitive APFS
|
||||||
|
|
||||||
|
# 实验创建大小写同名文件
|
||||||
|
touch /Volumes/LinuxDev/_test_a /Volumes/LinuxDev/_test_A
|
||||||
|
ls /Volumes/LinuxDev/_test_*
|
||||||
|
# 应输出两行(_test_A 和 _test_a)
|
||||||
|
rm /Volumes/LinuxDev/_test_*
|
||||||
|
```
|
||||||
|
|
||||||
|
从此 Linux 项目都放 `/Volumes/LinuxDev/` 下。
|
||||||
|
|
||||||
|
### 9.2.2 Mac 端 Git 配置
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 只需要配一次,以后所有项目都复用
|
||||||
|
git config --global user.name "你的名字"
|
||||||
|
git config --global user.email "你的邮箱"
|
||||||
|
git config --global credential.helper osxkeychain # PAT 存钥匙串
|
||||||
|
```
|
||||||
|
|
||||||
|
### 9.2.3 首次克隆到 case-sensitive 卷
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /Volumes/LinuxDev
|
||||||
|
git clone https://github.com/Leo-z8/OrangePi_CM5_Project.git
|
||||||
|
cd OrangePi_CM5_Project
|
||||||
|
# 首次弹出凭证提示:
|
||||||
|
# Username: Leo-z8
|
||||||
|
# Password: 粘贴 PAT (ghp_xxx...)
|
||||||
|
# 之后 PAT 存钥匙串永久免密
|
||||||
|
```
|
||||||
|
|
||||||
|
> **重要:不要用 GitHub Web 下载 ZIP**(文件夹带 `-main` 后缀那种)
|
||||||
|
> ZIP 不含 `.git/` 元数据,无法 push。必须 `git clone`。
|
||||||
|
|
||||||
|
### 9.2.4 创建开发分支
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /Volumes/LinuxDev/OrangePi_CM5_Project
|
||||||
|
git checkout -b dev/mac
|
||||||
|
git push -u origin dev/mac
|
||||||
|
```
|
||||||
|
|
||||||
|
## 9.3 虚拟机端一次性环境配置
|
||||||
|
|
||||||
|
如果之前已按本文档 8.7 配好 SSH ed25519 over 443,这步跳过。否则见 8.7。
|
||||||
|
|
||||||
|
确认:
|
||||||
|
```bash
|
||||||
|
ssh linux-vm "cd ~/OrangePi_CM5/Aandroid_OrangePi/merged/Android_13 && git remote -v"
|
||||||
|
# 应该显示 origin git@github.com:Leo-z8/OrangePi_CM5_Project.git
|
||||||
|
```
|
||||||
|
|
||||||
|
## 9.4 日常开发闭环(Claude 自主执行)
|
||||||
|
|
||||||
|
Claude 收到开发任务后会自动执行:
|
||||||
|
|
||||||
|
```
|
||||||
|
┌──────────────────────────────────────────────────────────┐
|
||||||
|
│ Claude 在 Mac 端工作 │
|
||||||
|
│ 1. cd /Volumes/LinuxDev/OrangePi_CM5_Project │
|
||||||
|
│ 2. 读源码 / grep / 分析 │
|
||||||
|
│ 3. Edit 修改代码 │
|
||||||
|
│ 4. git add xxx │
|
||||||
|
│ 5. git commit -m "描述" │
|
||||||
|
│ 6. git push origin dev/mac │
|
||||||
|
└──────────────────┬───────────────────────────────────────┘
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌──────────────────────────────────────────────────────────┐
|
||||||
|
│ Claude 通过 Bash 工具 SSH 到虚拟机 │
|
||||||
|
│ ssh linux-vm 'cd ~/OrangePi_CM5/.../Android_13 && \ │
|
||||||
|
│ git fetch origin && \ │
|
||||||
|
│ git checkout dev/mac && git pull && \ │
|
||||||
|
│ ./make.sh -F -b orangepicm5' │
|
||||||
|
│ │
|
||||||
|
│ 编译输出直接进 Claude 的上下文 │
|
||||||
|
└──────────────────┬───────────────────────────────────────┘
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌─────────────────────┐
|
||||||
|
│ 编译成功? │
|
||||||
|
└──────┬──────────────┘
|
||||||
|
│ 失败 │ 成功
|
||||||
|
▼ ▼
|
||||||
|
Claude 读错误 通知用户烧录
|
||||||
|
分析 → 修代码 (物理操作)
|
||||||
|
再 push 再编
|
||||||
|
(自循环)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 用户只在三个场景介入
|
||||||
|
1. 提需求("给 NFC 加 PN532 驱动")
|
||||||
|
2. 烧录到开发板(USB 接线、按 Loader 键)
|
||||||
|
3. 判断结果("这效果对不对")
|
||||||
|
|
||||||
|
## 9.5 分支策略
|
||||||
|
|
||||||
|
```
|
||||||
|
main ← 保护分支,只接受编译+烧录测试通过的代码
|
||||||
|
├─ dev/mac ← Mac 端 Claude 日常开发推这里
|
||||||
|
├─ feature/lcd-st77916-mipi ← 可选:大功能单独拉 feature 分支
|
||||||
|
└─ feature/nfc-pn532
|
||||||
|
```
|
||||||
|
|
||||||
|
**合并原则**:
|
||||||
|
- dev/mac 的改动在虚拟机编译通过 + 烧录验证 OK 后,才合并回 main
|
||||||
|
- 合并命令(在虚拟机端或 Mac 端都行):
|
||||||
|
```bash
|
||||||
|
git checkout main
|
||||||
|
git merge dev/mac --no-ff -m "集成 NFC PN532 驱动"
|
||||||
|
git push origin main
|
||||||
|
```
|
||||||
|
|
||||||
|
## 9.6 项目级 CLAUDE.md(关键)
|
||||||
|
|
||||||
|
在仓库根目录放一个 `CLAUDE.md`,**新的 Claude 对话打开项目时自动加载**,无需用户再解释工作流。
|
||||||
|
|
||||||
|
CLAUDE.md 内容要点(完整版见仓库):
|
||||||
|
- 项目本质(硬件、内核版本、开发类型)
|
||||||
|
- 双端架构(Mac 路径 + VM 路径)
|
||||||
|
- 关键命令(git push、SSH、编译)
|
||||||
|
- 全自动闭环流程
|
||||||
|
- 只可修改的目录清单
|
||||||
|
- 环境约束(case-sensitive 卷、不能 >100MB 文件等)
|
||||||
|
- 踩坑速查
|
||||||
|
- 用户偏好(中文、代码风格、响应风格)
|
||||||
|
|
||||||
|
## 9.7 本方案踩过的大坑总结
|
||||||
|
|
||||||
|
### 坑 1:ClashX 增强模式对 SSH 协议干扰
|
||||||
|
|
||||||
|
Mac 上 ClashX Pro 的 TUN 模式把 `ssh.github.com:443` 劫持到 fake-ip(`198.18.x.x`),但 **SSH 协议在 banner exchange 阶段被切**(`Connection timed out during banner exchange`),而 HTTPS 到同一域名却能通。
|
||||||
|
|
||||||
|
原因推测:某些节点对非 HTTP/HTTPS 流量做 DPI 过滤。
|
||||||
|
|
||||||
|
**规避**:Mac 端 Git 操作**只用 HTTPS + PAT**,不用 SSH。
|
||||||
|
虚拟机端没这问题(Tailscale 直连,没经过 Mac ClashX)。
|
||||||
|
|
||||||
|
### 坑 2:ClashX 的 7890 端口虽然开着但实际不转发
|
||||||
|
|
||||||
|
Mac ClashX Pro 当前配置下:
|
||||||
|
- ✅ TUN 透明代理工作(fake-ip 路径)
|
||||||
|
- ❌ 7890 HTTP 代理端口虽然能 `nc -z` 成功但不实际转发(curl -x 超时)
|
||||||
|
- ❌ 7891 SOCKS5 没开
|
||||||
|
|
||||||
|
意味着所有"显式指定代理"的方案(`git config http.proxy`、SSH ProxyCommand、proxychains)都不能用。
|
||||||
|
|
||||||
|
**规避**:依赖 TUN 透明路径,不用显式代理。
|
||||||
|
|
||||||
|
### 坑 3:default APFS 与 Linux 内核大小写冲突
|
||||||
|
|
||||||
|
macOS 主盘默认 APFS 是 case-insensitive,Linux 内核源码(netfilter 等)有大小写同名文件,checkout 时后者覆盖前者,`git status` 永远显示 8 个 .h 文件 modified 且不可还原。
|
||||||
|
|
||||||
|
**规避**:case-sensitive APFS 卷。见 9.2.1。
|
||||||
|
|
||||||
|
### 坑 4:GitHub ZIP 下载不含 .git
|
||||||
|
|
||||||
|
用户若因网络问题改用 GitHub Web 下载 ZIP(带 `-main` 后缀),后续无法 git push。必须 `git clone` 才有 `.git/`。
|
||||||
|
|
||||||
|
### 坑 5:SMB 挂载 Mac Finder 污染 `._*` 和 `.DS_Store`
|
||||||
|
|
||||||
|
Mac Finder 访问 SMB 共享时会写入 AppleDouble 元数据。
|
||||||
|
**规避**:`.gitignore` 已加规则 `._*` + `.DS_Store`。
|
||||||
|
|
||||||
|
### 坑 6:虚拟机 mihomo TUN 无法访问 Anthropic
|
||||||
|
|
||||||
|
即使在虚拟机内装 mihomo 跑 TUN 模式(透明代理),Anthropic 对机场 IP 的 API 级风控仍生效(TLS 握手成功但 POST 请求静默被丢)。
|
||||||
|
|
||||||
|
**规避**:根本不在虚拟机用 Claude。用本节方案。
|
||||||
|
|
||||||
|
## 9.8 性能参考(2026-04-23 实测)
|
||||||
|
|
||||||
|
| 指标 | 数值 |
|
||||||
|
|------|------|
|
||||||
|
| 仓库 clone 大小 | ~640 MB(.git) + ~2.3 GB(work tree)= 2.9 GB |
|
||||||
|
| Mac 端 clone 速度 | 17.5 MiB/s(走 ClashX TUN,GitHub HTTPS)|
|
||||||
|
| Mac → GitHub push 延迟 | 秒级(小改动)|
|
||||||
|
| 虚拟机 git pull 速度 | MB/s 级(Tailscale + SSH ed25519 over 443 直连)|
|
||||||
|
| VS Code 打开 case-sensitive 卷项目 | 索引 < 30 秒(本地速度)|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
文档版本: 3.2
|
||||||
|
最后更新: 2026-04-23
|
||||||
适用系统: Ubuntu 20.04/22.04 LTS (x86_64), macOS
|
适用系统: Ubuntu 20.04/22.04 LTS (x86_64), macOS
|
||||||
网络环境: 跨网络远程开发(Tailscale + ClashX Pro 共存 + GitHub SSH 443)
|
网络环境: 跨网络远程开发(Tailscale + ClashX Pro 共存 + GitHub SSH 443)
|
||||||
|
主要变更(v3.2):
|
||||||
|
- **新增第九部分:Mac 本地 + 虚拟机编译 的双端开发工作流**(推荐,规避 Anthropic 对机场 IP 的风控)
|
||||||
|
- 9.1 分析为什么不能在虚拟机内用 Claude
|
||||||
|
- 9.2 Mac 端环境配置:**case-sensitive APFS 卷**(避免 Linux 内核大小写冲突)+ HTTPS+PAT+Keychain 免密
|
||||||
|
- 9.3 虚拟机端 git SSH 配置(延续 v3.1 的 8.7)
|
||||||
|
- 9.4 Claude 自动化开发闭环流程(Mac 改 → push → SSH 虚拟机编译 → 看错误自修 → 循环)
|
||||||
|
- 9.5 分支策略(main / dev/mac / feature/*)
|
||||||
|
- 9.6 项目级 CLAUDE.md 机制(新对话零摩擦接手)
|
||||||
|
- 9.7 本方案全部踩坑:ClashX SSH 劫持、7890 代理端口不转发、APFS 大小写、mihomo 绕不过 Anthropic 风控等
|
||||||
|
- 9.8 实测性能数据
|
||||||
|
|
||||||
主要变更(v3.1):
|
主要变更(v3.1):
|
||||||
- 4.5 新增 SMB 挂载方式(Mac 端轻量文件访问方案)与 Remote-SSH 对比
|
- 4.5 新增 SMB 挂载方式(Mac 端轻量文件访问方案)与 Remote-SSH 对比
|
||||||
- 8.7 首次推送 GitHub 改为 SSH 密钥为主,PAT 降为备选
|
- 8.7 首次推送 GitHub 改为 SSH 密钥为主,PAT 降为备选
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user