适用场景
家庭宽带用户大多拥有动态公网IP,每次重新拨号后IP就会改变。如果要在家里搭建Web服务、远程桌面或NAS,就需要一个固定的域名来访问——DDNS(动态DNS)应运而生。Cloudflare DNS更新接口允许你通过自己的Cloudflare API Token,将域名下的A或AAAA记录更新为最新IP,实现动态解析。
除此之外,以下场景同样适用:
- 办公室内部服务的外网访问(出口IP可能变化)
- 自建邮件服务器或游戏服务器
- 需要定时同步多个域名的记录
接口能力边界
在接入前,先理解这个接口能做什么、不能做什么:
- 支持的记录类型:仅A(IPv4)和AAAA(IPv6),不处理TXT、CNAME等
- 更新范围:只能更新已有DNS记录,不能新增或删除记录(需先在Cloudflare面板添加占位记录)
- 权限要求:Cloudflare API Token必须拥有对应域名的DNS:Edit权限
- 频率限制:接口QPS为5次/秒,批量更新时需控制并发
- Token安全:接口仅做中间转发,不会持久化Token,但建议调用方仍妥善管理密钥
接口鉴权与请求头
根据官方示例,调用时需要在请求头中携带两个信息:
X-API-Key:用于标识调用者的API密钥(由API平台提供)Content-Type:固定为application/json
另外,接口文档也支持Authorization头,具体使用哪种以平台实际要求为准。本文示例统一使用X-API-Key方式。
你需要在API平台获取专属的API Key(通常称为APIZERO_API_KEY),并在每次请求中传入。
请求参数详解
请求体为JSON对象,字段如下:
| 参数名 | 必填 | 类型 | 说明 | 示例 |
|---|---|---|---|---|
domain | 是 | string | 根域名,如 example.com | "example.com" |
host | 是 | string | 主机记录,可为 @ 或 www | "home" |
ip | 是 | string | 要更新的IP地址;留空则自动获取请求来源IP | "1.2.3.4" |
token | 是 | string | 你的Cloudflare API Token(需DNS:Edit权限) | "YOUR_CF_TOKEN" |
type | 否 | string | 记录类型:A 或 AAAA,默认 A | "AAAA" |
ttl | 否 | number | TTL值,范围120-86400秒,默认120 | 300 |
proxied | 否 | boolean | 是否开启Cloudflare CDN代理,默认 false | true |
关键说明:
ip字段如果传空字符串"",接口会自动使用请求来源的公网IP进行更新。这对家庭宽带场景特别方便。token是你的Cloudflare API Token,不是邮箱密码。Token可以在Cloudflare Dashboard -> My Profile -> API Tokens 中创建,建议分配“DNS:Edit”权限并限定到具体域名。- 如果只更新IPv4,忽略
type字段即可;IPv6需显式传入"AAAA"。
curl接入示例
以下是一个完整的可运行curl命令(请替换占位符):
#!/bin/bash # 请将以下变量替换为实际值 APIZERO_API_KEY="your_api_zero_key_here" CF_TOKEN="your_cloudflare_token_here" DOMAIN="example.com" HOST="home" IP="" # 留空表示使用当前公网IP TYPE="A" TTL=120 PROXIED=false curl -sS -X POST \ -H "X-API-Key: ${APIZERO_API_KEY}" \ -H "Content-Type: application/json" \ -d '{ "domain": "'${DOMAIN}'", "host": "'${HOST}'", "ip": "'${IP}'", "token": "'${CF_TOKEN}'", "type": "'${TYPE}'", "ttl": '${TTL}', "proxied": '${PROXIED}' }' \ "https://v1.apizero.cn/api/cf-dns"如果不想手动填写IP,可直接留空"ip": "",接口会自动检测。
Python 接入示例
import requests import json url = "https://v1.apizero.cn/api/cf-dns" headers = { "X-API-Key": "your_api_zero_key_here", "Content-Type": "application/json" } payload = { "domain": "example.com", "host": "home", "ip": "", # 自动获取 "token": "your_cloudflare_token_here", "type": "A", "ttl": 120, "proxied": False } resp = requests.post(url, headers=headers, json=payload) data = resp.json() print(json.dumps(data, indent=2, ensure_ascii=False))Node.js 接入示例
const axios = require('axios'); const payload = { domain: 'example.com', host: 'home', ip: '', token: 'your_cloudflare_token_here', type: 'A', ttl: 120, proxied: false }; axios.post('https://v1.apizero.cn/api/cf-dns', payload, { headers: { 'X-API-Key': 'your_api_zero_key_here', 'Content-Type': 'application/json' } }).then(res => { console.log(JSON.stringify(res.data, null, 2)); }).catch(err => { console.error(err.response ? err.response.data : err.message); });返回字段解读
成功时HTTP状态码为200,响应JSON格式如下:
{ "code": 0, "data": { "changed": true, "full_name": "home.example.com", "message": "DNS 记录更新成功", "new_ip": "5.6.7.8", "old_ip": "1.2.3.4", "type": "A" }, "msg": "成功" }| 字段 | 类型 | 说明 |
|---|---|---|
code | number | 状态码,0表示成功,非0表示错误 |
msg | string | 状态描述 |
data.changed | boolean | 本次是否实际修改了记录(true/false) |
data.full_name | string | 完整记录名称,如home.example.com |
data.message | string | 操作结果中文描述 |
data.new_ip | string | 更新后的IP |
data.old_ip | string | 更新前的IP |
data.type | string | 记录类型 |
如果changed为false,可能是因为新IP与旧IP相同(无需更新),或Token无权限,或记录不存在。此时message会给出具体原因。
常见错误与排查
1. 认证失败(401)
- 现象:
code非0,msg包含“认证失败”或“Invalid API Key” - 解决:检查
X-API-Key是否正确,是否已过期。可在API平台重新生成。
2. 参数缺失或格式错误(400)
- 现象:
msg提示“参数错误”并列出缺失字段 - 解决:对照参数表确认所有必填字段都已提供,且JSON格式正确。特别注意
token字段不能为空。
3. Cloudflare Token权限不足
- 现象:接口返回成功(code=0),但
changed为false,message包含“权限不足” - 解决:在Cloudflare Token配置页确认已添加DNS:Edit权限,且作用域包含目标域名。
4. 域名或主机记录不存在
- 现象:
code=0,message提示“记录不存在” - 解决:先在Cloudflare DNS面板中手动添加一条占位A记录(IP随意),后续再由接口更新。
5. QPS超限
- 现象:返回HTTP 429 Too Many Requests
- 解决:降低调用频率,或引入重试等待机制(如指数退避)。
工程化注意事项
1. 密钥管理
- 永远不要在代码中硬编码
token和APIZERO_API_KEY。使用环境变量或加密的配置文件。 - 示例:在Linux下设置
export CF_TOKEN="...",然后在脚本中引用$CF_TOKEN。
2. 获取公网IP的脚本片段
如果需要在脚本中自动获取当前公网IP,可以配合以下命令:
# 获取IPv4 WAN_IP=$(curl -s https://api.ipify.org) echo $WAN_IP # 获取IPv6(如果支持) WAN_IP6=$(curl -s https://api6.ipify.org)然后将ip字段设置为获取到的IP,或直接留空让接口自动获取。
3. 定时执行(Crontab)
对于家庭宽带,建议每5分钟执行一次检测。在crontab中添加:
*/5 * * * * /path/to/update_dns.sh >> /var/log/ddns.log 2>&1其中update_dns.sh内包含curl调用逻辑,建议在脚本中加入简单的IP比对:如果IP没有变化,跳过更新以减少API调用。
4. 错误处理与日志
- 将每次请求的返回内容记录到日志文件,方便排查问题
- 使用
-w "\nHTTP_CODE:%{http_code}\n"将HTTP状态码也记录下来 - 对于非200响应,发送告警通知(邮件/钉钉/企业微信)
5. 多域名支持
如果需要更新多个域名,可以编写一个循环或并行脚本来调用,但注意QPS限制为5/s,建议分批执行,每次请求间隔至少200ms。
参考文档
- Cloudflare DNS更新接口文档
- 原始Markdown文档
(如需进一步了解Cloudflare API Token的创建与管理,请参考Cloudflare官方文档。)