Cloudflare DDNS 设置

1 背景

家中有台 NAS,但没有静态公网 IP,想要通过公网访问 NAS 和路由管理页面,只能通过 DDNS 来实时上报并修改 Cloudflare 的 DNS 记录,通过仔细阅读相关文档,发现Cloudflare完整支持 DNS 的增删改查,以下简单记录下使用方法:

1.1 列出所有

1
GET zones/:zone_identifier/dns_records
1
2
3
4
curl -X GET "https://api.cloudflare.com/client/v4/zones/023e105f4ecef8ad9ca31a8372d0c353/dns_records?type=A&name=example.com&content=127.0.0.1&page=1&per_page=20&order=type&direction=desc&match=all" \
-H "X-Auth-Email: [email protected]" \
-H "X-Auth-Key: c2547eb745079dac9320b638f5e225cf483cc5cfdda41" \
-H "Content-Type: application/json"

1.2 创建记录

1
POST zones/:zone_identifier/dns_records
1
2
3
4
5
curl -X POST "https://api.cloudflare.com/client/v4/zones/023e105f4ecef8ad9ca31a8372d0c353/dns_records" \
-H "X-Auth-Email: [email protected]" \
-H "X-Auth-Key: c2547eb745079dac9320b638f5e225cf483cc5cfdda41" \
-H "Content-Type: application/json" \
--data '{"type":"A","name":"example.com","content":"127.0.0.1","ttl":120,"priority":10,"proxied":false}'

1.3 获取详情

1
GET zones/:zone_identifier/dns_records/:identifier
1
2
3
4
curl -X GET "https://api.cloudflare.com/client/v4/zones/023e105f4ecef8ad9ca31a8372d0c353/dns_records/372e67954025e0ba6aaa6d586b9e0b59" \
-H "X-Auth-Email: [email protected]" \
-H "X-Auth-Key: c2547eb745079dac9320b638f5e225cf483cc5cfdda41" \
-H "Content-Type: application/json"

1.4 更新记录

1
PUT/PATCH zones/:zone_identifier/dns_records/:identifier
1
2
3
4
5
curl -X PATCH "https://api.cloudflare.com/client/v4/zones/023e105f4ecef8ad9ca31a8372d0c353/dns_records/372e67954025e0ba6aaa6d586b9e0b59" \
-H "X-Auth-Email: [email protected]" \
-H "X-Auth-Key: c2547eb745079dac9320b638f5e225cf483cc5cfdda41" \
-H "Content-Type: application/json" \
--data '{"type":"A","name":"example.com","content":"127.0.0.1","ttl":120,"proxied":false}'

1.5 删除记录

1
DELETE zones/:zone_identifier/dns_records/:identifier
1
2
3
4
curl -X DELETE "https://api.cloudflare.com/client/v4/zones/023e105f4ecef8ad9ca31a8372d0c353/dns_records/372e67954025e0ba6aaa6d586b9e0b59" \
-H "X-Auth-Email: [email protected]" \
-H "X-Auth-Key: c2547eb745079dac9320b638f5e225cf483cc5cfdda41" \
-H "Content-Type: application/json"

2 实战

我们看到,在整个 DNS 修改过程中,请求体是大同小异的,其中主要用到了以下 3 个 key:

  1. zone identifier: 即 Zone ID,可在 Cloudflare 控制台页面的 Overview 页面右下角或 URL 获取
  2. dns records identifier: 通过上述【列出所有】接口的返回结果的 id 获取
  3. X-Auth-Key: 在个人中心的 My Profile -> API Tokens -> Global API Key

这里有一点需要注意:X-Auth-Key 必须使用 Global API Key,但这样导致授权过大,可以在 My Profile -> API Tokens -> API Tokens -> Create Token 创建相应权限的 TOKEN,这里只需要有相应 DNS 的编辑权限即可,相应的,请求时的 header 也要做修改,如

1
2
3
4
curl -X GET "https://api.cloudflare.com/client/v4/zones/023e105f4ecef8ad9ca31a8372d0c353/dns_records" \
-H "X-Auth-Email: [email protected]" \
-H "Authorization: Bearer c2547eb745079dac9320b638f5e225cf483cc5cfdda41" \
-H "Content-Type: application/json"

现在,我们就得到 DDNS 脚本了(使用前请先安装 jq,群辉已自带)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/bin/bash

# Author: Xinyu Shi

zone_identifier=
dns_identifier=
api_token=
domain=
email=

# Get dns record of cloudflare
record=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$zone_identifier/dns_records/$dns_identifier" -H "X-Auth-Email: $email" -H "Authorization: Bearer $api_token" -H "Content-Type: application/json" | jq .result.content)

# Get current ip
ip=$(curl -s whatismyip.akamai.com)

# Edit records only when IP changes
if [ ${record//\"/} != $ip ]; then
curl -s -X PATCH "https://api.cloudflare.com/client/v4/zones/$zone_identifier/dns_records/$dns_identifier" -H "X-Auth-Email: $email" -H "Authorization: Bearer $api_token" -H "Content-Type: application/json" --data '{"type":"A","name":"'$domain'","content":"'$ip'","ttl":1,"proxied":false}'
fi

最后,设置定时任务每分钟执行即可。

因为热爱,所以执着。