优雅的使用shell,定时更新Cloudflare DDNS记录

不用啥编程语言,简单粗暴动态更新居家公网IP到你的Cloudflare,域名访问想想都得劲儿~

在各位激情薅羊毛的同时,一定有这么一批人希望利用自己的本地资源极限白嫖,如果你家里有公网ip,那必然是动态的,因为买得起固定ip当家宽,恐怕也没薅羊毛的必要。


背景

有公网ip,本地的服务器不用啥内网穿透,直接ip加端口方式,或者,自己找一个赏你二级甚至三、四、五级域名的ddns解析服务商下,通过服务商域名+端口的方式在野外传播你的各种优(jī)质(qíng)服(shì)务(pín),但是苦于没有自定义的一(zhuāng)级(bī)域名用着舒心。同时又想不暴露自己的内网服务器,ip伪装一下,不要太容易被人看穿,还不要钱?一想到能有这种闷骚的操作,是不是很爽啊?

需求

  • 一级域名+端口方式访问内网服务
  • 域名返回ip并非内网服务ip
  • 域名方式直接访问(不在本文解释范围,原理就是内网穿透,站内搜索一大把)
  • 内地内穿且同时开启Cloudflare代理502问题(不在本文解释范围,看情况再另起一篇吧)

干货

废话不多说,直接上货,注释写得很清楚了,还是多动动眼睛和手吧各位......

#!/bin/bash

auth_email=""                                     # 用于登录https://dash.cloudflare.com的邮箱
auth_method="token"                                            # Api Key类型"global"或"token"其中一种
auth_key=""            # Api Key
zone_identifier=""             # 域名概览页(Overview)找到区域id(Zone ID)
record_name="sub.heheda.io"                                 # 需要更新的域名A记录+根域名全称,比如要更新domain.com的sub子域名,就完整填入,即record_name="sub.domain.com"
ttl="60"                                                       # DNS TTL (单位秒,最低60)
proxy=false                                                    # 是否通过Cloudflare代理
tgChatId="123123"                                           # tgChatId
tgBotToken="123123:eynfisgbbkvfangc"    # tgBotToken
tgurl=""                 # tgurl,不需要tg推送更新情况的话,此处留空即可,需要则填"https://api.telegram.org/bot${tgBotToken}/sendMessage"

###########################################
## 推送
###########################################
sendnotify() {
    if [[ $tgurl != "" ]]; then
        notify=$(curl -s -X POST $tgurl -d chat_id=${tgChatId} -d text="${message}")
        case "$notify" in
        *"\"success\":false"*)
            printf "Telegram推送失败。\n"
            exit 1
            ;;
        *)
            printf "Telegram推送成功。\n"
            exit 0
            ;;
        esac
    fi
    printf "未开启Telegram推送功能。\n"
}

###########################################
## 检测公网IP(如果你的环境有做科学上网,请注意选择下面适合自己的ip获取域名)
###########################################
ip=$(curl -s https://api.ipify.org || curl -s https://ipv4.icanhazip.com/ || curl -s http://members.3322.org/dyndns/getip)

if [ "${ip}" == "" ]; then
    printf "DDNS 更新助手:公网IP获取失败\n"
    message="DDNS 更新助手:公网IP获取失败"
    sendnotify
    exit 1
fi

###########################################
## 检查api_key类型
###########################################
if [ "${auth_method}" == "global" ]; then
    auth_header="X-Auth-Key:"
else
    auth_header="Authorization: Bearer"
fi

###########################################
## 查找A记录是否存在
###########################################

printf "DDNS 更新助手: 检查开始...\n"
record=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$zone_identifier/dns_records?type=A&name=$record_name" \
    -H "X-Auth-Email: $auth_email" \
    -H "$auth_header $auth_key" \
    -H "Content-Type: application/json")

if [[ $record == *"\"count\":0"* ]]; then
    printf "DDNS 更新助手:${record_name} 记录不存在,请先手动创建一次 ${record_name} 记录\n"
    message="DDNS 更新助手:${record_name} 记录不存在,请先手动创建一次 ${record_name} 记录"
    sendnotify
    exit 1
fi

###########################################
## 获取已存在的IP
###########################################
old_ip=$(echo "$record" | sed -E 's/.*"content":"(([0-9]{1,3}\.){3}[0-9]{1,3})".*/\1/')
# Compare if they're the same
if [[ $ip == $old_ip ]]; then
    printf "DDNS 更新助手: ${record_name} 记录IP - ${ip}未发生变动\n"
##如果自己设置的定时比较频繁,比如10分钟或者半小时更新一次,建议删除下面两行
##删除起点
    message="DDNS 更新助手: ${record_name} 记录IP - ${ip}未发生变动"
    sendnotify
##删除终点
    exit 0
fi

###########################################
## 匹配record id
###########################################
record_identifier=$(echo "$record" | sed -E 's/.*"id":"(\w+)".*/\1/')

###########################################
## 更新IP
###########################################
update=$(curl -s -X PATCH "https://api.cloudflare.com/client/v4/zones/$zone_identifier/dns_records/$record_identifier" \
    -H "X-Auth-Email: $auth_email" \
    -H "$auth_header $auth_key" \
    -H "Content-Type: application/json" \
    --data "{\"type\":\"A\",\"name\":\"$record_name\",\"content\":\"$ip\",\"ttl\":\"$ttl\",\"proxied\":${proxy}}")

###########################################
## 最终状态反馈
###########################################
case "$update" in
*"\"success\":false"*)
    printf "DDNS 更新助手:DDNS记录$record_name更新失败,详细信息:\n$update\n"
    message="DDNS 更新助手:DDNS记录$record_name更新失败,请手动查看日志。"
    sendnotify
    exit 1
    ;;
*)
    printf "DDNS 更新助手: DDNS 已更新,$record_name - $ip。\n"
    message="DDNS 更新助手:DDNS记录更新成功,当前$record_name的新IP地址为:$ip。"
    sendnotify
    exit 0
    ;;
esac

最后,复制以上代码,新建名为“cloudflare.sh”(举个例子,名字随意,最终以sh结尾即可)的文件粘贴进去并保存,放置到你喜欢的位置,然后添加cron定时任务即可

-> 加入科技玩家交流群组:点击加入 <-
注意:
1.文中二维码和链接可能带有邀请性质,请各位玩家自行抉择。
2.请勿通过链接填写qq号与密码、银行卡号与密码等个人隐私信息。
3.禁止纯拉人头,拉app注册等信息,发现必小黑屋。
4.同一种信息仅发一次,多发会被删除。
5.文章中源码或APP等,无法保证其绝对安全,需自行辨别。
6.文章关联方不想展示也可以微信站长“socutesheep”删除。
本文由 @Ciel 发布。如若转载,请注明出处: 科技玩家 » 优雅的使用shell,定时更新Cloudflare DDNS记录

给TA买糖
共{{data.count}}人
人已买糖
教程玩家投稿

清爽无广告—Adguardhome应用篇(12月5日更新IPv6远程访问爱快-群晖docker)

2021-12-2 22:04:20

教程玩家投稿

cloudflare cdn加速 隐藏IP 域名修改dns(免备案 免实名 )-12月3日更新

2021-12-3 13:02:39

58 条回复 A文章作者 M管理员
贴心提醒
请认真对待作者付出,勿发表无意义言论,触发过滤规则的评论将无法提交,包含敏感词的评论会自动变成待审核状态哦。
  1. 这把看我表演

    谢谢分享,学习了

  2. 萝卜头

    谢谢,分享学习了

  3. lev1ne

    想问下有没有能直接域名不加端口访问家宽的指定端口的方法呢?

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索