mirror of
https://github.com/aipeach/cloudflare-api-v4-ddns.git
synced 2025-01-18 22:09:28 +08:00
d1c5b3ca58
Added "record name" and "zone name" in the local file, and check whether they is equl with the user's input. Prevent the make error when user changing these two properties.
133 lines
4.4 KiB
Bash
133 lines
4.4 KiB
Bash
#!/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 user@example.com \
|
|
# -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
|
|
|
|
# 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=
|
|
|
|
# Username, eg: user@example.com
|
|
CFUSER=
|
|
|
|
# Zone name, eg: example.com
|
|
CFZONE_NAME=
|
|
|
|
# Hostname to update, eg: homeserver.example.com
|
|
CFRECORD_NAME=
|
|
|
|
# Cloudflare TTL for record, between 120 and 86400 seconds
|
|
CFTTL=120
|
|
|
|
# Ignore local file, update ip anyway
|
|
FORCE=false
|
|
|
|
# Site to retrieve WAN ip, other examples are: bot.whatismyipaddress.com, https://api.ipify.org/ ...
|
|
WANIPSITE="http://icanhazip.com"
|
|
|
|
# get parameter
|
|
while getopts k:u:h:z:f: opts; do
|
|
case ${opts} in
|
|
k) CFKEY=${OPTARG} ;;
|
|
u) CFUSER=${OPTARG} ;;
|
|
h) CFRECORD_NAME=${OPTARG} ;;
|
|
z) CFZONE_NAME=${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}`
|
|
if [ -f $HOME/.wan_ip-cf.txt ]; then
|
|
OLD_WAN_IP=`cat $HOME/.wan_ip-cf.txt`
|
|
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/.id-cf.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=$(head -1 $ID_FILE)
|
|
CFRECORD_ID=$(tail -1 $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":")[^"]*')
|
|
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\":\"A\",\"name\":\"$CFRECORD_NAME\",\"content\":\"$WAN_IP\", \"ttl\":\"$CFTTL\"}")
|
|
|
|
if [ "$RESPONSE" != "${RESPONSE%success*}" ] && [ $(echo $RESPONSE | grep "\"success\":true") != "" ]; then
|
|
echo "Updated succesfuly!"
|
|
echo $WAN_IP > $HOME/.wan_ip-cf.txt
|
|
exit
|
|
else
|
|
echo 'Something went wrong :('
|
|
echo "Response: $RESPONSE"
|
|
exit 1
|
|
fi |