所需参数

  • 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