所需参数
-
CF_API_TOKEN
: Cloudflare API Token,需具备 Zone.DNS 编辑权限 -
CF_ZONE_ID
: 域名所在 Zone ID -
CF_RECORD_ID
: 需要更新的 DNS 记录 ID -
CF_RECORD_NAME
: 要更新的记录名称,例如 “sub.example.com”
其中RECORD_ID
要通过
curl -s -X GET "https://api.cloudflare.com/client/v4/zones/${CF_ZONE_ID}/dns_records?name=${CF_RECORD_NAME}" -H "Authorization: Bearer ${CF_API_TOKEN}" -H "Content-Type: application/json" | jq -r '.result[0].id'
来获得
IP Provider
ip.sb
ip.3322.net
Script
GPT写的简单脚本:
#!/usr/bin/env bash
# Cloudflare DDNS 更新脚本
# 依赖: curl, jq
# 使用前请设置以下环境变量:
# CF_API_TOKEN: Cloudflare API Token,需具备 Zone.DNS 编辑权限
# CF_ZONE_ID: 域名所在 Zone ID
# CF_RECORD_ID: 需要更新的 DNS 记录 ID
# CF_RECORD_NAME: 要更新的记录名称,例如 "sub.example.com"
# 可选:
# IP_PROVIDER: 获取公网 IP 的接口,默认使用 https://api.ipify.org
# 默认配置
CF_API_TOKEN="xxx"
CF_RECORD_NAME="xxx"
CF_RECORD_ID="xxxx"
CF_ZONE_ID="xxxx"
IP_PROVIDER="ip.3322.net"
CACHE_FILE="/tmp/cloudflare_ddns_last_ip.txt"
# 获取当前公网 IP
current_ip=$(curl --interface eth0 "$IP_PROVIDER")
if [[ -z "$current_ip" ]]; then
echo "无法获取公网 IP,请检查网络或 IP_PROVIDER 设置。"
exit 1
fi
# 获取上一次记录的 IP
if [[ -f "$CACHE_FILE" ]]; then
last_ip=$(cat "$CACHE_FILE")
else
last_ip=""
fi
# 如果 IP 未变化,则退出
if [[ "$current_ip" == "$last_ip" ]]; then
echo "IP 未变化 ($current_ip),无需更新。"
exit 0
fi
echo "检测到 IP 变化: $last_ip -> $current_ip,开始更新 Cloudflare 记录..."
# 构建 JSON 数据
read -r -d '' payload <<EOF
{
"type": "A",
"name": "${CF_RECORD_NAME}",
"content": "${current_ip}",
"ttl": 120,
"proxied": false
}
EOF
# 调用 Cloudflare API 更新 DNS 记录
response=$(curl -s -X PUT \
"https://api.cloudflare.com/client/v4/zones/${CF_ZONE_ID}/dns_records/${CF_RECORD_ID}" \
-H "Authorization: Bearer ${CF_API_TOKEN}" \
-H "Content-Type: application/json" \
--data "$payload")
# 检查更新结果
success=$(echo "$response" | jq -r '.success')
if [[ "$success" == "true" ]]; then
echo "更新成功: ${CF_RECORD_NAME} -> ${current_ip}"
echo "$current_ip" > "$CACHE_FILE"
exit 0
else
echo "更新失败: $(echo "$response" | jq -r '.errors[]?.message')"
exit 1
fi