场景:在国内云服务器(阿里云/腾讯云等)上,通过自己的机场订阅,让服务器能科学上网并运行 Claude Code,SSH 连上就能直接用
claude命令。本教程在以下环境验证通过:
- 服务器:阿里云北京 ECS · Ubuntu 24.04 · root 用户
- 客户端:Windows 11 + Xshell 7 + Python 3.9(可选,用于自动化)
- 机场:任意 Clash 格式订阅(如 hk-beup 等)
- Claude 计划:Pro 月付订阅(API key 也支持)
📑 目录
- 整体架构与原理
- 前置条件
- Step 1:SSH 连接服务器并体检
- Step 2:处理机场订阅(关键坑点)
- Step 3:安装 mihomo 内核
- Step 4:生成简化配置(默认走日本节点)
- Step 5:下载 GeoIP 数据并启动 mihomo
- Step 6:配置 systemd 开机自启
- Step 7:写入全局代理环境变量
- Step 8:安装 Node.js 与 Claude Code
- Step 9:登录 Claude(订阅 vs API key)
- Step 10:配置默认模型
- Step 11:创建一键状态检查命令
- 端口与防火墙详解
- 常见故障排查
- 完整目录结构与文件清单
1. 整体架构与原理
1.1 流量链路图
[本地 Windows]
│
│ SSH 22 端口
▼
┌─────────────────────────────────────────────┐
│ 云服务器 XXX.XXX.XXX.XXX(北京阿里云) │
│ │
│ ① Claude Code 进程 │
│ │ │
│ │ HTTP 请求 → 127.0.0.1:7890 │
│ │ (本机回环,不走物理网卡) │
│ ▼ │
│ ② mihomo 进程(Clash 内核命令行版) │
│ 监听 127.0.0.1:7890 │
│ │ │
│ │ VLESS 加密协议封装 │
│ ▼ │
│ ③ 出物理网卡,目标: │
│ {机场域名}:{节点端口} │
└─────────────────────────────────────────────┘
│
│ TCP(出阿里云,目的端口随节点而异)
▼
[机场境外节点(Tokyo / HK / US ...)]
│
│ TCP 443 (HTTPS)
▼
[api.anthropic.com](Anthropic 服务器)
1.2 为什么需要这套架构
| 问题 | 原因 |
|---|---|
| 国内云服务器直连 Claude 报 403 | Anthropic 对中国大陆 IP 限制访问 |
| 直接用 clash-for-linux 经常失败 | 维护停滞、依赖混乱、配置复杂 |
| 本地装 Clash 不能让服务器用 | 服务器需要自己有出口能力 |
解决思路:在服务器上跑一个无图形界面的 Clash 内核(mihomo),服务器自己变成”翻墙客户端”,再让 Claude Code 通过本地 7890 端口走代理出去。
2. 前置条件
| 必需 | 说明 |
|---|---|
| ✅ 一台云服务器 | 任意国内云厂商,root 权限或 sudo,Ubuntu 20.04+ 推荐 |
| ✅ 机场订阅链接 | Clash 格式(URL 末尾有 flag=clash 或自动转换) |
| ✅ Anthropic 账号 | Pro/Max 订阅 或 API key(有余额) |
| ✅ SSH 客户端 | Xshell / WindTerm / 系统自带 ssh 都可以 |
如果没有机场订阅:先去买一个(月费 5-30 元)或自建(需要境外 VPS)。本教程不涵盖建机场。
Step 1:SSH 连接服务器并体检
1.1 连接
ssh root@你的服务器IP
1.2 体检:看服务器位置和现状
# 服务器位置
curl -s https://ipinfo.io
# 看 country 字段。如果是 CN 说明在国内,需要本教程;如果是境外(HK/JP/US)反而不需要折腾代理
# 测试能否直连 Claude
curl -s -o /dev/null -w "%{http_code}n" --max-time 10 https://api.anthropic.com
# 国内大陆服务器返回 403(地区封禁),境外服务器返回 405(正常)
# 架构(决定要下载哪个 mihomo 版本)
uname -m
# 输出 x86_64 或 aarch64
1.3 期望结果
- 国内服务器:
country: CN+ Claude API 返回403→ 继续本教程 - 境外服务器:直接跳到 Step 8,不需要装代理
Step 2:处理机场订阅(关键坑点)
2.1 ⚠️ 大坑:云服务器 IP 段被机场封禁
99% 的机场都会封禁数据中心 IP 段(防止有人买一个订阅在云上搭代理转卖)。直接在服务器上 curl 订阅 URL 会返回 403:
<h1>403 Forbidden</h1>
<p>The isp has been denied.</p>
别浪费时间换 User-Agent,行不通的。
2.2 解决方案:本地下载 + 上传
在你本地电脑上(家用宽带 IP)下载订阅文件:
# Windows PowerShell 或 Linux bash 都可以
curl -L -A "clash" -o clash_config.yaml "https://你的机场.com/api/v1/client/subscribe?token=xxxxx&flag=clash"
# 验证下载成功(应该是几百行 YAML 文本)
wc -l clash_config.yaml
head -5 clash_config.yaml
# 应该看到 mixed-port: 7890 之类的
2.3 上传到服务器
# 在服务器上创建配置目录
ssh root@你的服务器IP "mkdir -p /etc/mihomo"
# 用 scp 或 sftp 上传
scp clash_config.yaml root@你的服务器IP:/etc/mihomo/config.yaml
或者用 Xshell 的 rz 命令、WinSCP 拖文件都行。
Step 3:安装 mihomo 内核
mihomo 是什么:Clash 内核的活跃分支(Clash.Meta),命令行版无需图形界面,是当前最稳定的选择。
3.1 SSH 连到服务器,下载 mihomo
# 1. 查最新版本号
curl -s https://api.github.com/repos/MetaCubeX/mihomo/releases/latest | grep tag_name
# 假设输出: "tag_name": "v1.19.24"
# 2. 下载(如果服务器直连 GitHub 慢,用国内加速镜像)
VERSION="v1.19.24"
ARCH="amd64" # ARM 服务器改成 arm64
# 国内加速镜像
URL="https://ghfast.top/https://github.com/MetaCubeX/mihomo/releases/download/${VERSION}/mihomo-linux-${ARCH}-${VERSION}.gz"
curl -L -o /tmp/mihomo.gz "$URL"
# 3. 安装
gunzip /tmp/mihomo.gz
chmod +x /tmp/mihomo
mv /tmp/mihomo /usr/local/bin/mihomo
# 4. 验证
/usr/local/bin/mihomo -v
# 期望输出: Mihomo Meta v1.19.24 linux amd64 with go1.x
Step 4:生成简化配置(默认走日本节点)
4.1 为什么要简化原配置
机场原始 yaml 通常 600+ 行,规则极复杂,可能导致:
- mihomo 启动失败
- 启动慢(要加载几千条规则)
- 行为难以预测
只为 Claude Code 用代理的话,规则三条就够。
4.2 在本地用 Python 生成简化配置
把下面脚本保存为 simplify_config.py:
import yaml
# 读原始订阅
with open('clash_config.yaml', 'r', encoding='utf-8') as f:
cfg = yaml.safe_load(f)
# 提取所有节点,排除非节点项(提示信息)
proxies = cfg.get('proxies', [])
real_nodes = [
p['name'] for p in proxies
if not p['name'].startswith(('剩余流量', '距离下次', '套餐到期', '🏘️', '🛠️'))
]
# 选一个默认节点(可改为 "🇭🇰 香港|Hong Kong 01" 等)
DEFAULT_NODE = '🇯🇵 日本|Japan 01'
assert DEFAULT_NODE in real_nodes, f'默认节点不存在!可选: {real_nodes[:5]}'
# 生成简化配置
new_cfg = {
'mixed-port': 7890, # HTTP+SOCKS 混合端口
'allow-lan': False, # 不允许局域网访问
'bind-address': '127.0.0.1', # 仅监听本地(安全)
'mode': 'rule',
'log-level': 'info',
'external-controller': '127.0.0.1:9090',
'dns': {
'enable': True,
'ipv6': False,
'enhanced-mode': 'fake-ip',
'fake-ip-range': '198.18.0.1/16',
'nameserver': ['223.5.5.5', '119.29.29.29'],
'fallback': ['1.1.1.1', '8.8.8.8'],
'fallback-filter': {'geoip': True, 'geoip-code': 'CN'},
},
'proxies': proxies, # 保留所有节点
'proxy-groups': [{
'name': 'PROXY',
'type': 'select',
'proxies': [DEFAULT_NODE] + [n for n in real_nodes if n != DEFAULT_NODE],
}],
'rules': [
'DOMAIN-SUFFIX,anthropic.com,PROXY',
'DOMAIN-SUFFIX,claude.ai,PROXY',
'DOMAIN-SUFFIX,openai.com,PROXY',
'DOMAIN-SUFFIX,googleapis.com,PROXY',
'DOMAIN-SUFFIX,github.com,PROXY',
'DOMAIN-SUFFIX,githubusercontent.com,PROXY',
'DOMAIN-SUFFIX,npmjs.org,PROXY',
'DOMAIN-SUFFIX,registry.npmjs.org,PROXY',
'GEOIP,CN,DIRECT', # 国内 IP 直连
'MATCH,PROXY', # 其余全走代理
],
}
with open('config_simple.yaml', 'w', encoding='utf-8') as f:
yaml.safe_dump(new_cfg, f, allow_unicode=True, default_flow_style=False, sort_keys=False)
print(f'已生成 config_simple.yaml,包含 {len(real_nodes)} 个节点,默认 {DEFAULT_NODE}')
运行:
pip install pyyaml
python simplify_config.py
4.3 上传简化配置覆盖原配置
scp config_simple.yaml root@你的服务器IP:/etc/mihomo/config.yaml
Step 5:下载 GeoIP 数据并启动 mihomo
5.1 mihomo 需要 GeoIP 数据库识别”哪些 IP 是国内”
# SSH 到服务器
cd /etc/mihomo
# 用国内镜像加速下载
curl -sL --max-time 90 -o geoip.metadb
"https://ghfast.top/https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip.metadb"
curl -sL --max-time 90 -o geosite.dat
"https://ghfast.top/https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite.dat"
curl -sL --max-time 90 -o Country.mmdb
"https://ghfast.top/https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/country.mmdb"
# 验证目录
ls -la /etc/mihomo/
# 应该看到:config.yaml + geoip.metadb + geosite.dat + Country.mmdb
5.2 测试配置是否合法
/usr/local/bin/mihomo -t -d /etc/mihomo
# 期望最后一行: configuration file /etc/mihomo/config.yaml test is successful
5.3 临时启动测试
# 后台启动(用 setsid 完全脱离 SSH 会话)
setsid /usr/local/bin/mihomo -d /etc/mihomo > /var/log/mihomo.log 2>&1 < /dev/null &
# 等 3 秒后检查
sleep 3
ss -tlnp | grep 7890
# 期望:LISTEN ... 127.0.0.1:7890 ... users:(("mihomo",...))
# 测试代理出口(应该看到日本东京 IP)
curl -sx http://127.0.0.1:7890 -m 15 https://ipinfo.io
# 测试 Claude API
curl -sx http://127.0.0.1:7890 -m 15 -o /dev/null -w "%{http_code}n" https://api.anthropic.com
# 期望:405 (之前是 403,说明地区封锁突破成功)
Step 6:配置 systemd 开机自启
6.1 创建 systemd 服务文件
cat > /etc/systemd/system/mihomo.service <<'EOF'
[Unit]
Description=mihomo Daemon
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/mihomo -d /etc/mihomo
Restart=on-failure
RestartSec=5
LimitNOFILE=1048576
[Install]
WantedBy=multi-user.target
EOF
6.2 启用并启动
# 先杀掉之前手动启动的进程
pkill -9 -f mihomo
# 重载 systemd 并启用 + 启动
systemctl daemon-reload
systemctl enable mihomo
systemctl start mihomo
# 查状态(应该看到 active (running))
systemctl status mihomo --no-pager
至此 mihomo 已经开机自启。可以 reboot 验证:重启后无需操作直接能用。
Step 7:写入全局代理环境变量
7.1 创建自动加载脚本
cat > /etc/profile.d/proxy.sh <<'EOF'
# === Auto-loaded proxy settings (mihomo 7890) ===
if [ -z "${HTTPS_PROXY:-}" ] && nc -z 127.0.0.1 7890 2>/dev/null; then
export HTTP_PROXY="http://127.0.0.1:7890"
export HTTPS_PROXY="http://127.0.0.1:7890"
export http_proxy="http://127.0.0.1:7890"
export https_proxy="http://127.0.0.1:7890"
export NO_PROXY="localhost,127.0.0.1,::1,*.local"
export no_proxy="localhost,127.0.0.1,::1,*.local"
fi
EOF
chmod +x /etc/profile.d/proxy.sh
7.2 让交互式 shell 也加载
/etc/profile.d/*.sh 默认只在 login shell 时加载,某些 SSH 客户端可能用 non-login shell。补一下:
grep -q "profile.d/proxy.sh" /etc/bash.bashrc
|| echo "[ -f /etc/profile.d/proxy.sh ] && . /etc/profile.d/proxy.sh" >> /etc/bash.bashrc
7.3 验证
# 退出当前 SSH,重新连接
exit
# 再 ssh root@... 进来
# 检查环境变量
env | grep -i proxy
# 应该看到 HTTPS_PROXY=http://127.0.0.1:7890 等
Step 8:安装 Node.js 与 Claude Code
8.1 检查/安装 Node.js(≥ 18)
node -v
# 如果输出版本 ≥ v18.x,跳过下面安装
如果没装 Node.js:
# Ubuntu 24.04 仓库自带的版本
apt update && apt install -y nodejs npm
# 或者装最新 LTS(推荐)
curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
apt install -y nodejs
8.2 通过代理装 Claude Code
环境变量已经在 Step 7 设置好了,npm 会自动走代理:
npm install -g @anthropic-ai/claude-code
# 验证
claude --version
# 期望输出: 2.x.xx (Claude Code)
which claude
# 期望输出: /usr/bin/claude 或 /usr/local/bin/claude
Step 9:登录 Claude(订阅 vs API key)
9.1 ⚠️ 关键概念区分
| 方式 | 怎么登录 | 计费 |
|---|---|---|
| Pro/Max 订阅 | claude auth login 选 Claude account → 浏览器 OAuth |
包月,订阅内不限消息 |
| API key | 设环境变量 ANTHROPIC_API_KEY |
按 token 扣 credit balance |
两种钱包独立:你 Pro 订阅没钱 ≠ API credits 没钱。混着用会出现”我月付了为什么 Rate limit”的诡异现象。
9.2 推荐:用订阅登录
# 先确保没有 API key 干扰
grep -i ANTHROPIC_API_KEY ~/.bashrc /etc/environment /etc/profile /etc/profile.d/*.sh 2>/dev/null
# 如果有结果,注释或删掉这些行
# 启动登录流程
claude auth login
# 选 1. Claude account (claude.ai login)
# 它会显示一段 URL
9.3 完成 OAuth(服务器没浏览器也能搞定)
- 复制屏幕上的 URL
- 在你 本地 Windows 浏览器 打开
- 用 Pro/Max 账号登录并授权
- 授权后会看到一段 Authentication Code
- 复制 Code,粘贴回 SSH 终端
- 终端显示
Login successful即成功
9.4 验证
claude auth status
# 期望:
# {
# "loggedIn": true,
# "authMethod": "claude.ai",
# "subscriptionType": "pro" ← 关键:你的订阅类型
# }
9.5 替代方案:用 API key
如果你坚持用 API key(按量计费):
echo 'export ANTHROPIC_API_KEY="sk-ant-api03-xxxxx"' >> ~/.bashrc
source ~/.bashrc
Step 10:配置默认模型
10.1 模型别名
| 别名 | 实际模型 | Pro 计划 | Max 计划 |
|---|---|---|---|
sonnet |
claude-sonnet-4-6 | ✅ | ✅ |
opus |
claude-opus-4-7 | ⚠️ 配额很少 | ✅ |
haiku |
claude-haiku-4-5 | ✅ | ✅ |
10.2 设置默认模型
编辑 ~/.claude/settings.json:
mkdir -p ~/.claude
cat > ~/.claude/settings.json <<'EOF'
{
"model": "sonnet",
"env": {
"API_TIMEOUT_MS": "3000000"
}
}
EOF
10.3 选模型建议
- 日常编程:默认
sonnet,配额最多 - 复杂任务:临时切 Opus(在 TUI 里输
/model) - 简单问答:
haiku速度最快、最省额度
坑点:某些版本的 Claude Code 在
/model菜单里 Opus 显示成 4.6(实际是 4.7),但claude --model claude-opus-4-7 -p "test"跑得通就说明你账号有权限。可以直接在settings.json写全名"model": "claude-opus-4-7"绕过显示 bug。
Step 11:创建一键状态检查命令
便于以后排查问题:
cat > /usr/local/bin/claude-status <<'EOF'
#!/bin/bash
echo "=== mihomo 服务 ==="
systemctl is-active mihomo --quiet && echo "✅ active" || echo "❌ stopped"
systemctl is-enabled mihomo --quiet && echo "✅ enabled (开机自启)" || echo "⚠️ disabled"
echo ""
echo "=== 代理出口 ==="
curl -sx http://127.0.0.1:7890 -m 8 https://ipinfo.io 2>/dev/null | grep -E '"(ip|city|country)"' || echo "❌ 代理不通"
echo ""
echo "=== 环境变量 ==="
echo "HTTPS_PROXY=$HTTPS_PROXY"
echo ""
echo "=== Claude Code ==="
claude --version 2>&1
echo ""
echo "=== Claude 登录状态 ==="
claude auth status 2>&1
EOF
chmod +x /usr/local/bin/claude-status
以后只要 SSH 进来运行 claude-status 就能查所有项。
🎉 至此全部完成
日常使用流程:
# 1. SSH 进来(环境变量自动加载)
ssh root@你的服务器IP
# 2. 直接用
claude
# 3. 想检查状态
claude-status
端口与防火墙详解
入站方向(外部 → 服务器)
| 端口 | 必要性 | 说明 |
|---|---|---|
| 22 (SSH) | ✅ 必需 | 否则你连不进来 |
| 7890 (mihomo) | ❌ 不需要开 | mihomo 监听 127.0.0.1,外部连不进来 |
| 9090 (mihomo API) | ❌ 不需要开 | 仅本机访问 |
出站方向(服务器 → 外部)
| 目标 | 端口 | 说明 |
|---|---|---|
| 机场节点 | 各种(VLESS 多个高位端口) | 阿里云出站默认全开 |
| Anthropic API | 443 | 通过代理 |
| GitHub/npm | 443 | 通过代理 |
为什么 mihomo 监听 127.0.0.1 不是 0.0.0.0
两个原因:
- 安全 ——监听
0.0.0.0等于把代理服务挂到公网。任何人扫到端口都能免费蹭你的机场流量。 - 不需要 —— claude 在服务器内部跑,本机访问够了。
TCP 出站连接的本质
每次进程发起出站连接:
- 源端口:操作系统从临时端口范围(Linux 默认 32768~60999)随机分配
- 目标端口:对方的监听端口(如机场节点的 XXXXX 端口)
- 不需要在防火墙开任何端口:防火墙只管入站
总结一句话:进来的门要主动开,出去的随便走。
常见故障排查
故障 1:curl https://api.anthropic.com 返回 403
原因:没用代理,直连被地区封禁。
排查:
echo $HTTPS_PROXY
# 应该是 http://127.0.0.1:7890;如果空,环境变量没加载
source /etc/profile.d/proxy.sh
故障 2:claude 启动报 Credit balance too low
原因:环境变量里残留 ANTHROPIC_API_KEY,且这个 key 余额不足。
修复:
# 找出来源
grep -rn "ANTHROPIC_API_KEY" ~/.bashrc /etc/environment /etc/profile /etc/profile.d/ 2>/dev/null
# 删掉对应行(或注释)
sed -i '/ANTHROPIC_API_KEY/d' ~/.bashrc
# 退出当前 SSH 重连
exit
故障 3:claude 启动报 Rate limit reached
可能原因:
- 同时存在 API key + 订阅登录,状态混乱
- 用了 1M context 模型(Pro 计划不支持)
修复:
# 改回标准 sonnet
sed -i 's/"sonnet[1m]"/"sonnet"/' ~/.claude/settings.json
故障 4:mihomo 启动失败
journalctl -u mihomo --no-pager -n 50
# 看具体错误。常见:
# - GeoIP 文件缺失 → 重新下载(Step 5.1)
# - 配置语法错误 → /usr/local/bin/mihomo -t -d /etc/mihomo
# - 端口被占用 → ss -tlnp | grep 7890,杀掉占用进程
故障 5:网速慢/Claude 经常超时
可能是节点不稳,切换节点:
# 列出所有节点
curl -s http://127.0.0.1:9090/proxies/PROXY | python3 -c "import json,sys; print('n'.join(json.load(sys.stdin)['all']))"
# 切到指定节点(替换 NODE_NAME)
curl -X PUT http://127.0.0.1:9090/proxies/PROXY
-H 'Content-Type: application/json'
-d '{"name":"🇭🇰 香港|Hong Kong 01"}'
# 再测速
curl -sx http://127.0.0.1:7890 -m 15 https://ipinfo.io
故障 6:机场订阅过期/换了,怎么更新
# 1. 在本地重新下载新订阅
# 2. 用 Step 4 的 simplify_config.py 重新生成简化配置
# 3. 上传覆盖
scp config_simple.yaml root@你的服务器IP:/etc/mihomo/config.yaml
# 4. 重启 mihomo
ssh root@你的服务器IP "systemctl restart mihomo && sleep 2 && claude-status"
完整目录结构与文件清单
部署完成后,服务器上的关键文件:
/etc/mihomo/ # mihomo 配置目录
├── config.yaml # 主配置(你的订阅简化版)
├── geoip.metadb # GeoIP 数据库
├── geosite.dat # GeoSite 数据库
└── Country.mmdb # MaxMind 国家库
/etc/systemd/system/
└── mihomo.service # systemd 服务定义
/etc/profile.d/
└── proxy.sh # 代理环境变量自动加载
/etc/bash.bashrc # 已追加 source proxy.sh
/usr/local/bin/
├── mihomo # mihomo 二进制
└── claude-status # 一键状态检查命令
/var/log/
└── mihomo.log # mihomo 运行日志
~/.claude/ # Claude Code 用户配置
├── settings.json # 模型、环境变量、插件等
└── .credentials.json # OAuth 凭据(自动生成)
~/.claude.json # Claude Code 全局状态
/usr/lib/node_modules/@anthropic-ai/ # Claude Code 安装位置
└── claude-code/
附录:常用命令速查
# 服务管理
systemctl status mihomo # 看状态
systemctl restart mihomo # 重启
systemctl stop mihomo # 停止
journalctl -u mihomo -n 50 --no-pager # 看最近 50 行日志
# 测试
claude-status # 一键自检
curl -sx http://127.0.0.1:7890 https://ipinfo.io # 测代理出口
curl -sx http://127.0.0.1:7890 -o /dev/null -w "%{http_code}" https://api.anthropic.com # 测 API
# 节点切换
curl -s http://127.0.0.1:9090/proxies/PROXY # 看当前节点
curl -X PUT http://127.0.0.1:9090/proxies/PROXY
-d '{"name":"节点全名"}' # 切换节点
# Claude Code
claude --version # 版本
claude auth status # 登录状态
claude auth logout # 退出登录
claude --model claude-opus-4-7 "你的问题" # 临时指定模型
致谢与参考
- mihomo (Clash.Meta): https://github.com/MetaCubeX/mihomo
- Claude Code 文档: https://docs.anthropic.com/en/docs/claude-code
- GitHub 加速镜像: https://ghfast.top (第三方,仅供参考)
📅 教程版本:基于 mihomo v1.19.24 + Claude Code v2.1.87,2026-05-08 验证通过。
⚠️ 安全提醒:
- 不要把 mihomo 的 7890 端口暴露到公网(除非加认证),否则会被滥用
- 不要在公开场合贴你的机场订阅 URL 或 ANTHROPIC_API_KEY
- 服务器 root 密码不要太弱,建议改用 SSH 密钥登录
全文完。如有问题,照着 常见故障排查 章节逐项检查。
发表回复