巨人的肩膀:https://github.com/yulewang/cloudflare-api-v4-ddns
ddns一般就是NAT小鸡使用,定期把IP更新到域名上,因为商家给的域名有时不好使
另外增加了一个小功能,如果VPS给了一个IPv6的地址块,如/64,使用 -c 参数可以根据给定的前缀,给eth0网络接口添加一个/128的随机地址,每次启动脚本都会更新。作用嘛,也许能增加点直连防封的概率吧,我还没被封过
另外感谢纱版 @Just纱世里 的IPv6科普帖,学习完之后我也会玩IPv6了
#!/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
正好在找,多谢!给大佬奉上鸡腿
收藏了,使用token好评
支持
收藏了
谢谢分享!
过去看了一眼大佬的帖子,还是头大,慢慢学
收藏先
有个小问题,最好新建dat文件时插入三个空行,不然sed会不生效
@xing-dp #8
感谢反馈,改了
为什么不用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