利用 CloudFlare API 实现自动 DDNS 功能|支持IPv4|IPv6

小助手读文章 00:00 / 00:00

不知道什么时候起,宽带变成了 N 级 NAT,花生壳、ORAY、NO-IP 等基于动态公网 IP 的 DDNS 服务全线倒地,虽然 FRPNGROK 这些内网穿透依然可以实现类 DDNS 功能,但网络严重依赖于中转服务器带宽,不是非常适合有大流量需求的业务,比如监控、云盘、同步等等。

最近发现本地宽带终于支持 IPv6 了,DDNS 就又可以搞起来了,考虑到安全问题,本文将探讨使用 CloudFlare API 来实现 DDNS 功能。

对了,DDNS 是指动态 DNS(英语:Dynamic DNS)是域名系统(DNS)中的一种自动更新名称服务器(Name Server)内容的技术,根据互联网的域名订立规则,域名必须有固定的 IP 地址,动态 DNS 系统就是为动态 IP 提供一个固定的名称服务器(Name Server),通过即时更新,使外界用户能够连上使用动态 IP 用户的网址。

一、思路

虽然现在上了 IPv6,可以直接与外界通信,但仍然不是静态 IP,即重新拨号或重新联网后,IP 会发生变更,根据 DDNS 原理,可以通过实时监测公网 IP,判断是否发生变更,一旦监测到发生变更,则立即更新 DNS 记录。

二、实现

CloudFlare 以前就有介绍过,是一家功能十分强大的电信服务提供商,今天我们就是通过其 DNS 管理和 API 功能来实现上述思路。

1、SHELL 脚本代码

#!/bin/bash

###############  授权信息(需修改成你自己的) ################ 
# CloudFlare 注册邮箱
auth_email="[email protected]" 
# CloudFlare Global API Key,下一节会说到
auth_key="123456789"  
# 做 DDNS 的根域名
zone_name="vircloud.net" 
# 做 DDNS 的域名,创建成功后就是通过该域名访问内网资源
record_name="www.vircloud.net"

######################  修改配置信息 ####################### 
# 域名类型,IPv4 为 A,IPv6 则是 AAAA
record_type="AAAA"
# IPv6 检测服务
ip=$(curl -s https://ipv6.vircloud.net)
# IPv4 检测服务
#ip=$(curl -s https://ipv4.vircloud.net)
# 变动前的公网 IP 保存位置
ip_file="ip.txt"
# 域名识别信息保存位置
id_file="cloudflare.ids"
# 监测日志保存位置
log_file="cloudflare.log"

######################  监测日志格式 ######################## 
log() {
    if [ "$1" ]; then
        echo -e "[$(date)] - $1" >> $log_file
    fi
}
log "Check Initiated"

######################  判断 IP 是否变化 #################### 
if [ -f $ip_file ]; then
    old_ip=$(cat $ip_file)
    if [ "$ip" == "$old_ip" ]; then
        echo "IP has not changed."
        exit 0
    fi
fi

######################  获取域名及授权 ###################### 
if [ -f $id_file ] && [ $(wc -l $id_file | cut -d " " -f 1) == 2 ]; then
    zone_identifier=$(head -1 $id_file)
    record_identifier=$(tail -1 $id_file)
else
    zone_identifier=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones?name=$zone_name" -H "X-Auth-Email: $auth_email" -H "X-Auth-Key: $auth_key" -H "Content-Type: application/json" | grep -Po '(?<="id":")[^"]*' | head -1 )
    record_identifier=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$zone_identifier/dns_records?name=$record_name&type=$record_type" -H "X-Auth-Email: $auth_email" -H "X-Auth-Key: $auth_key" -H "Content-Type: application/json"  | grep -Po '(?<="id":")[^"]*')
    echo "$zone_identifier" > $id_file
    echo "$record_identifier" >> $id_file
fi

######################  更新 DNS 记录 ###################### 
update=$(curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$zone_identifier/dns_records/$record_identifier" -H "X-Auth-Email: $auth_email" -H "X-Auth-Key: $auth_key" -H "Content-Type: application/json" --data "{\"id\":\"$zone_identifier\",\"type\":\"$record_type\",\"name\":\"$record_name\",\"content\":\"$ip\"}")

#########################  更新反馈 ######################### 
if [[ $update == *"\"success\":false"* ]]; then
    message="API UPDATE FAILED. DUMPING RESULTS:\n$update"
    log "$message"
    echo -e "$message"
    exit 1 
else
    message="IP changed to: $ip"
    echo "$ip" > $ip_file
    log "$message"
    echo "$message"
fi

2、获取授权信息

使用 CloudFlare "DDNS 服务" 需要把域名托管到 CloudFlare,此处不做介绍,自行搜索。
DNS 页面,由于我们要达到的是 DDNS 效果,所以 CDN 不要开启,即这朵云保持灰色状态(默认是开启的):

DNS Records.png

其中 Type 是你要设置的 IP 类型,Name 是要做为连接的域名, Value 第一次可以随便设一个,TTL 2 minutes 或者 Automatic 都可以,再次强调 Status 这朵云不要点亮。

个人信息页面 下滑到 API Keys,把 Global API Key 一串字符贴到上述脚本中的 auth_key:

API Keys.png

3、执行结果

~# chmod +x ddns.sh 
~# ./ddns.sh
IP changed to: ****
~# ./ddns.sh 
IP has not changed.

4、定时运行

由于无法得知运营商什么时候会把 IP 变了,所以我们可以设置定时运行脚本来实现实时监控 并更新 IP 的变化。比如通过 crontab 实现:

~# crontab -e
......
0 */1 * * *  /root/ddns.sh >/dev/null 2>&1
......

可以通过 cloudflare.log 来查看历史执行记录。

5、错误分析

问题

~# ./ddns.sh 
API UPDATE FAILED. DUMPING RESULTS:
{"success":false,"errors":[{"code":6007,"message":"Malformed JSON in request body"}],"messages":[],"result":null}

分析

猜测是网络原因引起的,概率出现这个提示,如若出现忽略再执行一次即可。

三、总结

自己搭建 DDNS 最大的好处在于可以充分发挥宽带的带宽,不再局限于服务端的限制,其次安全性有了保证,可以不受服务提供者的记录。

其实并不仅仅 CloudFlare 可以实现,其他支持 API 更新 DNS 的 DNS 服务商理论上都支持通过上面的方法来实现 DDNS,而且从网络大环境而言,国内的服务商肯定会比国外的稳定。

文中 IP 检测工具是真实有效的,大家都可以引用,但是请合理使用(建议 30 分钟检测一次即可),因为最近发现服务器负载过大,查了一下日志,好几个 IP 一天几万次请求,显然已经超过正常合理使用范畴,为保证服务可用,目前已经屏蔽这些 IP。

参考文章:

1、 《利用CloudFlare设置Dynamic DNS(DDNS)获取动态IP
2、 《GitHub: benkulbertis/cloudflare-update-record.sh
3、 《CloudFlare API Documentation


ArmxMod for Typecho
个性化、自适应、功能强大的响应式主题

推广

 继续浏览关于 cloudflareipv6ddnsapi 的文章

 本文最后更新于 2019/06/04 17:10:46,可能因经年累月而与现状有所差异

 引用转载请注明:VirCloud's Blog > 运维 > 利用 CloudFlare API 实现自动 DDNS 功能|支持IPv4|IPv6

精选评论

  1. Kelcoin

    支持一次修改多个域名吗

    1. 欧文斯

      重复以下命令就好啦

  2. xus

    google amp打开你的网站会触发到防盗链

    1. 欧文斯

      发现了,暂时没想到怎么解决