OpenWrt中通过自定义脚本为Cloudflare域名更新DDNS

  在上一篇文章中,威联通NAS上myQNAPcloud DDNS获取外网地址不准确的问题,提到使用myQNAPcloud服务来设置DDNS。这次尝试不依赖QNAP的服务,在OpenWrt里定时运行自定义脚本来直接更新域名的DNS地址。

  我的域名托管在Cloudflare上,所以主要思路是定时在OpenWrt里运行脚本检测公网IP地址是否有变化,如果有就用Cloudflare的token和API来更新相关DNS设置。

  记录具体步骤如下:

  1. 获取Cloudflare的API token,稍后脚本中会用到。进入 https://dash.cloudflare.com/profile/api-tokens 页面,Create Token,为了使token权限最小化选择Create Custom Token,设置如下图。Specific zone选项可限制token权限为仅允许更新某一个域名。
  2. 在上面所选域名的DNS设置中,添加一条A记录,设置成DDNS想要绑定的域名。IP地址随意设置比如8.8.8.8(之后脚本会付覆盖),Proxy status设置为DNS only。
  3. OpenWrt运行的脚本。参考了一些网上的脚本,发现 https://raw.githubusercontent.com/K0p1-Git/cloudflare-ddns-updater/main/cloudflare-template.sh 这个脚本比较全面(下载链接),注释也清楚。几点注意事项:
    • 第一行的#!/bin/bash需要修改成#!/bin/sh,否则OpenWrt中没有bash环境无法运行。
    • 要填写的项目有auth_email,auth_key,zone_identifier,record_name,其余可留空。
    • auth_method="token" 注意保持token方式,对应步骤1中创建的API token。同一页面还可看到Cloudflare的Global API Key,因为它可以操作账户里的所有设置,不建议使用。
    • 如果OpenWrt设置了科学上网/透明代理,curl -s -4 https://cloudflare.com/cdn-cgi/trace运行时可能获取到代理服务器的ipv4地址。可以注释掉相关if判断部分,改为用其它API直接获取,即ip=$(curl -s https://api.ipify.org || curl -s https://ipv4.icanhazip.com) 。注:此地址需添加到科学上网的“不走代理域名”列表内,否则全局代理时,访问这些地址获取到的也变成了代理地址。
  4. 用scp命令将修改好的脚本上传到/root目录,chmod +x updateDDNS_cloudflare.sh赋予执行权限。先手动运行一次观察输出是否正常/bin/sh -x updateDDNS_cloudflare.sh。如果脚本运行无误的话,可以在Cloudflare中观察到对应A记录的DNS更新成功。
  5. crontab -e编辑计划任务,添加一行内容*/10 * * * * /root/updateDDNS_cloudflare.sh,这样此脚本会每10分钟运行一次以按需更新DDNS。此步骤也可在OpenWrt网页端的“系统->计划任务”里完成。

  其实同样的工作也可以在OpenWrt的web管理页面上完成,如果你可以在“服务->动态DNS->DDNS 服务提供商 [IPv4]”的设置中找到Cloudflare选项的话。我用的OpenWrt编译了动态DNS的应用(luci-app-ddns, ddns-scripts),但没有Cloudflare的入口点。尝试安装ddns-scripts-cloudflare或更早的ddns-scripts_cloudflare.com-v4_2.7.8-3_all.zip,不仅依然找不到Cloudflare入口点,还有可能破坏掉OpenWrt:实际后台依然运行,可以上网,但web页面(LuCI web interface)报错Bad Gateway The process did not produce any response.,只能借助ESXI里的快照恢复或重新安装OpenWrt。所以才有了这篇博客。

One thought on “OpenWrt中通过自定义脚本为Cloudflare域名更新DDNS”

  1. Pingback: 自动更新 AWS Lightsail 实例的公网 IP 地址并同步到 Cloudflare 的域名 DNS 记录 – 菩提老王的葡萄架

Leave a Comment

Your email address will not be published. Required fields are marked *