Cloudflare通过API更新DNS解析

鉴于目前域名价格上涨,可以在其它平台注册便宜域名,或者首年优惠的域名,然后将DNS更改为Cloudflare的DNS,然后用它的API来自动更新DNS解析记录

生成API token

登录后点击个人头像,进入个人资料页面

通过左边的侧栏选项切换到“API令牌”

点击“创建令牌”,根据模板可以为单独指定服务开通API令牌权限。生成的令牌只会显示一次,记得及时保存。

查询域名信息

步骤

  • [[#查询账号下所有域名信息]], 找出指定域名的ID(zone_identifier)

  • [[#通过域名ID查出该域名下对应的解析记录及ID(identifier)]]

查询账号下所有域名信息

curl --request GET \
  --url https://api.cloudflare.com/client/v4/zones \
  --header 'Content-Type: application/json' \
  --header 'X-Auth-Email: email@address' \ # 账号邮箱地址
  --header "X-Auth-Key: api_token" \ # API令牌(token)

响应结果

{
    "result": [
        {
            "id": "1de9e53f1...23762b6",
            "name": "kaside365.com",
            "status": "active",
            "paused": false,
            "type": "full",
            "development_mode": 0,
            "name_servers": [
                "becky.ns.cloudflare.com",
                "brad.ns.cloudflare.com"
            ],
            "original_name_servers": null,
            "original_registrar": null,
            "original_dnshost": null,
            "modified_on": "2023-06-21T00:44:36.560030Z",
            "created_on": "2023-06-20T09:48:18.575850Z",
            "activated_on": "2023-06-20T09:48:27.150675Z",
            "meta": {
                "step": 4,
                "custom_certificate_quota": 0,
                "page_rule_quota": 3,
                "phishing_detected": false,
                "multiple_railguns_allowed": false
            },
            "owner": {
                "id": null,
                "type": "user",
                "email": null
            },
            "account": {
                "id": "343e21eb9...6854fcd1",
                "name": "Q...t.com's Account"
            },
            "tenant": {
                "id": null,
                "name": null
            },
            "tenant_unit": {
                "id": null
            },
            "permissions": [
                "#access:read",
                "#legal:edit"
            ],
            "plan": {
                "id": "0feeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
                "name": "Free Website",
                "price": 0,
                "currency": "USD",
                "frequency": "",
                "is_subscribed": false,
                "can_subscribe": false,
                "legacy_id": "free",
                "legacy_discount": false,
                "externally_managed": false
            }
        }
    ],
    "result_info": {
        "page": 1,
        "per_page": 20,
        "total_pages": 1,
        "count": 2,
        "total_count": 2
    },
    "success": true,
    "errors": [],
    "messages": []
}
  • "id": "1de9e53f1…23762b6" 相当于是kaside365.com域名的ID,这个值是固定不变的。在下面的查询中,它会变成zone_id,两者是同一个

通过域名ID查出该域名下对应的解析记录及ID(identifier)

https://api.cloudflare.com/client/v4/zones/{identifier}/dns_records
  • identifier: 上一步查出来的“id”值为"1de9e53f1…23762b6" ,也就是kaside365.com域名的ID

curl --request GET \
  --url https://api.cloudflare.com/client/v4/zones/1de9e53f1...23762b6/dns_records \
  --header 'Content-Type: application/json' \
  --header 'X-Auth-Email: [email protected]' \
  --header "X-Auth-Key: 14e79883b.....640926d9" 

响应结果

{
    "result": [
        {
            "id": "63e6ab2...fcdebef4",
            "zone_id": "1de9e53f1...23762b6",
            "zone_name": "kaside365.com",
            "name": "r.kaside365.com",
            "type": "A",
            "content": "113.57.150.15",
            "proxiable": true,
            "proxied": false,
            "ttl": 3600,
            "locked": false,
            "meta": {
                "auto_added": false,
                "managed_by_apps": false,
                "managed_by_argo_tunnel": false,
                "source": "primary"
            },
            "comment": "Domain verification record",
            "tags": [],
            "created_on": "2023-07-26T02:57:58.00706Z",
            "modified_on": "2023-07-26T02:57:58.00706Z"
        }
    ],
    "success": true,
    "errors": [],
    "messages": [],
    "result_info": {
        "page": 1,
        "per_page": 100,
        "count": 1,
        "total_count": 1,
        "total_pages": 1
    }
}
  • id": 这里的"id"不再是域名对应的'id'而是A记录r.kaside365.com 的id,"63e6ab2…dfcdebef4",生成后只要不删除,也不会变

创建新的A记录解析

https://api.cloudflare.com/client/v4/zones/{id}/dns_records
  • id: 就是域名对应的id,值为"1de9e53f1…23762b6"

curl --request POST \
  --url https://api.cloudflare.com/client/v4/zones/1de9e53f1...23762b6/dns_records \
  --header 'Content-Type: application/json' \
  --header 'X-Auth-Email: [email protected]' \
  --header "X-Auth-Key: 14e79883b...3640926d9" \
  --data '{
  "content": "1.1.1.1",
  "name": "ss.kaside365.com",
  "proxied": false,
  "type": "A",
  "comment": "add a new record",
  "ttl": 3600
}'

更新/修改A记录解析

https://api.cloudflare.com/client/v4/zones/{identifier}
  • identifier: 对应A记录的"id",值为63e6a…fcdebef4 ,例如在这里就代表r.kaside365.com这个A记录的ID

curl --request PATCH \
  --url https://api.cloudflare.com/client/v4/zones/1de9e53f1...23762b6/dns_records/63e6a...fcdebef4 \
  --header 'Content-Type: application/json' \
  --header 'X-Auth-Email: [email protected]' \
  --header "X-Auth-Key: 14e79883b...3640926d9" \
  --data '{
  "content": "1.1.1.1",
  "name": "r.kaside365.com",
  "proxied": false,
  "type": "A",
  "comment": "Domain verification record",
  "ttl": 3600
}'

删除A记录解析

https://api.cloudflare.com/client/v4/zones/{zone_id}/dns_records/{id}
  • zone_id: 域名对应的id

  • id: A记录对应的id

curl --request DELETE \
  --url https://api.cloudflare.com/client/v4/zones/1de9e53f1...23762b6/dns_records/63e6a...fcdebef4 \
  --header 'Content-Type: application/json' \
  --header 'X-Auth-Email: [email protected]' \
  --header "X-Auth-Key: 14e79883b...3640926d9"

自动更新脚本

#!/bin/bash

# CHANGE THESE
auth_email="[email protected]"
auth_key="14e79883bd7a3c0xxxxxxxd9" # found in cloudflare account settings
zone_name="domain.com"
record_name="r.domain.com"

# MAYBE CHANGE THESE
ip=$(curl -s http://ipv4.icanhazip.com)
#ip=$(ip address| grep pppoe | grep inet | awk '{print $2}')
ip_file="ip.txt"
id_file="cloudflare.ids"
log_file="cloudflare.log"

# LOGGER
log() {
    if [ "$1" ]; then
        echo -e "[$(date)] - $1" >> $log_file
    fi
}

# SCRIPT START
log "Check Initiated"

if [ -f $ip_file ]; then
    old_ip=$(cat $ip_file)
    if [ "$ip" = "$old_ip" ]; then
        echo "IP has not changed."
        exit 0
    fi
fi

if [ -f $id_file ] && [ "$(wc -l < $id_file)" = "2" ]; then
    zone_identifier=$(head -1 $id_file)
    record_identifier=$(tail -1 $id_file)
else
    zone_identifier=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones?name=$zone_name" -H "X-Auth-Email: $auth_email" -H "X-Auth-Key: $auth_key" -H "Content-Type: application/json" | grep -o '"id":"[^"]*' | cut -d '"' -f 4 | head -1)
    record_identifier=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$zone_identifier/dns_records?name=$record_name" -H "X-Auth-Email: $auth_email" -H "X-Auth-Key: $auth_key" -H "Content-Type: application/json"  | grep -o '"id":"[^"]*' | cut -d '"' -f 4)
    echo "$zone_identifier" > $id_file
    echo "$record_identifier" >> $id_file
fi

update=$(curl --request PATCH --url https://api.cloudflare.com/client/v4/zones/$zone_identifier/dns_records/$record_identifier -H "Content-Type: application/json" -H "X-Auth-Email: $auth_email" -H "X-Auth-Key: $auth_key" --data '{"content": "'"${ip}"'","name": "'"${record_name}"'","proxied": false,"type": "A","ttl": 60}')

if [[ "$update" == *'"success":false'* ]]; then
    message="API UPDATE FAILED. DUMPING RESULTS:\n$update"
    log "$message"
    echo -e "$message"
    exit 1
else
    message="IP changed to: $ip"
    echo "$ip" > $ip_file
    log "$message"
    echo "$message"
fi

最后更新于