由于 CNAME 跟任何记录都冲突的特性,在根域(@)下添加 CNAME 记录指向 CDN(或其他服务)会导致 mx(邮箱记录)、TXT(一些站长验证)、DS 等常用记录冲突等且多级 CNAME 会导致解析性能下降等问题,所以拉平是一个很不错的解决方案。但目前 DNSPod 并没有提供拉平的功能,所以需要自己写脚本调用 API 实现。(本文以腾讯云 CDN 为例,但是其他 CDN 服务商也可以使用,替换脚本里面的 CNAME 域名即可。)
PS:自2019年1月接触互联网行业以来一直在做运营相关的工作,本身也不是学计算机相关专业的,代码写的可能不是很好,欢迎大佬们指正。

操作场景

本文将指导您如何使用 DNSPod 的 API 实现拉平 CNAME 记录,以解决相关记录冲突的问题。(以腾讯云 CDN 为例)

前提条件

  • 域名解析托管在腾讯云 DNSPod。
  • 域名已绑定企业版或更高版本套餐。

方法说明

流程图

流程图
实现的方法大体如上图所示,获取 CDN 在31个省份三大运营商的调度结果,然后将调度结果更新到 DNSPod 上。

相关说明

  • 因本人海外访问全部由 Cloudflare 提供服务,且由于服务 IP 基本固定,故本脚本中未考虑海外使用 CDN 的情况,如果 CDN 有海外节点,可以在脚本中自行添加海外 CDN 调度部分。
  • 需要企业版或更高版本套餐的原因是因为从企业版开始才支持分省分运营商解析调度。(或许有时间写个华为云 DNS 的)
  • 考虑 CDN 存在多级 CNAME 的情况,本脚本从 DoH 获取的调度结果第二个 “data” 才开始取值,由于 CDN 每次返回的 IP 数量不一,仅取两个 IP,能满足目前大部分 CDN 的情况,当然不排除有些 CDN 存在多级 CNAME 的情况,这种情况下需要自行修改脚本。
  • 考虑到并非所有人都开启了 IPv6,故本脚本分为 IPv4 和 IPv6 两个版本,您可根据自身情况选择使用。

脚本

GitHub 地址:https://github.com/KincaidYang/CNAMEFlattening
直接下载(IPv4 脚本):https://dl.r2wind.cn/script/DNSPodCDNv4.py
直接下载(IPv6 脚本):https://dl.r2wind.cn/script/DNSPodCDNv6.py

操作步骤

获取脚本

您可直接下载脚本,或者使用 git clone 命令下载本脚本。
直接下载:
IPv4 脚本:

1
wget https://dl.r2wind.cn/script/DNSPodCDNv4.py

IPv6 脚本:

1
wget https://dl.r2wind.cn/script/DNSPodCDNv6.py

使用 git clone 命令:

1
git clone https://github.com/KincaidYang/CNAMEFlattening.git

修改变量配置

打开脚本,修改以下变量:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 配置参数
# domanin替换为自己的域名,如'r2wind.cn'
domain='xxx.cn'
# sub_domain替换为自己的子域名,如'@'或'www'
subdomain='xxx'
# CDNCNAME请替换为CDN提供的CNAME地址,如'r2wind.cn.cdn.dnsv1.com'
CDNCNAME='xxx.xxx.xxx.cn'
# SecretId请替换为自己的腾讯云SecretId,可前往https://console.cloud.tencent.com/cam/capi获取
SecretId='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
# SecretKey请替换为自己的腾讯云SecretKey,可前往https://console.cloud.tencent.com/cam/capi获取
SecretKey='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
# URL为 DNSPod DOH接口地址,用以获取CDN实时解析情况,可自行替换为其他厂商的DoH接口
DoH='https://1.12.12.12/resolve'
# 记录类型("A"为IPv4,"AAAA"为IPv6)
record_type='A'

本站配置示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 配置参数
# domanin替换为自己的域名
domain='r2wind.cn'
# sub_domain替换为自己的子域名
subdomain='@'
# CDNCNAME请替换为CDN提供的CNAME地址
CDNCNAME='r2wind.cn.cdn.qcloudcdn.cn'
# SecretId请替换为自己的腾讯云SecretId
SecretId='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
# SecretKey请替换为自己的腾讯云SecretKey
SecretKey='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
# URL为 DNSPod DOH接口地址,用以获取CDN实时解析情况,可自行替换
DoH='https://1.12.12.12/resolve'
# 记录类型("A"为IPv4,"AAAA"为IPv6)
record_type='A'

说明:
若觉得下方用于 ECS 协议的 IP 子网存在问题,可自行修改。

安装依赖

脚本使用 Python3 运行,故您需要安装 Python3 环境。(一般镜像都会预装 Python3)

1
2
3
4
# CentOS/RHEL
yum install python3
# Debian/Ubuntu
apt install python3

本脚本使用了 requests 库和腾讯云 SDK,故您还需要安装 requests 库和 SDK。

1
2
3
4
# requests 库
pip3 install requests
# 腾讯云 SDK
pip3 install tencentcloud-sdk-python

说明:
某些系统下可能需要将 pip3 替换为 pip。

导入记录

使用前请您前往DNSPod 控制台添加相应记录,否则本脚本将无法正常运行,或参照下述方式导入记录。

下载记录模板

IPv4 模板:https://dl.r2wind.cn/template/DNSPod-IPv4-importtemplate.xls
IPv6 模板:https://dl.r2wind.cn/template/DNSPod-IPv6-importtemplate.xls

说明:
导入前请自行修改模板中的主机记录。(若有需要)
导入前请自行修改模板中的记录值为当前 CDN 节点 IP,否则会影响域名正常访问。(节点 IP 可以通过nslookup查询CDN CNAME地址获取)
若需要导入的记录已在控制台添加过,请删除原有记录后再导入。

导入记录

  1. 登录 DNSPod 控制台,进入批量操作-导入记录页面。
  2. 输入需要导入的域名,上传已经修改好的模板,点击导入
  3. 等待导入完成,请注意查看导入结果,若有导入失败的记录,查看原因修正后手动添加记录,不要重复导入。

调试脚本

请先在本地使用编辑器(如VScode)调试脚本,若调试成功则可继续部署。
若脚本正常运行,您将看到类似如下输出:
{“RecordId”: 1300xxxxxx, “RequestId”: “b690601d-b97f-46fa-a5fb-xxxxxxxxxx”}

[TencentCloudSDKException] code:InvalidParameter.DomainRecordExist message:记录已经存在,无需再次添加

部署运行

脚本使用 cron 定时运行,故您需要安装 cron。

1
2
3
4
# CentOS/RHEL
yum install cronie
# Debian/Ubuntu
apt install cron

安装完成后,您需要编辑 crontab 文件,添加定时任务。

1
crontab -e

在 crontab 文件中添加如下内容:

1
*/5 * * * * python3 /root/DNSPodCDNv4.py

说明:
本配置每 5 分钟运行一次,您可以根据需要自行修改。
请将 /root/DNSPodCDNv4.py 替换为您的脚本路径。
若您使用的是 IPv6 脚本,请将上述内容替换为 */5 * * * * python3 /root/DNSPodCDNv6.py

验证效果

您可以在 DNSPod 控制台查看对应域名的相关记录,若记录值已经更新为 CDN 节点 IP,则说明脚本运行成功。

D 监控

可开启 D 监控配合使用,注意调整监控频率,监控频率应小于更新频率。
注:D 监控仅支持 IPv4。

问题反馈

若您在使用过程中遇到任何问题,欢迎您提交 Issue