#!/bin/sh API_TOKEN="" # Your API Token ZONE_ID="" # Your zone id, hex16 string RECORD_NAME="" # Your DNS record name, e.g. sub.example.com RECORD_TTL="1" # TTL in seconds (1=auto) UPDATE_IPv6=false # Set to true if you want to also update IPv6 IP_QUERY_SITE="https://myip.dnsomatic.com/" # Site used to get external DNS if router isn't able to pull it due to double NAT get_dns_record_ids() { local record_name=$1 local type=$2 local api_token=$3 local zone_id=$4 RESPONSE="$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/${zone_id}/dns_records?type=${type}&name=${record_name}" \ -H "Authorization: Bearer ${api_token}" \ -H "Content-Type:application/json")" echo $RESPONSE | python -c " import sys, json data = json.load(sys.stdin) for record in data['result']: print (record['id'])" } update_dns_record() { local record_name=$1 local record_id=$2 local type=$3 local ip=$4 local record_ttl=$5 local api_token=$6 local zone_id=$7 curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/${zone_id}/dns_records/${record_id}" \ -H "Authorization: Bearer ${api_token}" \ -H "Content-Type: application/json" \ --data "{\"type\":\"${type}\",\"name\":\"${record_name}\",\"content\":\"${ip}\",\"ttl\":${record_ttl},\"proxied\":false}" } RESULT=true # Update IPv4 #Get IPv4 from Router otherwise from external source IPv4=${1} if [ -z "$IPv4" ]; then IPv4="$(curl -fs4 $IP_QUERY_SITE)" logger "IP ${IPv4} obtained external source $IP_QUERY_SITE" else logger "IP ${IPv4} obtained by router" fi A_RECORD_IDS=$(get_dns_record_ids $RECORD_NAME A $API_TOKEN $ZONE_ID) for A_RECORD_ID in $A_RECORD_IDS; do RESPONSE="$(update_dns_record $RECORD_NAME $A_RECORD_ID A $IPv4 $RECORD_TTL $API_TOKEN $ZONE_ID)" echo $RESPONSE | grep '"success":\ *true' >/dev/null if [ $? -eq 0 ]; then logger "Updated A record for ${RECORD_NAME} to ${IPv4}" else logger "Unable to update A record for ${RECORD_NAME} with ${IPv4}" RESULT=false fi done if [ "$UPDATE_IPv6" == true ]; then # Update IPv6 IPv6=$(ip -6 addr list scope global $device | grep -v " fd" | sed -n 's/.*inet6 \([0-9a-f:]\+\).*/\1/p' | head -n 1) AAAA_RECORD_IDS=$(get_dns_record_ids $RECORD_NAME AAAA $API_TOKEN $ZONE_ID) for AAAA_RECORD_ID in $AAAA_RECORD_IDS; do RESPONSE="$(update_dns_record $RECORD_NAME $AAAA_RECORD_ID AAAA $IPv6 $RECORD_TTL $API_TOKEN $ZONE_ID)" echo $RESPONSE | grep '"success":\ *true' >/dev/null if [ $? -eq 0 ]; then logger "Updated AAAA record for ${RECORD_NAME} to ${IPv6}" else logger "Unable to update AAAA record for ${RECORD_NAME}" RESULT=false fi done fi if [ "$RESULT" == true ]; then /sbin/ddns_custom_updated 1 else /sbin/ddns_custom_updated 0 fi