Duke Yin's Technology database

本地hosts自动更新Cloudflare解析记录

当本地有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

直到执行后没有报错即可。

脚本的功能:

  1. 当wan口ip发生改变的时候,执行脚本
  2. 使用CloudFlare拉取DNS记录,并写文件到/etc/cloudflare_hosts
  3. 为了防止DDNS有延迟,执行完首次后,延时60秒再执行一次,确保解析,延迟秒数可以在头部参数修改
  4. 日志文件保存在/var/log/cloudflare_hosts.log

查看日志:

cat /var/log/cloudflare_hosts.log

一切正常后,在OpenWRT网络-hosts-额外的hosts处填写

/etc/cloudflare_hosts

作为本地解析,就ok。

# # #

发布评论

评论

标注 * 的为必填项。