logo NodeSeekbeta

写了个cf-ddns脚本,增加IPv6/128自动更新功能

巨人的肩膀:https://github.com/yulewang/cloudflare-api-v4-ddns


ddns一般就是NAT小鸡使用,定期把IP更新到域名上,因为商家给的域名有时不好使
另外增加了一个小功能,如果VPS给了一个IPv6的地址块,如/64,使用 -c 参数可以根据给定的前缀,给eth0网络接口添加一个/128的随机地址,每次启动脚本都会更新。作用嘛,也许能增加点直连防封的概率吧,我还没被封过 ac01

另外感谢纱版 @Just纱世里 的IPv6科普帖,学习完之后我也会玩IPv6了 xhj008


#!/usr/bin/env bash

# 原理:
# 通过 CFZONE_ID 和 CFRECORD_NAME 获取 CFRECORD_ID,然后使用CF的API修改dns
# -c 参数可以给eth0添加一个/128的IPv6

# crontab:
# 0 * * * * /path/cf-ddns.sh # 每小时更新一次ddns
# 0 * * * * /path/cf-ddns.sh -c # 每小时换一个IPv6/128并更新ddns

# 参考:
# https://github.com/yulewang/cloudflare-api-v4-ddns

# API Token,需要ZONE.DNS.EDIT权限
CFTOKEN="xxxxxxxx"
# Zone ID,在根域名Overview的右下角
CFZONE_ID="xxxxxxxx"
# 二级域名
CFRECORD_NAME="ddns.example.com"
# A:IPv4,AAAA:IPv6
CFRECORD_TYPE="A"
# 120 - 86400s
CFTTL="120"

# IPv6前缀
IPv6_PREFIX="1234:5678:9012"
# 网络接口,默认eth0
INTERFACE="eth0"

# 在$HOME文件夹下维护一个记录文件 .ddns.dat,格式如下:
# OLD_IPv6: 上一次添加的IPv6/128
# OLD_WANIP: 上一次获取的公网IP
# CFRECORD_ID: 一次获取之后复用
DDNS_FILE="$HOME/.ddns.dat"
if [ -f $DDNS_FILE ]; then
  OLD_IPv6=$(awk 'NR==1' $DDNS_FILE)
  OLD_WANIP=$(awk 'NR==2' $DDNS_FILE)
  CFRECORD_ID=$(awk 'NR==3' $DDNS_FILE)
else
  echo "No database, created already."
  cat > $DDNS_FILE <<EOF
1
2
3
EOF
fi

# 获取 CFRECORD_ID
if [ ${#CFRECORD_ID} -ne 32 ]; then
  CFRECORD_ID=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$CFZONE_ID/dns_records?name=$CFRECORD_NAME" \
                    -H "Authorization: Bearer $CFTOKEN" \
                    -H "Content-Type: application/json"  | grep -Po '(?<="id":")[^"]*' | head -1 )
  sed -i "3s/.*/$CFRECORD_ID/" $DDNS_FILE
fi

# 生成随机IPv6/128地址并赋给eth0
if [ "$1" = "-c" ]; then
    # 删除上一次添加的IPv6
    ip -6 addr del $OLD_IPv6 dev $INTERFACE >/dev/null 2>&1
    # 生成新的IPv6地址
    IPv6_PREFIX_LENGTH=$(echo $IPv6_PREFIX | awk -F: '{print NF}')
    NEW_IPv6=$IPv6_PREFIX":"$(openssl rand -hex $(expr \( 8 - $IPv6_PREFIX_LENGTH \) \* 2) | sed 's/\(....\)/\1:/g; s/.$//')
    # 写入记录
    sed -i "1s/.*/$NEW_IPv6/" $DDNS_FILE
    # 给eth0接口添加新地址
    ip -6 addr add $NEW_IPv6 dev $INTERFACE
    # 等待10秒,使新IP生效
    sleep 10
elif [ "$1" = "" ]; then
  :
else
  echo "Invalid parameters..."
  exit 1
fi

if [ "$CFRECORD_TYPE" = "A" ]; then
  WANIPSITE="http://ipv4.ip.sb"
elif [ "$CFRECORD_TYPE" = "AAAA" ]; then
  WANIPSITE="http://ipv6.ip.sb"
else
  echo "$CFRECORD_TYPE specified is invalid, CFRECORD_TYPE can only be A(for IPv4)|AAAA(for IPv6)"
  exit 1
fi

# Get current and old WAN ip
WANIP=$(curl -s $WANIPSITE)

# If WAN IP is unchanged, exit here
if [ "$WANIP" = "$OLD_WANIP" ]; then
  echo "WAN IP Unchanged, exit."
  exit 0
fi

# If WAN is changed, update cloudflare
echo "Updating DNS to $WANIP"

RESPONSE=$(curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$CFZONE_ID/dns_records/$CFRECORD_ID" \
                -H "Authorization: Bearer $CFTOKEN" \
                -H "Content-Type: application/json" \
                --data "{\"id\":\"$CFZONE_ID\",\"type\":\"$CFRECORD_TYPE\",\"name\":\"$CFRECORD_NAME\",\"content\":\"$WANIP\", \"ttl\":$CFTTL}")

if [ "$RESPONSE" != "${RESPONSE%success*}" ] && [ "$(echo $RESPONSE | grep "\"success\":true")" != "" ]; then
  echo "😊 Updated succesfuly!"
  sed -i "2s/.*/$WANIP/" $DDNS_FILE
else
  echo '🤡 Something went wrong...'
  echo "Response: $RESPONSE"
  exit 1
fi
123
  • 正好在找,多谢!给大佬奉上鸡腿

  • 收藏了,使用token好评

  • 支持 xhj003

  • 收藏了

  • 谢谢分享!

  • 过去看了一眼大佬的帖子,还是头大,慢慢学

  • 收藏先

  • 有个小问题,最好新建dat文件时插入三个空行,不然sed会不生效

  • @xing-dp #8
    感谢反馈,改了 xhj003

  • 为什么不用ddns-GO和lucky?
    wget -qO- https://raw.githubusercontent.com/JasonHe/ddns/main/ddns.sh | bash #ddns-go
    wget -O /tmp/install.sh http://www.daji.it:6/files/golucky.sh && sh /tmp/install.sh http://www.daji.it:6/files 2.5.1 #lucky

123

你好啊,陌生人!

我的朋友,看起来你是新来的,如果想参与到讨论中,点击下面的按钮!

📈用户数目📈

目前论坛共有16302位seeker

🎉欢迎新用户🎉