优雅的使用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

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

    谢谢分享,学习了

  2. 萝卜头

    谢谢,分享学习了

  3. lev1ne

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

  4. LAzySleep

    继续加油哦,争取发表更多优秀帖子

  5. LAzySleep

    又学习到了,写的非常好?

  6. 七年

    瞅瞅瞅瞅,mark一手

  7. seatom

    感谢分享,谢谢楼主,赞

  8. wasd2134

    感谢分享,谢谢楼主

  9. seatom

    继续加油哦,争取发表更多优秀帖子

  10. Shenchong

    学习下,谢谢

  11. slimei

    前来顶贴!

  12. 84896150

    学习中

  13. 幻念

    mark一下。

  14. 科技达人

    学习一下

  15. slimei

    打卡升级

  16. slimei

    先看看,不明白的地方再问

  17. 84896150

    必须点赞

  18. 七年

    打卡升级

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