TL;DR/省流

⚠️注意: 1. 仅适用于IPv6公网地址 2. 以下命令必须可用: ip curl jq

更新 Cloudflare 解析:

cfddns_v6.sh

#!/bin/bash

# Cloudflare API 配置
ZONE_NAME="example.com"       # 域名
RECORD_NAME="sub.example.com"  # DDNS 记录(即希望用于 DDNS 的域名)
CF_API_TOKEN="YOUR_CF_TOKEN"  # 替换为你的 Cloudflare API 令牌
PREVIOUS_IP=$(cat /tmp/ip_cache || echo '')  # 获得早前的公网IP
CURRENT_IP=$(ip address show end0 dynamic | grep inet6 | awk {'split($2, arr, "/"); print arr[1]'} | head -n 1) # 获取当前公网 IP

if [ "$CURRENT_IP" != "$PREVIOUS_IP" ]; then

    # 获取 Zone ID
    ZONE_ID=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones?name=${ZONE_NAME}" \
            -H "Authorization: Bearer ${CF_API_TOKEN}" \
            -H "Content-Type: application/json" | jq -r '.result[0].id')

    # 获取记录 ID
    RECORD_ID=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records?name=${RECORD_NAME}" \
            -H "Authorization: Bearer ${CF_API_TOKEN}" \
            -H "Content-Type: application/json" | jq -r '.result[0].id')

    # 更新 DNS 记录
    UPDATE=$(curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records/${RECORD_ID}" \
            -H "Authorization: Bearer ${CF_API_TOKEN}" \
            -H "Content-Type: application/json" \
            --data "{\"type\":\"AAAA\",\"name\":\"${RECORD_NAME}\",\"content\":\"${CURRENT_IP}\",\"ttl\":1,\"proxied\":false}")

    echo $CURRENT_IP > /tmp/ip_cache

    if echo "$UPDATE" | grep -q '"success":true'; then
        echo "[$(date)] DNS record updated: ${CURRENT_IP}"
    else
        echo "[$(date)] DNS record update FAILED"
        echo "$UPDATE"
    fi

else
        echo "IP unchanged"
fi

用于执行脚本的 service 文件:

/etc/systemd/system/cloudflare_ddns.service

[Unit]
Description=Update DNS Record when IP Changed
After=network-online.target nss-lookup.target

[Service]
Type=oneshot
ExecStart=/usr/bin/bash SOME_PATH/cfddns_v6.sh

定时执行用的 systemd-timer

/etc/systemd/system/cloudflare_ddns.timer

[Unit]
Description=Check Local IP Every 10 mins

[Timer]
OnActiveSec=1s
OnUnitInactiveSec=10m

[Install]
WantedBy=timers.target

关于脚本

对于实际执行操作的 cfddns_v6.sh 脚本,需要首先在自己的账户申请一个 Cloudflare API 密钥)。脚本会使用密钥请求 Cloudflare 并更新 DNS 纪录,简单的处理 ip address 的结果,并将当前的 IP 写入 /tmp/ip_cache 里。而后每一次开始执行时都先读取上一次存储的 IP ,判断是否有变化,变了就更新纪录。 cloudflare_ddns.timer 中的时间可以自行调整,我设置为每 10 min 一次。 cloudflare_ddns.service 必须设置在网络上线以后,需要添加 After 条件。

在编辑好这些文件,填入正确的路径以后,启用 timer 即可。

systemctl enable cloudflare_ddns.timer

在 Arch Linux 中,使用 systemd 的条件下,仅需要额外安装 jq curl 包。因为 iproute2 包已作为 base 包的依赖项被安装了。

希望对使用 Cloudflare DDNS 的朋友有所帮助。

简易脚本配置 Cloudflare IPv6 DDNS

作者

白音

发布日期

2025 - 06 - 28

许可证

CC BY-NC-SA 4.0