Skip to content

Instantly share code, notes, and snippets.

@mgarratt
Last active November 26, 2019 12:16
Show Gist options
  • Save mgarratt/6b356d78c75ba4625237099e27d60909 to your computer and use it in GitHub Desktop.
Save mgarratt/6b356d78c75ba4625237099e27d60909 to your computer and use it in GitHub Desktop.
DDNS in Cloudflare using bash/curl/jq/ipify - Only calls Cloudflare when IP changes and ipify has no rate limit so can be run as often as you like. Requires an ini file in the same format as certbot cloudflare-dns plugin
#!/usr/bin/env bash
ini_file=$1
dns_zone=$2
domain=$3
function load_ini_value {
filename=$1
property=$2
variable=$3
declare -g ${variable}=$(source <(grep ${property} ${filename} | sed 's/ *= */=/g'); echo ${!property})
}
load_ini_value ${ini_file} dns_cloudflare_email email
load_ini_value ${ini_file} dns_cloudflare_api_key api_key
function get_zone_id {
variable=$1
declare -g ${variable}=$(curl -sS https://api.cloudflare.com/client/v4/zones?name=${dns_zone} \
-H "X-Auth-Email: ${email}" \
-H "X-Auth-Key: ${api_key}" \
-H "Content-Type: application/json" \
| jq -r .result[0].id)
}
function get_record_id {
local zone_id=$1
id_variable=$2
ip_variable=$3
local result=$(curl -sS https://api.cloudflare.com/client/v4/zones/${zone_id}/dns_records \
-H "X-Auth-Email: ${email}" \
-H "X-Auth-Key: ${api_key}" \
-H "Content-Type: application/json")
declare -g ${id_variable}=$(echo ${result} | jq -r ".result[] | select(.name == \"${domain}\" and .type == \"A\") | .id")
if [[ ! -z "${ip_variable}" ]]; then
declare -g ${ip_variable}=$(echo ${result} | jq -r ".result[] | select(.name == \"${domain}\" and .type == \"A\") | .content")
fi
}
function update_dns_ip {
local zone_id=$1
local record_id=$2
local new_ip=$3
local variable=$4
declare -g ${variable}=$(curl -sS -X PUT https://api.cloudflare.com/client/v4/zones/${zone_id}/dns_records/${record_id} \
-H "X-Auth-Email: ${email}" \
-H "X-Auth-Key: ${api_key}" \
-H "Content-Type: application/json" \
--data "{\"type\":\"A\",\"name\":\"${domain}\",\"content\":\"${new_ip}\",\"proxied\":true}")
}
if [[ ! -f .dns-ip ]]; then
get_zone_id zone_id
get_record_id ${zone_id} record_id record_ip
echo $record_ip > .dns-ip
fi
last_ip=$(<.dns-ip)
external_ip=$(curl -sS https://api.ipify.org/)
if [[ "${external_ip}" != "${last_ip}" ]]; then
echo "IP has change, updating from ${last_ip} to ${external_ip}"
if [[ -z "${zone_id}" ]]; then
get_zone_id zone_id
fi
if [[ -z "${record_id}" ]]; then
get_record_id ${zone_id} record_id
fi
update_dns_ip $zone_id $record_id $external_ip result
if [[ $(echo ${result} | jq -r .success) == "true" ]]; then
echo "SUCCESS"
else
echo "FAILURE"
echo ${result} | jq .
exit 1
fi
else
echo "No change"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment