我需要让一台已经承载个人网站的阿里云 ECS 长期访问 ChatGPT、Codex 和 OpenAI API,同时不能破坏网站和 SSH 的现有入口。因此,问题不只是临时连通,还要给服务器增加一条可维护的外网出口。
最终我使用 Proton Free 的 OpenVPN TCP 配置,让服务器主动发起的流量走 VPN;同时用策略路由保留阿里云公网网卡的回包路径,避免 SSH 和网站进站流量被改乱。
先把进站和出站分开看
很多人听到“服务器连不上 OpenAI”,第一反应是安装一个 VPN 客户端,然后把配置导进去。这个方向没错,但如果服务器上已经跑着网站,就不能只看“我能不能 curl 到 OpenAI”,还要同时看另外几个问题。
需要同时确认四件事:
- 公网访问网站的流量还能不能正常进来;
- SSH 会不会因为默认路由改变而断开;
- 网站后端访问第三方服务时,出口 IP 会不会变化;
- 重启、掉线和 DNS 切换会不会让问题过几天再次出现。
需要解决的不是安装客户端,而是增加一条可控的出站路径,并明确它会影响哪些流量。
WireGuard 握手始终没有建立
WireGuard 是现代 Linux 上非常好的选择:内核支持好,配置简单,性能高,资源占用低。如果网络路径允许 UDP 正常工作,WireGuard 往往是最轻量的方案。
这次也先按 WireGuard 思路做了验证。配置文件可以导入,接口也能启动,远端 IP 的 TCP 端口可以访问,但 WireGuard 握手始终没有建立,表现为只有发送流量、没有接收流量。
这类现象通常说明问题不在本机命令是否写对,而在更底层的路径上:UDP 被限制、运营商路径不稳定、云环境出站策略不友好,或者配置对应的 WireGuard 参数无法被服务端接受。继续硬调 WireGuard 的收益就不高了。
在这台服务器上,继续硬调 WireGuard 的收益已经不高,能稳定工作的 OpenVPN TCP 更合适。
为什么换成 OpenVPN TCP
Proton Free 也提供 OpenVPN 配置,其中 TCP profile 对一些受限网络更友好。OpenVPN TCP 的性能通常不如 WireGuard,延迟也可能更高,但它有一个现实优势:更容易穿过只允许常见 TCP 流量的网络路径。
这次服务器的目标主要是让 ChatGPT、Codex、OpenAI API 能够长期访问,并不是承载大带宽转发。对这种用途来说,OpenVPN TCP 的稳定性比极限性能更重要。
最终采用的是 Proton 的 OpenVPN TCP 配置,导入到 Linux 标准的 OpenVPN client 服务里,由 systemd 管理生命周期。
关键设计:网站进站不走 VPN,服务器出站走 VPN
最终路由设计可以概括成一句话:
外部用户访问网站时,ECS 仍然通过阿里云公网网卡响应;服务器主动访问 OpenAI 时,走 Proton VPN 出口。
这背后依赖策略路由。VPN 连接建立后,OpenVPN 会把默认出站流量导向 tun0。如果什么都不做,服务器主动访问外网确实能走 VPN,但公网入口回包、SSH 会话、某些阿里云内网服务都可能被影响。
为避免这个问题,需要为 ECS 自己的公网源地址保留一张直连路由表,让来自阿里云网卡源地址的响应仍然从原网关出去。这样用户访问网站时,连接路径仍然是:
visitor -> Aliyun public IP -> nginx -> local app -> Aliyun public IP -> visitor
而服务器主动访问 OpenAI 时,路径变成:
ECS -> tun0 -> Proton exit -> OpenAI
这两个方向分清楚以后,问题就不再混乱。
DNS 也要跟着处理
VPN 可用不代表 DNS 一定正确。很多“网络通了但服务还是打不开”的问题,其实是 DNS 仍然走原来的解析路径,或者系统同时保留了多个 resolver,导致解析结果不稳定。
这次的做法是:VPN 启动后使用 Proton 推送的 DNS;VPN 关闭时恢复系统原来的 DNS 状态。这样可以避免 OpenAI 相关域名在服务器上被解析到不可用路径,同时不把这个改动永久写死在系统配置里。
DNS 的处理尤其适合写进 up / down hook,而不是手动修改 /etc/resolv.conf。手改虽然快,但几天后很容易忘记自己改过什么。
用 systemd 管理常驻连接
临时连通和长期可用是两回事。要让这条通道成为服务器能力的一部分,至少要处理三件事。
具体包括三点:
- 服务开机自启,服务器重启后不需要人工 SSH 启动;
- OpenVPN 异常退出后自动恢复,能应对网络抖动、服务端切换和临时断线;
- 保留清晰的状态检查命令,方便区分 VPN、DNS 和目标服务本身的问题。
最终服务状态应该具备这些特征:
openvpn-client@proton.service: active
openvpn-client@proton.service: enabled
Restart: on-failure
RestartSec: 30s
这样它才更像一个可维护的服务器组件,而不是一次性的终端会话。
我怎样确认它真的可用
这类改动不能只靠“感觉能打开”。我至少检查五项:
- 服务器出口 IP 是否已经变成 VPN 出口;
chatgpt.com是否能建立连接;api.openai.com/v1/models是否返回401。没有 API key 时这是预期结果,说明 TLS、DNS 和路由已经通到 OpenAI API;auth.openai.com是否可访问,避免登录和授权链路单独卡住;- 原网站的 nginx 和后端应用是否仍然返回
200 OK。
可以把日常检查收敛成几条命令:
ssh aliyun 'proton-ovpn status'
ssh aliyun 'proton-ovpn ip'
ssh aliyun 'proton-ovpn check-chatgpt'
如果只看一个点,很容易误判。比如首页返回 403 不一定代表网络不通,可能只是目标站对命令行客户端的访问策略;而 API 返回 401 也不代表失败,它往往代表网络层已经成功。
这个方案的副作用
当前方案是“整台服务器的主动出站流量走 VPN”。这很直接,也最容易让 Codex、ChatGPT、OpenAI API 立即可用,但它有副作用。
如果网站后端要调用支付、邮件、短信、OAuth、Webhook、风控、统计、对象存储、第三方 API,对方看到的出口 IP 会变成 Proton 的出口 IP,而不是阿里云 ECS 的 IP。有些服务会对 VPN 或数据中心出口更敏感,可能触发限流、风控或地区差异。
因此,如果网站未来承担更严肃的业务功能,建议再做一步分流:让网站服务继续走阿里云原出口,只让指定进程、指定命令、代理端口或单独的 network namespace 走 VPN。
按使用场景区分:
- 个人工具型 ECS:整机出站走 VPN,省事。
- 网站后端依赖很多第三方服务:应做进程级或容器级分流。
- 有支付、登录、IP 白名单、企业 API:不要让整机默认出口长期漂到 VPN。
不要把免费方案当成无限稳定
Proton Free 能解决可达性问题,但免费节点不等于商业专线。它可能遇到节点拥挤、出口 IP 被某些服务限制、服务器切换、延迟波动等情况。
所以这套方案适合把阿里云 ECS 变成一个能长期访问 OpenAI 的个人工作节点,适合跑 Codex、拉取模型服务、执行自动化任务;但如果要做严肃生产依赖,还需要监控、告警、备用出口,甚至更明确的网络供应商方案。
另外,任何跨网络访问方案都应该遵守所在地法律、云服务商条款以及目标服务条款。技术上能连通,只是工程问题的一半;另一半是知道自己在什么边界内使用它。
最后得到的配置
最终,阿里云 ECS 可以长期访问 ChatGPT、Codex 和 OpenAI API,原有网站入口也保持正常。这个结果依赖的不是某一条 VPN 命令,而是对流量方向、回包路径、DNS、服务自恢复和验证标准的完整处理。
我最喜欢这个方案的一点是它足够朴素:不改网站架构,不迁移服务,不引入复杂网关,只是在 ECS 上增加一条可维护的出站能力。它不是最华丽的网络架构,但对于一台个人服务器来说,已经是很舒服的平衡点。