splitdns 使用教程:把一个子域名配成「海外走 CF、国内走别的 CDN」

这是 splitdns 的使用教程。原理和纯手动的做法见另一帖:主域名留在 Cloudflare,只把一个子域名委派给 DNSPod 做国内外分流

工具是 Windows / macOS 桌面版,开源(MIT):github.com/woodchen-ink/splitdns,下载见 Releases。不联网上传任何东西,密钥只存在本机,也不监听端口。


它在解决什么

Cloudflare 的权威 DNS 不支持普通记录按地区返回不同答案;而记录一旦是橙云,返回的又是全球一致的 anycast IP。所以「同一个域名,不同地区解析到不同地方」这件事,CF 自己做不到。

唯一的出路是把这一个子域名的权威交给支持线路的 DNS 服务商(这里用 DNSPod),主域名和其它记录仍然留在 CF。但这样一来 CF 就不再管这个名字了,橙云、缓存、WAF 全部失效——于是再用 Cloudflare for SaaS 把其中一条线路带回 CF:它的特点正是「DNS 不在 CF 也能让 CF 代理这个主机名」。

example.com (Cloudflare)
    ├── www / mail / 其它所有记录 ──> 照旧, 完全不受影响
    └── img  NS ──> DNSPod            ← 只有这一条被委派出去
                      │
                      ├── 境内线 ──> CNAME 国内 CDN
                      └── 默认线 ──> CNAME SaaS 区的橙云记录 ──> CF 边缘 ──> 源站

被委派的必须是子域名。域名本身(zone apex)的 NS 由注册商控制,不是 CF 区里能加的记录。

准备三样:主域名在 CF、另一个也在 CF 的域名(做 SaaS 区)、一个 DNSPod 账号。自定义主机名不能和 SaaS 区同名,所以第二个域名是必须的。


第一步 · 凭据

「凭据」页各加一条。密钥保存后不再回显,只能覆盖。

平台 要什么 权限
Cloudflare API Token Zone:ReadDNS:EditSSL and Certificates:Edit;作用范围要同时覆盖父区和 SaaS 区
腾讯云 DNSPod SecretId / SecretKey DNSPod 读写

填完点「检测」。Cloudflare 会把这份 Token 能看到的 zone 全部列出来——Token 有效和权限范围够用是两回事,列表里没有你要用的 zone 就是白搭。


第二步 · 回源

「回源」页登记那些会被多个域名共用的落点,以后换机器只改这一处。只给一个域名用的(比如 EdgeOne 那种一域名一 CNAME),配域名时直接填就行,不必先来这里建。

四个类型里,最容易配反的是前两个:

「CF SaaS 落点」和「CF SaaS 自定义源」的区别

这两个描述的是回源链路上完全不同的两段

用户 ──解析──> [CF SaaS 落点] ──> CF 边缘 ──> [CF SaaS 自定义源] ──> 你的机器
        ↑                                   ↑
     DNS 记录的值                    自定义主机名上的一个字段

CF SaaS 落点 —— 它是 DNS 里那条 CNAME 的值,决定「流量怎么进 CF」。填 SaaS 区里任意一条橙云记录的主机名即可,不必非得是被设为「回退源」的那一条:流量到了 CF 边缘是按 Host 头去找自定义主机名的,CNAME 目标只负责把流量带进这个区。留空则用该区当前的回退源。

CF SaaS 自定义源 —— 它不是解析目标,而是配在 CF 自定义主机名上的 custom_origin_server,决定「流量进了 CF 之后往哪台机器转」。默认所有自定义主机名都回源到该区的回退源;只有当这个域名要走另一台机器时才需要它。

所以:

  • 只是「海外走 CF,回源到默认那台机器」→ 只要落点
  • 「海外走 CF,但这个域名要回源到另一台机器」→ 两个都要:落点把流量带进 CF,自定义源告诉 CF 转给谁

把自定义源填进 DNS 里是个常见错误——CF 根本不认识那个名字,请求进不了你的自定义主机名。

:warning: 用了自定义源还有个坑:源站必须能路由那个 SNI。CF 回源时 Host 头是访问域名,但 TLS 握手用的 SNI 是源服务器名字,源站上的 Traefik / Nginx 匹配不到对应 router 就直接 403——跟证书、跟后端服务都没关系。工具在那一步会给出具体到机器、名字和自检命令的指令。

另外两个类型没什么歧义:第三方 CDN CNAME 填对方给的加速 CNAME,直连源站 IP 就是不过任何 CDN 直接落到 IP。


第三步 · 域名

「域名 → 新增域名」,只有四件事要填:

  • 访问域名——填完父区会自动推导出来(拿它去凭据可见的 zone 里找最长后缀匹配),输入框下面会显示推导结果
  • Cloudflare 凭据DNSPod 凭据——各只有一份时会自动选中
  • SaaS 区——从下拉里选;这条线不走 CF 就选「不使用 CF for SaaS」
  • 线路落点——每条线路指一个落点,可以引用回源库,也可以直接填

:warning: 「默认」线是兜底,务必配上。只配境内 + 境外的话,识别不出归属的解析器会一条记录都拿不到。建议把覆盖面最广的那条挂在「默认」上。

DNSPod 免费版只有 默认 / 境内 / 境外 三条线路,要精确到某个国家得升级套餐。


第四步 · 跟着流程走

保存后自动进入配置流程。每一步下面的按钮:

按钮 含义
自动执行 程序调 API 替你做
我自己做完了 你在 CF / DNSPod 面板里做完后点,等待计时从这一刻开始
确认完成 只出现在程序验不了的步骤(比如源站的 SNI 路由)

不管哪种方式,做完都会重新去三个平台核对一遍。平台接口返回成功不算数,巡检查到真的生效才算完成。所以:

  • 关掉程序隔天回来,进度还在,而且会按当前真实状态重新判定
  • 已经通过的步骤如果线上被人改了,会自动退回「等待生效」并说明差在哪
  • 清理父区旧记录那步会先列出每一条,点确认才动手

等 DNS 或证书生效的步骤会挂在「等待生效」,并写明还差什么、大约要等多久:

清理那一步默认给的是「先迁移到 DNSPod 再删」——被遮蔽不等于该扔,那些记录本来在正常服务,只是委派之后待错了地方。它会逐条判断:接入域名本身只删不搬(落点归线路配置管),其余原样搬走。橙云记录会单独提示,因为搬到 DNSPod 之后就不再经过 CF 了。


几个不看文档就会踩的坑

委派后留在父区的记录会变成 shadowed records。 它们在 CF 面板里看得见,但一条都不生效。排查时最容易被带偏——以为配了,其实没生效。

CF 的验证 TXT 可能是同名多条。 证书带通配符 SAN 时,基础域名和通配符各要一条 DCV,主机记录同名、值不同。少写一条证书就签不出来,而且报错不会告诉你少了哪条。

DNSPod 新加的域名默认是暂停状态。 这时候委派、记录可以全对,解析就是不出结果。工具会自动开启,也会在巡检里单独报出来。

主域名不在同一个腾讯云账号下时,加子域名要先验证归属。 DNSPod 会报 QuhuiTxtNotMatch,要在主域名(还在 CF 那个)上加一条 TXT。工具会自动取值、写进 CF、再重试。

TTL 最低 600。 DNSPod 免费版的下限,填更小会被接口直接拒。


巡检

配完之后,随时可以回来核对三个平台的实际状态。它专门盯这些地方:

  • 父区里被委派遮蔽的记录
  • CF 要的验证 TXT 少没少
  • CF 那条有没有挂在「默认」线兜底
  • DNSPod 上域名是不是还处于暂停状态
  • 委派的 NS 与 DNSPod 实际分配的对不对得上
  • 证书状态、到期时间、自定义源服务器是否与配置一致

上图那条提醒就是前面说的 SNI 那个坑——它会算出要去哪台机器、加哪个名字,并给出自检命令。这一项程序验不了,得你自己确认。

下面「实际状态」和「DNSPod 解析记录」是原样拉回来的现状,出问题时对着看比翻两个控制台快。

存量域名建议也都录进来,出问题时一眼能看到差在哪。


换机器 / 备份

「数据」页可以整库导出和导入。导出的是一致性快照,导入前会自动把现有数据另存一份备份。

导出文件里有明文的平台密钥,当作密钥文件对待,别随手丢共享盘。


下载

Releases · woodchen-ink/splitdns · GitHub

  • Windows 安装版 *-installer.exe —— 数据在 %APPDATA%\splitdns,升级重装不动它
  • Windows 绿色版 *-portable.zip —— 解压即用,数据在 exe 同级 data/,整个文件夹拷走就带走全部配置
  • macOS *-macos-universal.zip —— Intel 与 Apple Silicon 通用,数据在 ~/Library/Application Support/splitdns

macOS 版没做签名公证,首次打开会被 Gatekeeper 拦:右键点 .app → 打开 → 再点一次「打开」,或者 xattr -dr com.apple.quarantine splitdns.app

源码在 github.com/woodchen-ink/splitdns(MIT),Windows 与 macOS 的包都由 GitHub Actions 打 tag 自动构建。