Skip to content

Instantly share code, notes, and snippets.

@c2h2
Created June 11, 2023 13:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save c2h2/8baf01c6610e399a832b0f9ef9dcbbfd to your computer and use it in GitHub Desktop.
Save c2h2/8baf01c6610e399a832b0f9ef9dcbbfd to your computer and use it in GitHub Desktop.
cloudflare ipv6 ddns
#!/usr/bin/env bash
# Step 1: Fill in EMAIL, TOKEN, DOMAIN and SUBDOMAIN. Your API token is here: https://www.cloudflare.com/a/account/my-account
# Make sure the token is the Global token, or has these permissions: #zone:read, #dns_record:read, #dns_records:edit
# Step 2: Create an A record on Cloudflare with the subdomain you chose
# Step 3: Run "./ddns.sh -l" to get the zone_id and rec_id of the record you created.
# Fill in ZONE_ID and REC_ID below
# This step is optional, but will save you 2 requests every time you this script
# Step 4: Run "./ddns.sh". It should tell you that record was updated or that it didn't need updating.
# Step 5: Run it every hour with cron. Use the '-s' flag to silence normal output
# 0 * * * * /path/to/ddns.sh -s
EMAIL='me@example.com' #change me
TOKEN='3f0f33364c09e3ab1cd2995824023984f7ccf' #change me, get from your free cloudflare.com account
DOMAIN='example.xyz' #change me
SUBDOMAIN=$1
ZONE_ID=''
REC_ID=''
#run me like ./ddns6.sh asdf, DNS of asdf.example.xzy will match your public ipv6
set -euo pipefail
#set -x # enable for debugging
echo $SUBDOMAIN.$DOMAIN
VERBOSE="[ '${1:-}' != '-s' ]"
LOOKUP="[ '${1:-}' == '-l' ]"
API_URL="https://api.cloudflare.com/client/v4"
CURL="curl -s \
-H Content-Type:application/json \
-H X-Auth-Key:$TOKEN \
-H X-Auth-Email:$EMAIL "
#IP="$(curl -s https://f.g77k.com/ip.php)"
IP=`ip -6 addr | grep inet6 | grep global | grep -v "temp" | grep -v "mngtmpaddr" | grep -v "fd" | awk -F '[ \t]+|/' '{print $3}'`
echo "my ip = $IP"
#RECORD_IP="$($CURL "${API_URL}/zones/${ZONE_ID}/dns_records/${REC_ID}" | sed -e 's/[{}]/\n/g' | sed -e 's/,/\n/g' | grep '"content":"' | cut -d'"' -f4)"
RECORD_IP=`dig $SUBDOMAIN.$DOMAIN AAAA +short`
echo "Record ip =" $RECORD_IP
if [ -z "$ZONE_ID" ] || $LOOKUP; then
ZONE_ID="$($CURL "$API_URL/zones?name=$DOMAIN" | sed -e 's/[{}]/\n/g' | grep '"name":"'"$DOMAIN"'"' | sed -e 's/,/\n/g' | grep '"id":"' | cut -d'"' -f4)"
$VERBOSE && echo "ZONE_ID='$ZONE_ID'"
fi
if [ -z "$REC_ID" ] || $LOOKUP; then
REC_ID="$($CURL "$API_URL/zones/$ZONE_ID/dns_records" | sed -e 's/[{}]/\n/g' | grep '"name":"'"$SUBDOMAIN"'.'"$DOMAIN"'"' | sed -e 's/,/\n/g' | grep '"id":"' |
cut -d'"' -f4)"
$VERBOSE && echo "REC_ID='$REC_ID'"
fi
#$LOOKUP && exit 0
if [ "$IP" == "$RECORD_IP" ]; then
$VERBOSE && echo "IP Unchanged"
exit 0
fi
$VERBOSE && echo "Setting IP to $IP"
$CURL -X PUT "$API_URL/zones/$ZONE_ID/dns_records/$REC_ID" --data '{"type":"AAAA","name":"'"$SUBDOMAIN"'","content":"'"$IP"'","proxied":false}' 1>/dev/null
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment