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

tengxunyun cera

不知道什么时候起,宽带变成了 N 级 NAT,花生壳、ORAY、NO-IP 等基于动态公网 IP 的 DDNS 服务全线倒地,虽然 FRP、NGROK 这些内网穿透依然可以实现类 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=”c2547eb745079dac9320b638f5e225cf483cc5cfdda41″
# 做 DDNS 的根域名
zone_name=”example.com”
# 做 DDNS 的域名,创建成功后就是通过该域名访问内网资源
record_name=”www.example.com”

###################### 修改配置信息 #######################
#
域名类型,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图 1:DNS Records(图片不显示?)

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

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

API Keys.png图 2:API Keys(图片不显示?)

3、执行结果
~# chmod +x ddns.sh
~# ./ddns.sh
IP changed to: ****
~# ./ddns.sh
IP has not changed.
4、定时运行
由于无法得知运营商什么时候会把 IP 变了,所以我们可以设置定时运行脚本来实现实时监控 并更新 IP 的变化。比如通过 crontab 实现:

~# crontab -e
……
*/10 * * * * /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,而且从网络大环境而言,国内的服务商肯定会比国外的稳定。

cera aliyun tengxunyun cloudiplc

相关推荐

国内利用Gitee|加速访问GitHub仓库|完全免费

我们在开发和#部署#项目的时候,经常需要从GitHub上Pull一些开源的项目啥的!国外的#服务器#还好,但是国内的服务器就比较苦恼了!要不就是#无法访问#,要不就是速度超级慢! 比如昨天我想给#vim#工具安装一下#golang#的插件!看看这clone的速度!     于是乎我就想起来了Gitee!利用它为GitHub仓库加速一下!加速后的效果~ 还是非常不错啦! PS:由于是新建的仓库第一次访问,后来再访问速度更快了!     关于Gitee OSCHINA 推出的#代码#托管·协作开发平台,开发者超过 500 万,托管项目超过 1000 万,汇聚几乎所有本土原创开源项目,并于 2016 年推出企业版,提供企业级代码托管服务,成为开发领域领先的 SaaS 服务提供商。 支持 #Git# / SVN,个人版免费#5G#仓库容量。 操作流程 1)登陆#Gitee#账号,然后新建仓库 – 【 从 GitHub / GitLab 导入仓库】或者【点击这里】 2)填写要导入的项目即可(如果之前有人导入过该仓库,可以直接复用他的仓库即可)。   3)然后就可以使用Gitee仓库了!   其他说明 Gitee支持WebIDE。 可手动从GitHub更新仓库内容。 同步的仓库不仅仅是#代码#,还有提交记录,分支,#标签#等,全部复制过来。 本文借鉴:如有

使用cf免费版的firewall|设置按国家屏蔽等功能

似乎很多mjj不知道#cf#免费版按国家屏蔽的办法 其实使用#firewall rules#是可以帮助我们达成这个目的的。特别适用于已经使用了cf的站 首先,选择firewall;点击按钮创建规则 第二步,编辑这个规则 也就是,如果符合下面的表达,就把他干action这件事 这个图中,如果访问的请求:来自的county  等于(equal)  china  ,就block(屏蔽)掉 这是今天看见的另一帖里做外贸的mjj要求的效果 注意这里面and 和 or 的逻辑关系 举例1:禁止非中美的IP访问 如果一个请求,符合(不来自中国 and 不来自美国),就屏蔽掉 注意,不能把举例1的规则写成(不来自中国 or 不来自美国),这样会屏蔽掉所有的请求 假设一个来自日本的请求,符合不来自中国,也符合不来自美国,那么()里的内容为真,就会触动规则 假设一个来自#美国#的请求,符合不来自中国,但不符合不来自美国,那么(true and false)的结果是false,不会触动规则 也可以干很多其他或者复杂的事情,因为规则很多。operator中有:等于(eq);不等于(neq);包含(contains);不包含等等 而且操作域(field)也有很多可以选择的,包括uri,ua,county,ip之类的 举例2,自用的规则:禁止非中美访问可能的wp后台

GoIndex|利用Google Drive不限容量|创建自己的国内可访问不限容量网盘;并在线看视频;获取文件直链

一、GoIndex功能 部署在 CloudFlare Workers的小程序。 可以将 Google Drive 文件以目录形式列出,并直连下载。 流量走 CloudFlare ,网速由 CloudFlare 决定。 限制: wokers一天10万请求限制 google drive 下载10T/24h(大佬说的) google api 调用限制 二、搭建GoIndex (一)安装部署方案1 1、在本地安装 rclone 2、按照 https://rclone.org/drive/ 流程进行授权。 a、安装依赖 yum -y install unzip fuse fuse-devel b、安装rclone curl https://rclone.org/install.sh | sudo bash c、 Google Drive授权 ./rclone config 输入 n ,新建挂载,选择Google Drive,按要求填写 d、复制上面的链接,到浏览器打开,获取Google Drive授权码 3、执行 rclone config file 查看 …

纯代码为WordPress站点添加倒计时功能

久伴觉得这个教程很实用,特别是发布某些活动,是活动肯定有截止日期,所以博客在发布活动类型的文章底部添加一个活动结束倒计时还是不错的-本文来源:boke112导航 纯代码添加倒计时到 WordPress 1、把下面的代码保存为 countdownjs.js,保存在当前所使用主题的 js/目录里: function getAdd(time){ if(time<10){ return “0”+time; }else{ return time; } } var interval = 1000; function ShowCountDown(year,month,day,hourd,minuted){ var now = new Date(); var endDate = new Date(year, month–1, day, hourd, minuted); var leftTime = endDate.getTime() – now.getTime(); var leftsecond = parseInt(leftTime/1000); var day = Math.floor(leftsecond/(60*60*24)); day = day < 0 ? …

微信扫一扫,分享到朋友圈

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