将动态IP同步到Cloudflare使用ddns服务

2024-06-25
265次阅读
没有评论

封面图:

将动态IP同步到Cloudflare使用ddns服务

脚本代码:

#!/usr/bin/env bash
set -o errexit
set -o nounset
set -o pipefail

# Automatically update your CloudFlare DNS record to the IP, Dynamic DNS
# Can retrieve cloudflare Domain id and list zone's, because, lazy

# Place at:
# curl https://raw.githubusercontent.com/yulewang/cloudflare-api-v4-ddns/master/cf-v4-ddns.sh > /usr/local/bin/cf-ddns.sh && chmod +x /usr/local/bin/cf-ddns.sh
# run `crontab -e` and add next line:
# */1 * * * * /usr/local/bin/cf-ddns.sh >/dev/null 2>&1
# or you need log:
# */1 * * * * /usr/local/bin/cf-ddns.sh >> /var/log/cf-ddns.log 2>&1

# Usage:
# cf-ddns.sh -k cloudflare-api-key 
# -u [email protected] 
# -h host.example.com  # fqdn of the record you want to update
# -z example.com  # will show you all zones if forgot, but you need this
# -t A|AAAA # specify ipv4/ipv6, default: ipv4

# Optional flags:
# -f false|true  # force dns update, disregard local stored ip

# default config

# API key, see https://www.cloudflare.com/a/account/my-account,
# incorrect api-key results in E_UNAUTH error
CFKEY=填写你的cf-key

# Username, eg: [email protected]
CFUSER=你的cf登录邮箱

# Zone name, eg: example.com
CFZONE_NAME=你的主域名

# Hostname to update, eg: homeserver.example.com
CFRECORD_NAME=完整子域名,例如 ddns.123.com

# Record type, A(IPv4)|AAAA(IPv6), default IPv4
CFRECORD_TYPE=A

# Cloudflare TTL for record, between 120 and 86400 seconds
CFTTL=120

# Ignore local file, update ip anyway
FORCE=false

WANIPSITE="https://4.ipw.cn"

# Site to retrieve WAN ip, other examples are: bot.whatismyipaddress.com, https://api.ipify.org/ ...
if [ "$CFRECORD_TYPE" = "A" ]; then
:
elif [ "$CFRECORD_TYPE" = "AAAA" ]; then
WANIPSITE="https://4.ipw.cn"
else
echo "$CFRECORD_TYPE specified is invalid, CFRECORD_TYPE can only be A(for IPv4)|AAAA(for IPv6)"
exit 2
fi

# get parameter
while getopts k:u:h:z:t:f: opts; do
case ${opts} in
k) CFKEY=${OPTARG} ;;
u) CFUSER=${OPTARG} ;;
h) CFRECORD_NAME=${OPTARG} ;;
z) CFZONE_NAME=${OPTARG} ;;
t) CFRECORD_TYPE=${OPTARG} ;;
f) FORCE=${OPTARG} ;;
esac
done

# If required settings are missing just exit
if [ "$CFKEY" = "" ]; then
echo "Missing api-key, get at: https://www.cloudflare.com/a/account/my-account"
echo "and save in ${0} or using the -k flag"
exit 2
fi
if [ "$CFUSER" = "" ]; then
echo "Missing username, probably your email-address"
echo "and save in ${0} or using the -u flag"
exit 2
fi
if [ "$CFRECORD_NAME" = "" ]; then
echo "Missing hostname, what host do you want to update?"
echo "save in ${0} or using the -h flag"
exit 2
fi

# If the hostname is not a FQDN
if [ "$CFRECORD_NAME" != "$CFZONE_NAME" ] && ! [ -z "${CFRECORD_NAME##*$CFZONE_NAME}" ]; then
CFRECORD_NAME="$CFRECORD_NAME.$CFZONE_NAME"
echo " => Hostname is not a FQDN, assuming $CFRECORD_NAME"
fi

# Get current and old WAN ip
WAN_IP=`curl -s ${WANIPSITE}`
WAN_IP_FILE=$HOME/.cf-wan_ip_$CFRECORD_NAME.txt
if [ -f $WAN_IP_FILE ]; then
OLD_WAN_IP=`cat $WAN_IP_FILE`
else
echo "No file, need IP"
OLD_WAN_IP=""
fi

# If WAN IP is unchanged an not -f flag, exit here
if [ "$WAN_IP" = "$OLD_WAN_IP" ] && [ "$FORCE" = false ]; then
echo "WAN IP Unchanged, to update anyway use flag -f true"
exit 0
fi

# Get zone_identifier & record_identifier
ID_FILE=$HOME/.cf-id_$CFRECORD_NAME.txt
if [ -f $ID_FILE ] && [ $(wc -l $ID_FILE | cut -d " " -f 1) == 4 ] 
&& [ "$(sed -n '3,1p' "$ID_FILE")" == "$CFZONE_NAME" ] 
&& [ "$(sed -n '4,1p' "$ID_FILE")" == "$CFRECORD_NAME" ]; then
CFZONE_ID=$(sed -n '1,1p' "$ID_FILE")
CFRECORD_ID=$(sed -n '2,1p' "$ID_FILE")
else
echo "Updating zone_identifier & record_identifier"
CFZONE_ID=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones?name=$CFZONE_NAME" -H "X-Auth-Email: $CFUSER" -H "X-Auth-Key: $CFKEY" -H "Content-Type: application/json" | grep -Po '(?<="id":")[^"]*' | head -1 )
CFRECORD_ID=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$CFZONE_ID/dns_records?name=$CFRECORD_NAME" -H "X-Auth-Email: $CFUSER" -H "X-Auth-Key: $CFKEY" -H "Content-Type: application/json" | grep -Po '(?<="id":")[^"]*' | head -1 )
echo "$CFZONE_ID" > $ID_FILE
echo "$CFRECORD_ID" >> $ID_FILE
echo "$CFZONE_NAME" >> $ID_FILE
echo "$CFRECORD_NAME" >> $ID_FILE
fi

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

RESPONSE=$(curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$CFZONE_ID/dns_records/$CFRECORD_ID" 
-H "X-Auth-Email: $CFUSER" 
-H "X-Auth-Key: $CFKEY" 
-H "Content-Type: application/json" 
--data "{"id":"$CFZONE_ID","type":"$CFRECORD_TYPE","name":"$CFRECORD_NAME","content":"$WAN_IP", "ttl":$CFTTL}")

if [ "$RESPONSE" != "${RESPONSE%success*}" ] && [ "$(echo $RESPONSE | grep ""success":true")" != "" ]; then
echo "Updated succesfuly!"
echo $WAN_IP > $WAN_IP_FILE
exit
else
echo 'Something went wrong :('
echo "Response: $RESPONSE"
exit 1
fi

设置定时任务,每2分钟检查一次并执行:

任意目录下,使用root权限,执行:
[pre]crontab -e[/pre]
选择第一个nano打开;

添加每次执行的代码:

*/2 * * * * /root/ddns/ddns.sh >> /root/ddns/ddns.log 2>&1

注意,按照你自己的文件所在的地址,别忘记修改文件路径

设置定时清除日志:

0 0 * * * > /root/ddns/ddns.log

每天定时0点清除所有的log信息。

特别注意:

不同于你手动bash执行文件,/root/ddns/ddns.log 和 /root/ddns/ddns.sh都需要给与权限,默认644权限,给它755权限。

正文结束
自由书生
版权声明:本站原创文章,由 自由书生 于2024-06-25发表,共计4356字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)
验证码