Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Cloudflare as Dynamic DNS
#!/bin/bash
# Cloudflare as Dynamic DNS
# From: https://letswp.io/cloudflare-as-dynamic-dns-raspberry-pi/
# Based on: https://gist.github.com/benkulbertis/fff10759c2391b6618dd/
# Original non-RPi article: https://phillymesh.net/2016/02/23/setting-up-dynamic-dns-for-your-registered-domain-through-cloudflare/
# Update these with real values
auth_email="email@example.com"
auth_key="global_api_key_goes_here"
zone_name="example.com"
record_name="home.example.com"
# Don't touch these
ip=$(curl -s http://ipv4.icanhazip.com)
ip_file="ip.txt"
id_file="cloudflare.ids"
log_file="cloudflare.log"
# Keep files in the same folder when run from cron
current="$(pwd)"
cd "$(dirname "$(readlink -f "$0")")"
log() {
if [ "$1" ]; then
echo -e "[$(date)] - $1" >> $log_file
fi
}
log "Check Initiated"
if [ -f $ip_file ]; then
old_ip=$(cat $ip_file)
if [ $ip == $old_ip ]; then
log "IP has not changed."
exit 0
fi
fi
if [ -f $id_file ] && [ $(wc -l $id_file | cut -d " " -f 1) == 2 ]; then
zone_identifier=$(head -1 $id_file)
record_identifier=$(tail -1 $id_file)
else
zone_identifier=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones?name=$zone_name" -H "X-Auth-Email: $auth_email" -H "X-Auth-Key: $auth_key" -H "Content-Type: application/json" | grep -Po '(?<="id":")[^"]*' | head -1 )
record_identifier=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$zone_identifier/dns_records?name=$record_name" -H "X-Auth-Email: $auth_email" -H "X-Auth-Key: $auth_key" -H "Content-Type: application/json" | grep -Po '(?<="id":")[^"]*')
echo "$zone_identifier" > $id_file
echo "$record_identifier" >> $id_file
fi
update=$(curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$zone_identifier/dns_records/$record_identifier" -H "X-Auth-Email: $auth_email" -H "X-Auth-Key: $auth_key" -H "Content-Type: application/json" --data "{\"id\":\"$zone_identifier\",\"type\":\"A\",\"name\":\"$record_name\",\"content\":\"$ip\"}")
if [[ $update == *"\"success\":false"* ]]; then
message="API UPDATE FAILED. DUMPING RESULTS:\n$update"
log "$message"
echo -e "$message"
exit 1
else
message="IP changed to: $ip"
echo "$ip" > $ip_file
log "$message"
echo "$message"
fi
@kanetzach

This comment has been minimized.

Copy link

kanetzach commented Jun 25, 2019

This happens
lwp-cloudflare-dyndns.sh: 33: [: ipaddress: unexpected operator
lwp-cloudflare-dyndns.sh: 39: [: 2: unexpected operator
lwp-cloudflare-dyndns.sh: 51: lwp-cloudflare-dyndns.sh: [[: not found
IP changed to: ipaddress

I changed my real ip for ipaddress

@TheFirsh

This comment has been minimized.

Copy link
Owner Author

TheFirsh commented Jul 11, 2019

We even started using this script on Ubuntu in an AWS EC2 instance and works fine. What have you tried and how were you using it to have run into that error?

@kanetzach

This comment has been minimized.

Copy link

kanetzach commented Jul 12, 2019

Raspbian 10 (Buster), probably it's because of that. A similar thing happened with another cloudflare ddns script but I fixed that through shellcheck.

@MohaBeacon

This comment has been minimized.

Copy link

MohaBeacon commented Jul 24, 2019

working good but can't enable proxy via ddns

@chitypo

This comment has been minimized.

Copy link

chitypo commented Aug 25, 2019

enable proxy

update=$(curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$zone_identifier/dns_records/$record_identifier" -H "X-Auth-Email: $auth_email" -H "X-Auth-Key: $auth_key" -H "Content-Type: application/json" --data "{\"id\":\"$zone_identifier\",\"type\":\"A\",\"name\":\"$record_name\",\"content\":\"$ip\",\"proxied\":true}")

@tarasis

This comment has been minimized.

Copy link

tarasis commented Sep 23, 2019

No working for me from a Raspberry Pi.

First attempts kept getting a URI error.

~/cf $ sudo ./lwp-cloudflare-dyndns.sh
API UPDATE FAILED. DUMPING RESULTS:
{"success":false,"errors":[{"code":7003,"message":"Could not route to \/zones\/dns_records, perhaps your object identifier is invalid?"},{"code":7000,"message":"No route for that URI"}],"messages":[],"result":null}

After self populating zone_identifier and record_identifier I get this error:

API UPDATE FAILED. DUMPING RESULTS:
{"success":false,"errors":[{"code":7001,"message":"Method PUT not available for that URI."}],"messages":[],"result":null}

Same result when I used a custom API token just for this script:

./lwp-cloudflare-dyndns.sh API UPDATE FAILED. DUMPING RESULTS: {"success":false,"errors":[{"code":7001,"message":"Method PUT not available for that URI."}],"messages":[],"result":null}

@TheFirsh

This comment has been minimized.

Copy link
Owner Author

TheFirsh commented Oct 1, 2019

Hi, it still works fine for me. From the docs: https://api.cloudflare.com/#accounts-update-account It tells us to use PUT, and these permissions are required: #organization:edit not sure where those are set though.

@ILAsoft

This comment has been minimized.

Copy link

ILAsoft commented Nov 30, 2019

This happens
lwp-cloudflare-dyndns.sh: 33: [: ipaddress: unexpected operator
lwp-cloudflare-dyndns.sh: 39: [: 2: unexpected operator
lwp-cloudflare-dyndns.sh: 51: lwp-cloudflare-dyndns.sh: [[: not found
IP changed to: ipaddress

I changed my real ip for ipaddress

This is most likely due to running as an SH vs BASH command. Try running like so: "bash lwp-cloudflare-dyndns.sh".

@strontiumss

This comment has been minimized.

Copy link

strontiumss commented Dec 20, 2019

Works great on RPi with buster. Thanks!

@natelandau

This comment has been minimized.

Copy link

natelandau commented Jan 10, 2020

FWIW, getting the same error

{"success":false,"errors":[{"code":7001,"message":"Method PUT not available for that URI."}],"messages":[],"result":null}

No idea how to fix it yet. Would appreciate it if someone could point out how to do so...

@pedrof1gueiredo

This comment has been minimized.

Copy link

pedrof1gueiredo commented Feb 29, 2020

Getting:
API UPDATE FAILED. DUMPING RESULTS:
{"success":false,"errors":[{"code":7003,"message":"Could not route to /zones/dns_records, perhaps your object identifier is invalid?"},{"code":7000,"message":"No route for that URI"}],"messages":[],"result":null}

Any idea? It is an account with multiple domains.

@heygambo

This comment has been minimized.

Copy link

heygambo commented Mar 17, 2020

Managed to get it to work:
https://gist.github.com/heygambo/6a6180d62469002297b2ec63406b7d37

  • Updated it to work with Cloudflare API tokens that can be limited.
  • Fixed id parsing for the identifiers
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.