扔台 VPS 给 AI,让它帮我搭梯子
开发者深夜配置代理服务器
别人家的服务器,我总觉得不踏实
用了好几年商业 VPN。用着用着越来越别扭——流量全过别人的服务器,对方是谁、数据怎么处理,全凭信任。
做了这么多服务端的活,自己搭一个按道理不难。
于是租了一台 VPS——Atlas Networks,洛杉矶,9929 线路,静态住宅 IP。然后把 SSH 凭据扔给 Claude Code:帮我搭一套完整的代理服务,我可以自用,也可以分享给朋友。
有几件事出乎我的意料——包括失败的方向,和最后搭出来的东西。
Shadowsocks:四小时阵亡
Claude Code 第一步部署的是 Shadowsocks。成熟方案,默认选择,没什么好说的。
四个小时之后 IP 就被封了。
不是限速,是整个封掉。流量直接断了。联系服务商,确认:主动封锁。
这件事让我搞明白了 GFW 检测的一个基础原理:它不是一个静态黑名单,而是一套主动探测系统。看到流量特征不符合已知协议,就主动去探你的服务器——发异常报文、测响应模式。Shadowsocks 曾经很难被识别,但 GFW 对它已经训练了很多年了。
2025 年用一个新 IP 部署 Shadowsocks,基本就是举牌告诉它"来探我"。
问题不是加密——GFW 读不了你的内容——而是流量指纹。高熵密文、非标准握手、响应模式匹配代理行为。Shadowsocks 全中。
换台 VPS,换个思路。
Reality:藏在明处的艺术
新方案是 sing-box + VLESS-Reality。
Claude Code 解释 Reality 工作原理的时候,我觉得这个设计确实聪明:它不是让流量看起来像什么都没有,而是让流量看起来像在访问一个真实网站——借用它的 TLS 指纹。你的握手和一个普通浏览器访问 microsoft.com 一模一样。
GFW 要么允许你过,要么把微软也封了。它永远不会选后者。
Reality 之外还部署了三个备用协议:Hysteria2 和 TUIC-v5(基于 QUIC 的 UDP 协议,速度快但吃网络质量)、以及 Vmess-WS(WebSocket,最弱但最后兜底)。四个协议,四个端口。防火墙只开了这几个端口,其他全关。
Clash Verge 的配置里,自动选择分组只包含 Reality,其他协议底层备用但不参与日常路由。Reality 够用就永远走 Reality。
证书踩坑和一路推进
协议选好之后,Claude Code 一路推进。
SSL 证书用的 acme.sh + Cloudflare DNS API 验证。不需要开 80 端口——给 acme.sh 一个只有 DNS 编辑权限的 Cloudflare API Token,它去创建 TXT 记录验证域名所有权,验完自动清除。这个方式很干净,服务器不需要暴露额外端口。
中间踩了一个坑:sing-box 一键脚本在内部跑过一次 acme.sh,把域名存进了邮箱字段的缓存里。后来我单独给订阅服务器申请证书的时候,acme.sh 复用了那份缓存,Let's Encrypt 收到的证书请求里邮箱字段是个域名格式,直接拒绝了。
错误信息有点绕,花了三个来回才定位到。删掉 CA 缓存目录,带上 --accountemail 重新跑,才过了。
防火墙、BBR 加速、服务开机自启,这些 Claude Code 一并处理掉了。基本没有需要我介入的地方。
订阅服务器:最有成就感的部分
很多自建代理方案就是生成一个 base64 字符串,或者一个 QR code,手动导进去。
我想要更完整一点的东西:一个真正的订阅 URL,客户端能读到流量统计。Clash Verge 支持 Subscription-Userinfo 响应头,读到之后会渲染一个流量条——已用多少、剩余多少、到期时间。这个细节让整套服务看起来完整,不像是拼凑出来的。
Claude Code 搭了一个 Python 服务跑在 nginx 后面:
- nginx 处理 443 端口的 TLS,把请求代理到本机 8089
- Python 服务读订阅配置文件,同时调
vnstat --json拿 VPS 的真实上下行数据,动态生成响应头 - 头格式:
upload=X; download=Y; total=Z; expire=T - Clash Verge 拿到之后自动渲染,不需要任何客户端配置
Token 是一段随机十六位 hex,存在服务器上。订阅 URL 就是 https://your.domain.com/{token}。
这里有个小插曲:最开始 Python 服务没处理 HEAD 请求,Clash Verge 用 HEAD 拿 header 时服务直接报错。加上 do_HEAD 方法就好了。这种细节不跑起来根本发现不了。
朋友粘贴链接就能用
订阅 URL 做完整之后,分享变得特别简单。
Clash Verge:粘贴 URL,点导入,激活配置,开 TUN 模式。Shadowrocket(iOS):URL 直接添加为订阅,或者扫 QR code。
朋友那边能看到流量条——已用多少、3TB 月限额剩多少、到期日期。看起来跟商业服务没什么区别。
Claude Code 是怎么处理失败的
回看这个过程,印象最深的不是 Claude Code 做了什么,而是它怎么处理失败。
证书因为缓存问题三次申请失败,它没有重复执行同一条命令。它去查 acme.sh 的状态,找到了那份坏缓存,清掉,重跑。nginx 的 proxy 配置有时候传 header 有时候不传,它把整个链路走了一遍,逐层确认每个环节在传什么、缺了什么。
每次失败大概十到十五分钟。但它没有绕开,也没有放弃——一直在找真正的原因。
Clash Verge 本身的行为是个例外。它会在重启时删掉你手动编辑的配置文件,只保留通过订阅 URL 导入的。这个是客户端特有的行为,Claude Code 不知道,最终是我们一起通过测试发现的。
有一条界限很清楚:凡是有明确验证标准的任务("这个 URL 应该返回包含 proxies: 字段的 YAML"),Claude Code 调试起来很干净,可以一直循环到通为止。凡是客户端行为比较特殊的地方,就需要人来观察和判断。
分工明确,效率就高。
一个下午,一套自己托管的代理服务,朋友发个链接就能用。