← 返回文章列表

阿里云 ECS 接入 OpenAI:从 WireGuard 切到 OpenVPN 的排障记录

一次阿里云 ECS 网络排障:WireGuard 握手失败后改用 OpenVPN TCP,再用策略路由保住网站入口和 SSH 回包。

Aliyun ECS
OpenAI
OpenVPN
Infrastructure

我需要让一台已经承载个人网站的阿里云 ECS 长期访问 ChatGPT、Codex 和 OpenAI API,同时不能破坏网站和 SSH 的现有入口。因此,问题不只是临时连通,还要给服务器增加一条可维护的外网出口。

最终我使用 Proton Free 的 OpenVPN TCP 配置,让服务器主动发起的流量走 VPN;同时用策略路由保留阿里云公网网卡的回包路径,避免 SSH 和网站进站流量被改乱。

阿里云 ECS 上的进出站路由示意图

先把进站和出站分开看

很多人听到“服务器连不上 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 上增加一条可维护的出站能力。它不是最华丽的网络架构,但对于一台个人服务器来说,已经是很舒服的平衡点。

分享这篇文章

复制链接,或分享到你常用的地方。

评论

发表评论

0 / 1000

KEEP READING

全部文章