当本地有DDNS服务的时候,有时候IP一变,我们本地没那么及时获取到DNS记录,就会导致很长时间局域网无法通过域名访问本地局域网的服务。
而Cloudflare有API可以读取某个域名的解析记录,是不是可以利用这一点将Cloudflare的域名-IP对应关系拉取到本地,作为hosts文件,帮助我们加速解析呢?
首先你的CloudFlare要创建一个API令牌,权限只允许读取需要的域名。
然后SSH登录OpenWRT主路由,创建一个脚本文件:
/etc/hotplug.d/iface/99-cloudflare-hosts
#!/bin/sh
# ---------------- 配置 ----------------
CF_API_TOKEN="{CF只读权限TOKEN}"
ZONE_ID="{ZONE_ID}"
# 文件路径
HOST_FILE="/etc/cloudflare_hosts"
TMP_FILE="/tmp/cloudflare_hosts.tmp"
LOG_FILE="/var/log/cloudflare_hosts.log"
LAST_IPV6_FILE="/tmp/last_ipv6"
# 接口与延迟配置
DEFAULT_WAN="pppoe-wan" #接口名称需要根据你实际的网络配置来修改
DELAY_SECONDS=60   # 延迟执行时间(秒)
# ---------------- 函数:执行主更新逻辑 ----------------
update_hosts() {
    IPV6=$(ip -6 addr show dev $DEVICE scope global | grep inet6 | awk '{print $2}' | cut -d/ -f1 | head -n1)
    [ -z "$IPV6" ] && echo "[$(date)] 未获取到IPv6地址" >> $LOG_FILE && exit 1
    LAST_IPV6=""
    [ -f $LAST_IPV6_FILE ] && LAST_IPV6=$(cat $LAST_IPV6_FILE)
    if [ "$IPV6" != "$LAST_IPV6" ] || [ "$ACTION" = "manual" ]; then
        echo "[$(date)] 更新 Cloudflare Hosts,当前IPv6: $IPV6"
        echo "$IPV6" > $LAST_IPV6_FILE
        # 获取Cloudflare解析记录
        wget -qO- --header="Authorization: Bearer $CF_API_TOKEN" \
               --header="Content-Type: application/json" \
               "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records" \
        | jq -r '.result[]
           | select((.type=="A" or .type=="AAAA") and (.name|startswith("*")|not))
           | "\(.content) \(.name)"' > $TMP_FILE
        mv $TMP_FILE $HOST_FILE
        /etc/init.d/dnsmasq reload
        LOG_ENTRY="[$(date)] 更新完成 IPv6=$IPV6"
        echo "$LOG_ENTRY" >> $LOG_FILE
        tail -n 50 $LOG_FILE > ${LOG_FILE}.tmp && mv ${LOG_FILE}.tmp $LOG_FILE
    else
        echo "[$(date)] ⚙️ IPv6未变化,跳过更新" >> $LOG_FILE
    fi
}
# ---------------- 初始化变量 ----------------
[ -z "$INTERFACE" ] && INTERFACE="wan"
[ -z "$DEVICE" ] && DEVICE="$DEFAULT_WAN"
[ -z "$ACTION" ] && ACTION="manual"
# ---------------- 执行逻辑 ----------------
if [ "$ACTION" = "manual" ]; then
    # 手动执行立即运行
    update_hosts
else
    # 自动执行(接口事件触发)
    echo "[$(date)] 接口事件触发:$INTERFACE ($ACTION),立即执行并将在${DELAY_SECONDS}s后再次执行" >> $LOG_FILE
    # 立即执行一次
    update_hosts
    # 延迟执行一次(后台执行)
    (
        sleep $DELAY_SECONDS
        update_hosts
    ) &
fi
赋予执行权限:
chmod +x /etc/hotplug.d/iface/99-cloudflare-hosts
创建后手动执行测试:
sh /etc/hotplug.d/iface/99-cloudflare-hosts
如果报错,查看是否因为缺少某些组件,我遇到的是缺少curl,于是安装curl
opkg remove curl
opkg update
opkg install curl libmbedtls12
直到执行后没有报错即可。
脚本的功能:
- 当wan口ip发生改变的时候,执行脚本
 
- 使用CloudFlare拉取DNS记录,并写文件到
/etc/cloudflare_hosts 
- 为了防止DDNS有延迟,执行完首次后,延时60秒再执行一次,确保解析,延迟秒数可以在头部参数修改
 
- 日志文件保存在
/var/log/cloudflare_hosts.log 
查看日志:
cat /var/log/cloudflare_hosts.log
一切正常后,在OpenWRT网络-hosts-额外的hosts处填写
/etc/cloudflare_hosts
作为本地解析,就ok。
                #cloudflare #ddns #openwrt