XIU2 / CloudflareSpeedTest

🌩「自选优选 IP」测试 Cloudflare CDN 延迟和速度,获取最快 IP !当然也支持其他 CDN / 网站 IP ~
GNU General Public License v3.0
19.86k stars 3.92k forks source link

自动更新 Cloudflare 中的域名解析记录为最快 IP(Windows/Linux 脚本+手动教程) #40

Closed XIU2 closed 3 years ago

XIU2 commented 3 years ago

如果你的域名托管在 Cloudflare,那么其实可以通过 Cloudflare 官方提供的 API 去更新域名解析记录。

写完才反应过来受众面比较窄,不过可以用于 Cloudflare Workers 的自选 IP~

Cloudflare Workers 自选 IP 很简单,只要在添加域名解析时,不要开启橙色云朵,而解析 IP 填写为任意 CF CDN IP 即可。



# 操作步骤观看顺序:

  1. [x] 获取 API 令牌
  2. [x] 准备依赖
  3. [x] 获取域名 ID
  4. [x] 获取域名解析记录 ID
  5. [x] 更新域名解析记录
  6. [x] 自动更新脚本
  7. [x] 定时任务

因为我没有 MacOS 设备,所以没有写相关教程,但查了下 MacOS 已经内置了 cURL,而命令是相通的,和 Linux 差不多。


如果看不到图片,只需把下面这条内容添加到 C:\Windows\System32\drivers\etc\hosts 文件中并重启浏览器:

151.101.88.133 user-images.githubusercontent.com
XIU2 commented 3 years ago

获取 API 令牌

任何 API 操作都需要提供账号邮箱和 API 令牌用来验证身份。

  1. 前往 Cloudflare API 令牌页面。
  2. 点击 Global API Key 后面的 [查看] 按钮。
  3. 输入 Cloudflare 账号的密码,并通过人机验证。
  4. 点击复制 API 令牌并保存好。

XIU2 commented 3 years ago

# 准备依赖

我比较习惯用 cURL 来 POST 提交数据,所以以下用的都是 cURL 命令。

## Linux 系统

虽然大部分的 Linux 系统都自带了 cURL,但是还是提前检查一下是否已安装:

curl --help

如果提示没找到命令,那么就需要手动安装了:

# CentOS 系统
yum install -y curl

# Debian/Ubuntu 系统
apt-get install -y curl

## Windows 系统

为了方便,我在 Windows 系统上也用的是 cURL,下载(32位 / 64位)并解压到任意位置。

考虑到很多人可能不会设置环境变量,那下面的 cURL 命令中就直接用绝对路径好了。

如果你会设置环境变量,那么将 cURL 加入环境变量后,就可以把下面的 cURL 命令中的绝对路径改成 curl 即可了。

解压 cURL 压缩包后,进入 curl\bin 文件夹看到 curl.exe 文件,这时候在地址栏复制当前文件夹路径,并替换下面 cURL 示例命令中的 D:\Program Files\curl\bin\curl.exe 路径。

XIU2 commented 3 years ago

# 获取域名 ID

域名 ID 指的是你在 Cloudflare 中托管一级/顶级域名的 ID(如 xxx.yyy,而不是子域名)。

注意:以下的命令都是一个整体,修改后要一起粘贴、运行\^ 符号是命令分行用的,这样写方便大家理解。

## Linux 系统

curl -X GET "https://api.cloudflare.com/client/v4/zones" \
-H "X-Auth-Email: 账号邮箱" \
-H "X-Auth-Key: 前面获取的 API 令牌" \
-H "Content-Type: application/json"

## Windows 系统

"D:\Program Files\curl\bin\curl.exe" -X GET "https://api.cloudflare.com/client/v4/zones" ^
-H "X-Auth-Email: 账号邮箱" ^
-H "X-Auth-Key: 前面获取的 API 令牌" ^
-H "Content-Type: application/json"

# 查找域名 ID

运行命令后,会输出一大串 JSON 内容,因为没有经过格式化,所以看起毫无可读性,可以随便找个在线 JSON 格式化网站,复制 JSON 内容到左边输入框中即可在右边看到格式化后的 JSON 内容,然后找到以下内容

注意:复制 JSON 内容去格式化的时候,别复制错了,JSON 是以 { 开头,以 } 结尾的。

"id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"name": "yyy.zzz",
"status": "active",
id 域名 ID
name 托管在 Cloudflare 的(顶级/一级)域名

保存好这个域名 ID,后面还需要用到。

XIU2 commented 3 years ago

# 获取域名解析记录 ID

域名解析记录 ID 指的是域名解析的完整子域名的 ID(完整子域名如 xxx.yyy.zzz,而不是 yyy.zzz)。

注意:以下的命令都是一个整体,修改后要一起粘贴、运行\^ 符号是命令分行用的,这样写方便大家理解。

## Linux 系统

curl -X GET "https://api.cloudflare.com/client/v4/zones/域名ID/dns_records?page=1&per_page=20&order=type&direction=asc" \
-H "X-Auth-Email: 账号邮箱" \
-H "X-Auth-Key: 前面获取的 API 令牌" \
-H "Content-Type: application/json"

## Windows 系统

"D:\Program Files\curl\bin\curl.exe" -X GET "https://api.cloudflare.com/client/v4/zones/域名ID/dns_records?page=1&per_page=20&order=type&direction=asc" ^
-H "X-Auth-Email: 账号邮箱" ^
-H "X-Auth-Key: 前面获取的 API 令牌" ^
-H "Content-Type: application/json"

# 查找域名的解析记录 ID

运行命令后,会输出一大串 JSON 内容,因为没有经过格式化,所以看起毫无可读性,可以随便找个在线 JSON 格式化网站,复制 JSON 内容到左边输入框中即可在右边看到格式化后的 JSON 内容,然后找到以下内容

注意:复制 JSON 内容去格式化的时候,别复制错了,JSON 是以 { 开头,以 } 结尾的。

"id":"yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy",
"zone_id":"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"zone_name":"yyy.zzz",
"name":"xxx.yyy.zzz",
"type":"A",
"content":"X.X.X.X",
"proxied":true,
"ttl":1,
id 域名解析记录 ID
zone_id 所属的域名 ID
zone_name 所属的(顶级/一级)域名
name 完整(子)域名
type 解析记录类型
content 解析 IP 地址
proxied 是否走 CDN 代理,是:true,否:false
ttl 解析记录生存时间,值为 1 则是自动,单位:秒

保存好这些信息,后面还需要用到。

XIU2 commented 3 years ago

# 更新域名解析记录

即修改指定子域名的解析记录信息。

注意:以下的命令都是一个整体,修改后要一起粘贴、运行\^ 符号是命令分行用的,这样写方便大家理解。

## Linux 系统

curl -X PUT "https://api.cloudflare.com/client/v4/zones/域名ID/dns_records/解析记录ID" \
-H "X-Auth-Email: 账号邮箱" \
-H "X-Auth-Key: 前面获取的 API 令牌" \
-H "Content-Type: application/json" \
--data '{"type":"A","name":"xxx.yyy.zzz","content":"最快 IP","ttl":1,"proxied":true}'

# 如果你只需要更新该域名解析记录中单独 “一个” 信息(上面那个只能同时设置域名解析记录的所有信息),那么可以改成这样:

curl -X PATCH "https://api.cloudflare.com/client/v4/zones/域名ID/dns_records/解析记录ID" \
-H "X-Auth-Email: 账号邮箱" \
-H "X-Auth-Key: 前面获取的 API 令牌" \
-H "Content-Type: application/json" \
--data '{"content":"最快 IP"}'

## Windows 系统

"D:\Program Files\curl\bin\curl.exe" -X PUT "https://api.cloudflare.com/client/v4/zones/域名ID/dns_records/解析记录ID" ^
-H "X-Auth-Email: 账号邮箱" ^
-H "X-Auth-Key: 前面获取的 API 令牌" ^
-H "Content-Type: application/json" ^
--data "{\"type\":\"A\",\"name\":\"xxx.yyy.zzz\",\"content\":\"最快 IP\",\"ttl\":1,\"proxied\":true}"

# 如果你只需要更新该域名解析记录中单独 “一个” 信息(上面那个只能同时设置域名解析记录的所有信息),那么可以改成这样:

"D:\Program Files\curl\bin\curl.exe" -X PATCH "https://api.cloudflare.com/client/v4/zones/域名ID/dns_records/解析记录ID" ^
-H "X-Auth-Email: 账号邮箱" ^
-H "X-Auth-Key: 前面获取的 API 令牌" ^
-H "Content-Type: application/json" ^
--data "{\"content\":\"最快 IP\"}"

# 成功?失败?

运行命令后,会输出的一大串 JSON 内容,在其末尾看到,


# 关于命令中的 JSON 数据说明

指的就是更新解析记录命令中的这段内容:

{"type":"A","name":"xxx.yyy.zzz","content":"最快 IP","ttl":1,"proxied":true}

名称 示例 说明
type A 解析记录类型,如:A, AAAA, CNAME, HTTPS, TXT, SRV, LOC, MX, NS, SPF, CERT, DNSKEY...
name xxx.yyy.zzz 完整的域名,不能只写子域名名称,最长 255 个字符
content 127.0.0.1 解析 IP 地址,IPv4、IPv6
ttl 1 解析记录生存时间,值为 1 则是自动,单位:秒
proxied true 是否走 CDN 代理,是:true,否:false

来自:https://api.cloudflare.com/#dns-records-for-a-zone-update-dns-record

XIU2 commented 3 years ago

# 自动更新脚本

因为时间优先,我就先简单的写了两个脚本,可能比较简陋。。。所以有什么建议可以跟我说。

## Linux 系统

[ 点击展开 查看内容 ] **** 脚本以内置到压缩包内了,只需要赋予其执行权限即可: ``` bash chomd +x cfst_ddns.sh ``` 然后复制以下内容修改后,**一起粘贴运行**,即可生成配置文件 `cfst_ddns.conf` : ``` ini echo -e "FOLDER=/root/CloudflareST ZONE_ID=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx DNS_RECORDS_ID=yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy EMAIL=xxx@yyy.com KEY=zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz TYPE=A NAME=xxx.yyy.zzz TTL=1 PROXIED=true" > cfst_ddns.conf ``` **配置文件说明:** | 变量名 | 值 | ---- | ---- **FOLDER** | CloudflareST 测速程序所在路径 **ZONE_ID** | 域名 ID **DNS_RECORDS_ID** | 域名解析记录 ID **EMAIL** | 账号邮箱 **KEY** | API 令牌 **TYPE** | 解析记录类型 **NAME** | 完整域名 **TTL** | 解析记录生存时间,值为 1 代表自动,单位:秒 **PROXIED** | 是否走 CDN 代理,是:true,否:false 然后运行脚本试试看: ``` bash bash cfst_ddns.sh ``` **** ### \#\# 其他说明 - 以上脚本只是一个示例,大家可以按需修改,比如在 `./CloudflareST` 后面添加其他参数。 - 如果是在**路由器**上面跑该脚本(如 OpenWrt),请先**关闭路由器内的代理**,否则测速结果会不准确。

## Windows 系统

[ 点击展开 查看内容 ] **** 脚本已内置到压缩包内了,只需 **右键脚本 - 编辑**,会看到如下脚本内容: ``` bat @echo off Setlocal Enabledelayedexpansion CloudflareST.exe -p 0 for /f "tokens=1 delims=," %%i in (result.csv) do ( Set /a n+=1 If !n!==2 ( Echo %%i curl -X PUT "https://api.cloudflare.com/client/v4/zones/域名ID/dns_records/域名解析记录ID" ^ -H "X-Auth-Email: 账号邮箱" ^ -H "X-Auth-Key: 前面获取的 API 令牌" ^ -H "Content-Type: application/json" ^ --data "{\"type\":\"A\",\"name\":\"完整域名\",\"content\":\"%%i\",\"ttl\":1,\"proxied\":true}" goto :END ) ) :END pause ``` 修改其中的**域名 ID、域名解析记录 ID、账号邮箱、API 令牌、完整域名**等信息。 最后保存,双击运行脚本试试看。 > **注意**:脚本运行完毕后**窗口不会关闭**,如果你想要脚本定时自动执行,记得先删除脚本最后的 `pause` 命令。 **** ### \#\# 其他说明 - Widnows 脚本加上参数 `-p 0` 是为了避免测速完成后,需要手动回车退出 CloudflareST。 - 以上脚本只是一个示例,大家可以按需修改,比如在 `CloudflareST.exe` 后面添加其他参数。 - 如果你需要**开机自动运行**该脚本,只需要**右键脚本 - 创建快捷方式**,然后将快捷方式移动到 `C:\Users\用户名\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup` 目录下即可。

如果你只需要在测速后获得最快的 IP,那么可以看一下这个 Issues

XIU2 commented 3 years ago

# 定时任务

## Linux 系统

Linux 自然要用 Cron 来定时执行脚本。

[ 点击展开 查看内容 ] **** #### \#\#\# 安装 Cron 一般各 Linux 系统都自带了 Cron,执行 `crontab -l` 命令,如果提示**命令不存在**,说明没有安装,**反之则跳过该步骤**。 ``` bash # 确认你是哪个系统,然后选择对应的命令安装 Cron 程序。 # CentOS 系统: yum install vixie-cron yum install crontabs # Debian/Ubuntu 系统: apt-get install cron ``` #### \#\#\# 配置 Cron 开始编辑定时任务, ``` bash crontab -e ``` 首次使用可能会提示你如下内容: ``` bash # 这就是让你选一个文本编辑器,新手建议用默认的 nano,直接回车即可。 Select an editor. To change later, run 'select-editor'. 1. /bin/nano <---- easiest 2. /usr/bin/vim.basic 3. /usr/bin/vim.tiny 4. /bin/ed ``` 然后就会看到一大片的文本,不用管,那些只是注释(井号 # 开头的都是注释),写的是使用方法。 - 如果你选的是 **nano** 编辑器,那么可以直接开始编辑了。 - 如果你选的是 **vim** 编辑器,则需要按下 **`I 键`** 进入编辑模式。 定时任务格式其实很简单: ``` bash * * * * * cd /xxx && ./cfst_ddns.sh - - - - - | | | | | | | | | +----- 星期中星期几 (0 - 7) (星期天 为0) | | | +---------- 月份 (1 - 12) | | +--------------- 一个月中的第几天 (1 - 31) | +-------------------- 小时 (0 - 23) +------------------------- 分钟 (0 - 59) ``` 还是看不懂?没关系,我直接给你几个示例([脚本下载](https://github.com/XIU2/CloudflareSpeedTest/issues/40#issuecomment-767474313)): ``` bash # 假设脚本位于 /root 目录下(其他位置自己改下面示例),那么: # 每天凌晨 5 点 0 分,执行一次脚本 0 5 * * * cd /root && ./cfst_ddns.sh # 每天凌晨 5 点 30 分,执行一次脚本 30 5 * * * cd /root && ./cfst_ddns.sh # 每 6 个小时(0 分时),执行一次脚本 0 */6 * * * cd /root && ./cfst_ddns.sh # 每小时 0 分,执行一次脚本 0 * * * * cd /root && ./cfst_ddns.sh ``` 写入后,保存定时任务: - **nano**:按下 `Ctrl+X` 键、按下 `Y` 键、按下回车键,即可保存。 - **vim**:按下 `Esc` 键退出编辑模式,直接输入 `:wq` 并回车(英文模式下),即可保存。 这时候再去查看定时任务,看看是否保存成功: ``` bash crontab -l ```

## Windows 系统

Windows 自带了一个任务计划程序,虽然比较简陋,但还能凑活着用。

[ 点击展开 查看内容 ] **** 按下 `Win+R` 键,输入 `taskschd.msc` 回车来打开任务计划程序。 点击右上角的 **[创建基本任务...]** 选项。 输入任务**名称**(随意,必填),描述(可留空),点击 **[下一步]** 继续。 任务触发时间选择 **[每天]**(或其他的),点击 **[下一步]** 继续。 选择开始时间(每日),不用管日期,只需要修改后面的**时间**(即每天这个时间开始运行),点击 **[下一步]** 继续。 选择**启动程序**,点击 **[下一步]** 继续。 点击 **[浏览]** 按钮,选择 `cfst_ddns.bat` 脚本([下载](https://github.com/XIU2/CloudflareSpeedTest/issues/40#issuecomment-767474313)),点击 **[下一步]** 继续。 > 不知道为什么,这里设置**起始于**无效,导致后面还需要改一下脚本才行。。。 确认没什么问题,点击 **[完成]**。 **** 这时候还不能运行该任务,还需要简单修改下 `cfst_ddns.bat` 脚本,**右键脚本 - 编辑**,在脚本第三行插入两行代码: ``` bat D: cd "D:\Program Files\CloudflareST" # 这两行代码的意思是进入 D 盘分区,再进入 CloudflareST 文件夹内 # 所以记得把 D: 改成你的 CloudflareST 所在分区的盘符,例如 C: # 把 D:\Program Files\CloudflareST 改成你电脑上 CloudflareST 所在文件夹路径 ``` 以下是完整脚本示例: ``` bat @echo off Setlocal Enabledelayedexpansion d: cd "D:\Program Files\CloudflareST" CloudflareST.exe -p 0 for /f "tokens=1 delims=," %%i in (result.csv) do ( Set /a n+=1 If !n!==2 ( Echo %%i curl -X PUT "https://api.cloudflare.com/client/v4/zones/域名ID/dns_records/域名解析记录ID" ^ -H "X-Auth-Email: 账号邮箱" ^ -H "X-Auth-Key: 前面获取的 API 令牌" ^ -H "Content-Type: application/json" ^ --data "{\"type\":\"A\",\"name\":\"完整域名\",\"content\":\"%%i\",\"ttl\":1,\"proxied\":true}" goto :END ) ) :END pause ``` 另外,如果你想要每次运行完自动退出,请记得删除脚本末尾的 `pause` 命令。 > 如果你需要**开机自动运行**该脚本,只需要**右键脚本 - 创建快捷方式**,然后将快捷方式移动到 `C:\Users\用户名\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup` 目录下即可。
doutuo commented 3 years ago

这个得出的最快ip,直接就填在域名的A记录里面,然后cdn代理又为真开启。那我域名本身对应的ip,应该是我服务器的ip,这样就没法用了。

XIU2 commented 3 years ago

@doutuo

该教程的目的是更新 Cloudflare 域名解析记录为最快 IP,受众面窄。 你说的情况,是因为该教程不适用于你的需求。


前几天有个人想要在他的路由器上自动运行并更新域名解析记录(V2ray 梯子),我远程协助帮他搞了搞,不过他的域名解析商用的不是 Cloudflare ,正好我有个 Github 文件下载加速网站(将域名解析为最快 IP 可以提高速度),因此我也自己捣鼓过自动更新域名解析记录,干脆就把我自用的脚本改了改写成教程了。

看看有没有人需要,反正这教程受众比较小,闲的没事写着玩。

XIU2 commented 3 years ago

@doutuo 等我稍后写两个自动更新 Hosts 的脚本,应该适用于你的需求了。

XIU2 commented 3 years ago

@doutuo 自动更新 Hosts 的脚本写完了,你可以去试试。

doutuo commented 3 years ago

@doutuo 自动更新 Hosts 的脚本写完了,你可以去试试。

谢谢,辛苦你了!

XIU2 commented 3 years ago

@doutuo 不用谢,用着好用的话,点个 ⭐ 就行了~

getizumo commented 3 years ago

和 @doutuo 有同样的疑问(且没看懂 @XIU2 下面的回复):

如果我的域名 company.domain 已经托管在CF,并开启了CDN,那这时候再修改它A记录的IP不就死循环了吗?

XIU2 commented 3 years ago

@getizumo

这个教程针对的是其他情况,比如:

一开始写这个教程的时候,我没拐过来弯(还想着上两种情况),写完上面那个人一说,才发现这个教程有点鸡肋,受众面太窄了,所以我又写了个自动更新 Hosts 的脚本。

892947707 commented 3 years ago

域名添加到CF的合作伙伴,使用第三方DNS管理解析记录,比如DNSPOD,测出最快IP后只要更新DNSPOD的记录就行了

XIU2 commented 3 years ago

@892947707

在第三方网站用 CNAME 接入 Cloudflare CDN,然后在其他的域名解析网站(如 DNSPOD)去指定自选 IP


但我在 DNSPOD 没有域名(连账号都没注册,因为还要实名验证),而要写 API 相关教程/脚本我必须要亲自测试过才行。

不过网上似乎已经有人写过使用 API 自动更新 DNSPOD 域名解析记录的脚本了。

但是很多是 Python 的脚本,这我不熟,而 Shell 的脚本则太老了。。。

coffeeyuyu commented 3 years ago

You cannot use this API for domains with a .cf, .ga, .gq, .ml, or .tk TLD (top-level domain). To configure the DNS settings for this domain, use the Cloudflare Dashboard

免费的域名,,用不了这个API

vistaspl commented 3 years ago

华为云应该怎样用,给了三个API User Name,Access Key Id,Secret Access Key

XIU2 commented 3 years ago

@vistaspl

你可以看看这个:https://github.com/XIU2/CloudflareSpeedTest/discussions/56

linkala commented 3 years ago

「在第三方网站用 CNAME 接入 Cloudflare CDN,然后在其他的域名解析网站(如 DNSPOD)去指定自选 IP」大佬能否实现自动化脚本,定时去执行直接第三方解析最快的API,小弟可以提供DNSPOD子账号,供大佬测试~

starxing22 commented 3 years ago

这个得出的最快ip,直接就填在域名的A记录里面,然后cdn代理又为真开启。那我域名本身对应的ip,应该是我服务器的ip,这样就没法用了。 cfst_ddns.conf里最后一行PROXIED=true改成PROXIED=false就可以了

beer-on-ice commented 3 years ago

大佬,怎么批量更新啊,有很多cfworkers

XIU2 commented 3 years ago

大佬,怎么批量更新啊,有很多cfworkers

@beer-on-ice 多复制几个脚本中的 curl 代码呗,如果是在同一个根域名下,那么只需要改改域名就行了。

beer-on-ice commented 3 years ago

大佬,怎么批量更新啊,有很多cfworkers

@beer-on-ice 多复制几个脚本中的 curl 代码呗,如果是在同一个根域名下,那么只需要改改域名就行了。

嗯嗯成

jiangbeth commented 1 year ago

Success'':false,errors'':((code'':10000,message'':Authentication error)) 这种如何解决呢,令牌和ID准确无误

2069692020 commented 1 year ago

大佬是否可以解析到阿里云

tvrohd commented 1 year ago

这个有用配合paopao dns,不要太好用,可以直接本地cname,自动更新cname后的那个域名,这样本地的IP也更新了 paopao DNS可以 这样 xxx.com@@@123.xxx.com 自动更新123.xxx.com的ip 就等于更新了xxx.com

aihoom commented 1 year ago

按照步骤来了 但是重定向太多

erdcy commented 1 year ago

Linux自动更新的脚本在哪个压缩包里啊,找了好久没找到