#!/bin/sh | |
# | |
# CloudFlare Dynamic DNS | |
# | |
# Updates CloudFlare records with the current public IP address | |
# | |
# Takes the same basic arguments as A/CNAME updates in the CloudFlare v4 API | |
# https://www.cloudflare.com/docs/client-api.html#s5.2 | |
# | |
# Use with cron jobs etc. | |
# | |
# e.g. | |
# | |
# manually run: | |
# cloudflare_dyn_dns.sh -key 404613183ab3971a2118ae5bf03d63e032f9e -email test@example.com -zone example.com -name extra | |
# | |
# cronjob entry to run every 5 minutes: | |
# */5 * * * * /path/to/cloudflare_dyn_dns.sh -key 404613183ab3971a2118ae5bf03d63e032f9e -email test@example.com -zone example.com -name extra >> /path/to/cloudflare_dyn_dns.log | |
# | |
# will both set the type A DNS record for extra.example.com to the current public IP address for user test@example.com with the provided API key | |
key= | |
email= | |
zone= | |
zone_id= | |
type=A | |
rec_id= | |
name= | |
content= | |
ttl=1 | |
proxied=false | |
while [ "$1" != "" ]; do | |
case $1 in | |
-key ) shift | |
key=$1 | |
;; | |
-email ) shift | |
email=$1 | |
;; | |
-zone ) shift | |
zone=$1 | |
;; | |
-zone_id ) shift | |
zone_id=$1 | |
;; | |
-type ) shift | |
type=$1 | |
;; | |
-rec_id ) shift | |
rec_id=$1 | |
;; | |
-name ) shift | |
name=$1 | |
;; | |
-content ) shift | |
content=$1 | |
;; | |
-ttl ) shift | |
ttl=$1 | |
;; | |
-proxied ) shift | |
proxied=$1 | |
;; | |
* ) echo "unknown parameter $1" | |
exit 1 | |
esac | |
shift | |
done | |
if [ "$content" = "" ] | |
then | |
content=`curl -s http://myexternalip.com/raw` | |
if [ "$content" = "" ] | |
then | |
date | |
echo "No IP address to set record value with." | |
exit 1 | |
fi | |
fi | |
if [ "$name" = "" ] | |
then | |
echo "You must provide the name of the record you wish to change." | |
exit 1 | |
fi | |
if [ "$zone" = "" ] | |
then | |
echo "You must provide the domain you wish to change." | |
exit 1 | |
fi | |
if [ "$name" = "$zone" ] | |
then | |
hostname="$name" | |
else | |
hostname="$name.$zone" | |
fi | |
command -v host > /dev/null 2>&1 | |
if [ "$?" = "1" ] | |
then | |
command -v nslookup > /dev/null 2>&1 | |
if [ "$?" = "1" ] | |
then | |
echo "Cannot find a way to check existing $type record for $hostname" | |
exit 1 | |
fi | |
existing_content=`nslookup -type=$type $hostname | awk -F 'Address: ' 'NR==6 { print $2 }'` | |
else | |
existing_content=`host -t $type $hostname | sed -E 's/.+?\s+([^\s]+)$/\1/'` | |
fi | |
if [ "$content" = "$existing_content" ] | |
then | |
echo "Existing record value $existing_content is the same as provided content $content. Exiting." | |
exit | |
fi | |
if [ "$key" = "" ] | |
then | |
echo "You must provide your user API token." | |
exit 1 | |
fi | |
if [ "$email" = "" ] | |
then | |
echo "You must provide your user email." | |
exit 1 | |
fi | |
# Get the zone id for the entry we're trying to change if it's not provided | |
if [ "$zone_id" = "" ] | |
then | |
zone_response_json=`curl -X GET "https://api.cloudflare.com/client/v4/zones?name=$zone" -H "X-Auth-Email: $email" -H "X-Auth-Key: $key" -H "Content-Type: application/json"` | |
zone_id=`echo $zone_response_json | sed -E "s/.+\"result\":\[\{\"id\":\"([a-f0-9]+)\"[^\}]+$zone.+/\1/g"` | |
if [ "$zone_id" = "" ] | |
then | |
echo "Cloudflare DNS Zone id could not be found, please make sure it exists" | |
exit 1 | |
fi | |
fi | |
# Get the record id for the entry we're trying to change if it's not provided | |
if [ "$rec_id" = "" ] | |
then | |
rec_response_json=`curl -X GET "https://api.cloudflare.com/client/v4/zones/$zone_id/dns_records?name=$hostname" -H "X-Auth-Email: $email" -H "X-Auth-Key: $key" -H "Content-Type: application/json"` | |
rec_id=`echo $rec_response_json | sed -E "s/.+\"result\":\[\{\"id\":\"([a-f0-9]+)\"[^\}]+\"type\":\"$type\"[^\}]+$hostname.+/\1/g"` | |
if [ "$rec_id" = "" ] | |
then | |
echo "Cloudflare DNS Record id could not be found, please make sure it exists" | |
exit 1 | |
fi | |
fi | |
# Update the DNS record | |
update_response=`curl -X PUT "https://api.cloudflare.com/client/v4/zones/$zone_id/dns_records/$rec_id" -H "X-Auth-Email: $email" -H "X-Auth-Key: $key" -H "Content-Type: application/json" --data "{\"id\":\"$rec_id\",\"type\":\"$type\",\"name\":\"$hostname\",\"content\":\"$content\",\"ttl\":$ttl,\"proxied\":$proxied}"` | |
success_val=`echo $update_response | sed -E "s/.+\"success\":(true|false).+/\1/g"` | |
if [ "$success_val" = "true" ] | |
then | |
echo "Record Updated." | |
else | |
echo "Record update failed." | |
exit 1 | |
fi |
This comment has been minimized.
This comment has been minimized.
add "content=" ))) |
This comment has been minimized.
This comment has been minimized.
Hi @anshgh apologies for the delayed response. You are quite correct, using an command line argument of |
This comment has been minimized.
This comment has been minimized.
got Stuck at line "++ curl -s http://myexternalip.com/raw" replaces it with this line, to make it work: curl -s checkip.dyndns.org | sed -e 's/.Current IP Address: //' -e 's/<.$//' |
This comment has been minimized.
This comment has been minimized.
Not sure why this isn't working for you @ftahirops , possibly some network issues? Could investigate with a |
This comment has been minimized.
This comment has been minimized.
I've got this
|
This comment has been minimized.
This comment has been minimized.
@wsokc I edited your comment to redact the key and e-mail in-case these were valid for your Cloudflare account. May I also suggest you refresh the key via Cloudflare's UI, otherwise if they were valid you may find some of your DNS records getting modified without your permission for anyone that had a copy. I've updated the script to deal with the scenario you've provided. The script was originally written to deal with sub-hosts, not with the top level domain record, it should now deal with this scenario (e.g. it could deal with the record for www.example.com, but not for example.com . It should now deal with both.) |
This comment has been minimized.
This comment has been minimized.
Anyone looking at this, it's also worth noting, /etc/ddclient/ddclient.conf
|
This comment has been minimized.
This comment has been minimized.
I got this
Update: got it worked by edit line 149 with jq
|
This comment has been minimized.
Thank you!
script works:
[root @ router1 sbin] # /etc/rc.d/cf_eth0.sh
Attempting to get current public IP Address for content.
Record Updated.
But I there are several IP addresses. How can I update a specific (one of the four IP)?