现在一定要月付,一定要先试。

如何稳定使用 Claude, ChatGPT, Gemini(静态IP + Clash)

这篇文章大约需要19分钟阅读。

这篇文章说一下如何使用固定IP 搭配 Clash Verge 的覆写功能来实现:不切换配置文件,日常上网用机场节点,AI 相关域名稳定分流到 IPRoyal ISP。

用 Shadowrocket 的可以看看最新文章《如何为 Shadowrocket 使用 IPRoyal 代理》

该方法不支持 Claude的桌面端,使用桌面端还是会偶尔跳到机场的节点。所以如果要使用桌面端,那就直接把静态节点作为本地配置文件导入到 Clash。

Sponsored links

前言

前天我的 Claude Code 突然就报403错误:

Please run /login · API Error: 403
<!DOCTYPE html><html lang="en-US">
<head><title>Just a moment...</title>

一开始看到 Please run /login,很容易以为是登录态过期。但我在 WSL 里跑了一下:

curl -I https://api.anthropic.com/v1/messages

结果返回的是:

HTTP/2 403
cf-mitigated: challenge
server: cloudflare

这就很明显了。不是 /login 的问题,是当前出口 IP 被 Cloudflare 给挡住了。因为 Claude Code 不是浏览器,它跑不了那个 “Just a moment…” 的 JS challenge,所以最后就是 403。

平常这时,我就去换个机场。但朋友给我分享过来一篇 X 上的文章,我看完之后发现里面有很多地方冲突。例如:一下说住宅IP,一下说静态IP,然后截图里又是静态IP,但是到了 Clash verge 的配置文件里写的又是住宅IP。而且就算是配置好了,那个配置只能是拿来用 AI,同时间干其他事情就不行了。

所以我就想着折腾一下,也是为了能稳定用 Claude Code。

解决思路

我用的是 Clash Verge Rev 的覆写功能:全局扩展脚本。简单说,你可以写一段自己的配置规则合并到机场订阅的前面去。好处是不用去手动改机场订阅,毕竟如果有多个订阅,改起来太麻烦,而且只要机场订阅一更新,你手动改的东西就没了。

解决思路:

  1. 机场订阅正常导入。
  2. 用脚本往配置里插入 IPRoyal 的代理节点和 AI 专用代理组。
  3. 最后把 OpenAI、Claude、Gemini 等这些域名分流到这个组。

这样平常该怎么用机场还是怎么用机场。只有命中规则的 AI 流量,才会走 ISP。

先在 IPRoyal 买 ISP

很多网站都有 ISP(静态住宅IP),我是在 IPRoayl 买的,因为我总在看到它的广告。而且价格确实也还便宜。美国不选地区的话,大概 4 美金一个。如果要指定地区,大概 5.2 美金一个。

大概流程是这样:

  1. 注册 IPRoyal。
  2. 找到 ISP Proxies。
  3. 地区选美国或者新加坡。指定地区就加钱。要求IP 风险为0 也要加钱。(我比较抠,一分没加)
  4. 支持支付宝付款,然后你会得到代理信息。

拿到的信息包括:主机、端口、用户名和密码。

IPRoyal 会给 HTTP 和 SOCKS5 两种端口。

加全局扩展脚本

  1. 左侧进入 Profiles。
  2. 最下面找到全局扩展脚本 / Global Extension Script。
  3. 右键编辑文件。
  4. 把下面这段代码贴进去。把你的代理信息填进去。
  5. 保存。

建议你自己把这段丢给AI,说清需求,让它改。本脚本只是个示范。

// 用途:普通公网流量走机场;已列出的 AI 网站和客户端通过机场中转到 IPRoyal。
// 使用:替换旧覆写,填写下方账号密码,在客户端开启规则模式与 TUN。
// 本脚本会重建分流规则;局域网和本机直连,机场原来的国内直连等规则不再使用。
function main(config) {
  // ===== 只需填写这里;服务器和端口以 IPRoyal 后台为准 =====
  var isp = {
    server: "xxx.xxx.xxx.xxx",
    username: "填写用户名",
    password: "填写密码",
    socksPort: 12324,
    httpPort: 12323
  };

  // 新增 AI 服务时填写它自己的域名后缀,不要填写网址或通用 google.com。
  var extraAiDomains = [];
  // 填写任务管理器“详细信息”中的程序名;不要添加 chrome.exe、node.exe 等通用程序。
  var extraAiProcesses = [];

  if (!isp.username || !isp.password || /填写/.test(isp.username + isp.password)) {
    throw new Error("请先在脚本顶部填写 IPRoyal 的真实用户名和密码,再保存覆写。");
  }
  if (!config || typeof config !== "object") {
    throw new Error("没有收到机场配置,请先导入并选中机场订阅。");
  }

  var names = {
    airport: "ISP分流-机场节点",
    auto: "ISP分流-机场自动",
    ai: "ISP分流-AI出口",
    socks: "ISP分流-IPRoyal-SOCKS5",
    http: "ISP分流-IPRoyal-HTTP"
  };
  var owned = Object.keys(names).map(function (key) { return names[key]; });
  function unique(list) {
    return list.filter(function (value, index) { return list.indexOf(value) === index; });
  }
  function isAirport(proxy) {
    return proxy && typeof proxy.name === "string" && !!proxy.server &&
      !/^(direct|reject|reject-drop|compatible|pass|pass-rule|dns)$/i.test(proxy.type || "") &&
      !/^(ISP分流-|IPRoyal)/i.test(proxy.name) &&
      String(proxy.server) !== isp.server;
  }
  // 先读取原订阅,再加入 ISP;不用 include-all,避免把 ISP 本身选成前置机场。
  var originalProxies = (Array.isArray(config.proxies) ? config.proxies : []).filter(function (p) {
    return owned.indexOf(p.name) === -1;
  });
  var originalGroups = (Array.isArray(config["proxy-groups"]) ? config["proxy-groups"] : []).filter(function (g) {
    return owned.indexOf(g.name) === -1;
  });
  var airportProxies = originalProxies.filter(isAirport);
  var airportNames = unique(airportProxies.map(function (p) { return p.name; }));
  var providers = config["proxy-providers"] || {};
  var providerNames = Object.keys(providers);
  if (airportNames.length === 0 && providerNames.length === 0) {
    throw new Error("当前订阅没有可用的机场节点或 proxy-providers,请检查订阅。");
  }
  // 本模板面向普通机场订阅;已有自定义代理链需要单独核对,避免自动拼接出循环。
  airportProxies.forEach(function (p) {
    if (p["dialer-proxy"] && p["dialer-proxy"] !== "DIRECT") {
      throw new Error("机场节点已设置 dialer-proxy,请先检查原有代理链:" + p.name);
    }
  });
  providerNames.forEach(function (name) {
    var override = providers[name].override || {};
    if (override["dialer-proxy"] && override["dialer-proxy"] !== "DIRECT") {
      throw new Error("节点集合已设置 dialer-proxy,请先检查原有代理链:" + name);
    }
  });

  var sourceOptions = {
    // 空集合必须拒绝连接,不能使用默认的 COMPATIBLE 直连兜底。
    "empty-fallback": "REJECT",
    "exclude-type": "Direct|Reject|Compatible|Pass|Dns",
    "exclude-filter": "(?i)^(ISP分流-IPRoyal-|IPRoyal)|剩余流量|到期时间|套餐到期|官网地址"
  };
  function airportGroup(name, type, withAuto) {
    var group = Object.assign({ name: name, type: type }, sourceOptions);
    var members = (withAuto ? [names.auto] : []).concat(airportNames);
    if (members.length) group.proxies = members;
    if (providerNames.length) group.use = providerNames.slice();
    if (type === "fallback") {
      group.url = "https://www.gstatic.com/generate_204";
      group.interval = 300;
      group.timeout = 5000;
      group.lazy = true;
    }
    return group;
  }

  config.proxies = originalProxies.concat([
    {
      name: names.socks, type: "socks5", server: isp.server, port: isp.socksPort,
      username: isp.username, password: isp.password, udp: false,
      "dialer-proxy": names.airport
    },
    {
      name: names.http, type: "http", server: isp.server, port: isp.httpPort,
      username: isp.username, password: isp.password, tls: false,
      "dialer-proxy": names.airport
    }
  ]);
  config["proxy-groups"] = [
    airportGroup(names.airport, "select", true),
    airportGroup(names.auto, "fallback", false),
    { name: names.ai, type: "select", proxies: [names.socks, names.http], "empty-fallback": "REJECT" }
  ].concat(originalGroups);

  var aiDomains = unique([
    // OpenAI、ChatGPT、Codex、Sora。
    "openai.com", "chatgpt.com", "chat.com", "oaistatic.com", "oaiusercontent.com",
    "oaistatsig.com", "sora.com", "chatgpt.livekit.cloud",
    // Claude 网页、桌面端、Claude Code。
    "anthropic.com", "claude.ai", "claude.com", "clau.de", "claudeusercontent.com",
    "claudemcpclient.com", "claudemcpcontent.com",
    // Gemini、AI Studio、NotebookLM,以及专用 API。
    "gemini.google.com", "gemini.google", "gemini.gstatic.com", "bard.google.com",
    "aistudio.google.com", "ai.google.dev", "ai.studio", "makersuite.google.com",
    "notebooklm.google.com", "notebooklm.google", "generativelanguage.googleapis.com",
    "alkalicore-pa.clients6.google.com", "alkalimakersuite-pa.clients6.google.com",
    "webchannel-alkalimakersuite-pa.clients6.google.com", "cloudaicompanion.googleapis.com",
    "cloudcode-pa.googleapis.com", "notebooklm-pa.googleapis.com", "notebooklm.googleapis.com",
    "aisandbox-pa.googleapis.com",
    // 常见 AI 编辑器、网站和 API 平台。
    "cursor.com", "cursor.sh", "cursorapi.com", "cursor-cdn.com",
    "windsurf.com", "windsurf.ai", "codeium.com", "codeiumdata.com",
    "perplexity.ai", "pplx.ai", "grok.com", "x.ai", "deepseek.com",
    "openrouter.ai", "poe.com", "mistral.ai", "groq.com"
  ].concat(extraAiDomains));
  var aiExactDomains = [
    "openaiapi-site.azureedge.net", "openaiassets.blob.core.windows.net",
    "openaicom-api-bdcpf8c6d2e9atf6.z01.azurefd.net", "openaicom.imgix.net",
    "openaicomproductionae4b.blob.core.windows.net", "production-openaicom-storage.azureedge.net",
    "servd-anthropic-website.b-cdn.net",
    // Google 登录也固定到 ISP;因此 Gmail 等其他 Google 服务的登录页也会走 ISP。
    "accounts.google.com", "oauth2.googleapis.com"
  ];
  var aiProcesses = unique([
    "ChatGPT.exe", "Claude.exe", "Codex.exe", "Cursor.exe", "Windsurf.exe",
    "Cherry Studio.exe", "CherryStudio.exe", "LM Studio.exe",
    "claude", "codex", "ChatGPT", "Claude", "Cursor", "Windsurf"
  ].concat(extraAiProcesses));

  // 局域网、本机 API 和本地 MCP 服务保持可用;不放行 198.18.0.0/16 假 IP 地址池。
  var rules = [
    "DOMAIN-SUFFIX,localhost,DIRECT", "DOMAIN-SUFFIX,local,DIRECT", "DOMAIN-SUFFIX,lan,DIRECT",
    "IP-CIDR,127.0.0.0/8,DIRECT,no-resolve", "IP-CIDR,10.0.0.0/8,DIRECT,no-resolve",
    "IP-CIDR,172.16.0.0/12,DIRECT,no-resolve", "IP-CIDR,192.168.0.0/16,DIRECT,no-resolve",
    "IP-CIDR,169.254.0.0/16,DIRECT,no-resolve",
    "IP-CIDR6,::1/128,DIRECT,no-resolve", "IP-CIDR6,fc00::/7,DIRECT,no-resolve",
    "IP-CIDR6,fe80::/10,DIRECT,no-resolve",
    // 让网页使用 TCP HTTPS,避免未识别的 QUIC 连接分到普通机场出口。
    "AND,((NETWORK,UDP),(DST-PORT,443)),REJECT"
  ];
  function addAiRule(type, value) {
    if (typeof value !== "string" || !value || /[,\r\n()]/.test(value)) {
      throw new Error("AI 域名或进程名格式不正确,请勿填写网址或规则分隔符。");
    }
    // 必须先拒绝这类 AI 流量的 UDP,不能让不支持 UDP 的 ISP 导致规则继续向下匹配。
    rules.push("AND,((NETWORK,UDP),(" + type + "," + value + ")),REJECT");
    rules.push(type + "," + value + "," + names.ai);
  }
  aiProcesses.forEach(function (name) { addAiRule("PROCESS-NAME", name); });
  aiDomains.forEach(function (domain) { addAiRule("DOMAIN-SUFFIX", domain); });
  aiExactDomains.forEach(function (domain) { addAiRule("DOMAIN", domain); });
  rules.push("MATCH," + names.airport);
  // 机场也不支持某种 UDP 时,拒绝连接,避免内核无匹配后的 DIRECT 兜底。
  rules.push("MATCH,REJECT");
  config.rules = rules;
  config.mode = "rule";
  config["find-process-mode"] = "always";

  // 保留订阅的 DNS 设置;补齐缺失项。TUN 的开关与 DNS 劫持仍在客户端中开启。
  config.dns = config.dns || {};
  config.dns.enable = true;
  if (!config.dns.nameserver || !config.dns.nameserver.length) {
    config.dns.nameserver = ["https://1.1.1.1/dns-query#" + names.airport];
  }
  if (!config.dns["proxy-server-nameserver"] || !config.dns["proxy-server-nameserver"].length) {
    config.dns["proxy-server-nameserver"] = ["223.5.5.5", "119.29.29.29"];
  }
  if (!config.dns["enhanced-mode"]) config.dns["enhanced-mode"] = "fake-ip";
  if (!config.dns["fake-ip-range"]) config.dns["fake-ip-range"] = "198.18.0.1/16";
  config.sniffer = Object.assign({}, config.sniffer || {}, {
    enable: true, "parse-pure-ip": true, "force-dns-mapping": true,
    "override-destination": false,
    sniff: { HTTP: { ports: [80, "8080-8880"] }, TLS: { ports: [443, 8443] }, QUIC: { ports: [443, 8443] } }
  });
  return config;
}

激活配置

点击“代理”,找到 AI-Services 分组,然后点击一下 IPRoyal-ISP-SOCKS5 , 就完成激活了。

打开 TUN 模式(可选)

如果你只用浏览器访问 AI 网站的话,系统代理就行了。但如果你是用客户端,例如 Claude Code,Antigravity,Codex,那就要打开 TUN 模式了。模式的话,选规则或者全局随便。

验证是否生效

可以在 Verge 高级设置里查看当前设置,看看里面有没有 IPRoyal的节点信息。也可以直接通过打开gemini 或者 claude 的页面,然后在连接里看看是不是通过这个分组访问的。

额外设置:浏览器层面禁用 QUIC

实际使用中,建议关掉浏览器的 QUIC,不然可能还是会漏到机场的IP去。尤其是使用 Claude 的 桌面客户端,这个我尝试了,没能解决。用Antigravity,Claude code,codex 没这个问题。

Chrome / Edge:

  1. 地址栏输入 chrome://flags
  2. 搜索 QUIC
  3. 找到 Experimental QUIC protocol
  4. 改成 Disabled
  5. 重启浏览器

Firefox:

  1. 地址栏 about:config
  2. 搜 network.http.http3.enable
  3. 改成 false

常见问题

脚本保存了,但没有看到 IPRoyal 节点

先检查脚本有没有启用。

再检查有没有重新应用配置。有时候你只是保存了脚本,但当前 profile 没重新加载,它不会马上生效。

还有一个可能是 JS 写错了,比如少了逗号、括号没闭合。Clash Verge Rev 一般会报错。

这种就把代码复制出来,先检查一下。

实在不行就问问 AI 吧。

要不要用链式代理

链式代理(机场 → IPRoyal)听起来像是”双保险”,但实际上:

速度肯定更慢,不会更快。链式的总延迟 = 你 → 机场节点 → IPRoyal → Anthropic,多一跳就多一段延迟和带宽瓶颈。机场节点本身往往是瓶颈(共享带宽、QoS 限速),叠加之后只会更卡。

没有意义。你买 IPRoyal 的目的就是拿到一个干净的 ISP 出口 IP 让 Cloudflare 放行。最终命中 Anthropic 的 IP 是 IPRoyal 的,机场那一跳除了消耗你的机场流量、增加延迟之外,没提供任何额外价值。

唯一可能需要链式的场景:你所在的网络环境直连不到 IPRoyal 的入口服务器(比如国内运营商对 IPRoyal 的 endpoint 做了封锁或 QoS)。这种情况下才需要先用机场翻出去,再连 IPRoyal。但 IPRoyal 的入口在国内一般是能直连的,至少能 TCP 连通,先测一下再说。如果是做链式代理的话,就要把 IPRoyal 直接作为节点添加到机场的配置中。

最后

我是觉得 AI 服务其实对IP挺宽容的,我自己测试机场,IP经常是乱飞的,Gemini,Chatgpt,甚至最近开通的 Claude Code 都没有封我。但是一个固定的IP 可以稳定的使用 AI 服务,还是让人舒心的。实际使用中,我觉得 Gemini 没必要用 ISP,随便用机场 IP 都行,但是 Antigravity 用了 ISP 之后就稳定多了, Claude Code也不会报403错误了。

另外,我认为使用eSIM卡加热点可能还是更稳一点吧。

Rate this post
订阅评论
提醒
12 评论
blank
1 月 前

用这种方法一定要开全局代理吗,我发现采用规则代理很卡很卡,只有偶尔可以,是不是需要在clash中添加某些规则呢?

Excel
4 月 前

大佬,现在有什么稳定的机场推荐 现在用的是ssr

Jerry
回复给  Kerry
2 月 前

今天下午glados貌似不太稳定,不知道是不是我免费试用的关系

Jerry
回复给  Kerry
2 月 前

您好,我发现我只是连校园网的时候glados才特别不稳定,只要我连我的手机流量热点就特别好。那就不是glados的问题了。校园网只是可能网速没那么快,但请问呢怎么会这样啊?

aron
4 月 前

辛苦大佬,请问这是否也有助于解决机场不稳定的问题

Kevin
回复给  Kerry
19 天 前

大佬有没有稳定点的机场推荐

12
0
希望看到您的想法,请您发表评论x
标题和URL已复制