Modify

Opened 5 years ago

Closed 2 years ago

#12500 closed enhancement (moved_to_github)

Add cloudflare.com to DDNS Scripts

Reported by: easisee@… Owned by: developers
Priority: normal Milestone: Chaos Calmer 15.05
Component: packages Version: Trunk
Keywords: Cc:

Description

As title.

Attachments (7)

cloudflare.patch (693 bytes) - added by easisee@… 5 years ago.
patch for cloudflare.com
20141002-ddns_cloudflare.update (2.6 KB) - added by chris5560 3 years ago.
20141002-dynamic_dns_functions.sh (25.3 KB) - added by chris5560 3 years ago.
20141002-dynamic_dns_updater.sh (17.3 KB) - added by chris5560 3 years ago.
20141003-update_cloudflare.sh (4.6 KB) - added by chris5560 3 years ago.
20141109-update_cloudflare.sh (4.3 KB) - added by chris5560 3 years ago.
ddns-scripts_2.1.0-1_all.ipk (24.2 KB) - added by chris5560 3 years ago.

Download all attachments as: .zip

Change History (37)

Changed 5 years ago by easisee@…

patch for cloudflare.com

comment:1 follow-up: Changed 5 years ago by jow

This patch will not work with the default system, it requires the full featured wget to work.

comment:2 in reply to: ↑ 1 Changed 5 years ago by easisee@…

Replying to jow:

This patch will not work with the default system, it requires the full featured wget to work.

According to https://dev.openwrt.org/browser/packages/net/ddns-scripts/files/usr/lib/ddns/dynamic_dns_updater.sh, it requires curl and cacert, then set

    option "use_https" "1"
    option "cacert"    "/path/to/cacert.pem"

comment:3 Changed 5 years ago by sayap

Patch works fine for me, using /etc/ssl/certs/ca-certificates.crt from gentoo as cacert.

comment:4 Changed 4 years ago by alghanmi@…

This has been confirmed to work with the following configuration on 12.09, r36088 with:

uci set ddns.myddns.use_https=1
uci set ddns.myddns.cacert=/path/to/GlobalSign_Root_R1_CERT.pem

The certificate can be found in the [GlobalSign certificate repository, https://www.globalsign.com/repository/ca-certificates/] named: GlobalSign Root R1.

curl http://secure.globalsign.net/cacert/Root-R1.crt -o /etc/ssl/certs/GlobalSign_Root_R1.pem

comment:5 Changed 3 years ago by sanshinron

The above patch is not working anymore due to changes in cloudflare api. It returns success message, but in reality nothing gets changed.
I've reviewed cloudflare api documentation and managed to "hack" a new url:

https://www.cloudflare.com/api_json.html?a=rec_edit&email=[USERNAME]&tkn=[PASSWORD]&type=A&z=[DOMAIN]&name=[SUBDOMAIN]&service_mode=0&ttl=1&id=[ID]&content=[IP]

Of course we need to define DOMAIN, SUBDOMAIN and ID in /etc/config/ddns.

ID is available with the following call:

https://www.cloudflare.com/api_json.html?a=rec_load_all&email=YOUR-EMAIL&tkn=YOUR-API-KEY&z=YOUR-DOMAIN

After these changes the dns entry gets updated properly.

comment:6 Changed 3 years ago by kiddyfurby@…

that works, any chance the changes got merged?

comment:7 Changed 3 years ago by chris5560

Hi,
for me it's not 100% clear what you need inside ddns-scripts.
simply a URL for the service or more functionality ?
As I understand the given URL uses more parameters as currently availible like SUBDOMAIN and ID.
ID can be get via an additional call needing EMAIL and API-KEY.
For me it's looks like to create a "cloudflare" version of ddns-scripts.
Am I right or wrong.

-EDIT-
After asking Google, the following url should work too (posted 2014-08-02):

http://www.cloudflare.com/api.html?a=DIUP&hosts=[DOMAIN]&u=[USERNAME]&tkn=[PASSWORD]&ip=[IP]

DOMAIN = your hostname to update
USERNAME = your registered email
PASSWORD = your registration token

try this as custom url. If this works (possibly for IPv4 and IPv6) I will update services and service_ipv6 files for ddns-scripts.

Christian

Last edited 3 years ago by chris5560 (previous) (diff)

comment:8 Changed 3 years ago by anonymous

Or use cloudflare update script

#!/bin/sh /etc/rc.common
# (c) Radio Kuchka 2014

API=API key <--change this
EMAIL= email <--change this
HOSTNAME= domain name <--change this

if test -f /tmp/ip_cloudflare.txt
then
CacheIP=$(cat /tmp/ip_cloudflare.txt)
fi

CurrentIP=/sbin/ifconfig pppoe-wan | grep 'inet addr' | cut -d ':' -f 2 | cut -d ' ' -f 1

if [ "$CurrentIP" != "$CacheIP" ]
then
echo "Updating CloudFlare DNS with" $CurrentIP
echo date "IP" $CurrentIP >> /tmp/log/cloudflare-dns-update.log

wget --no-check-certificate -O /tmp/cloudflare.domain "https://www.cloudflare.com/api_json.html?a=DIUP&hosts=$HOSTNAME&u=$EMAIL&tkn=$API&ip=$CurrentIP"

Then add file root to /etc/crontabs

with

#!/bin/sh
*/7 * * * * /etc/init.d/custom/cloudflare restart

then

/etc/init.d/cron start
/etc/init.d/cron enable

comment:9 Changed 3 years ago by sanshinron

@up:
Did you at least try your solution? No, because it will never work - cloudflare changed their api and your POST parameters are obsolete.
Did you read the posts above? No, because you would know that it's not working anymore.

Why do you even post this?

comment:10 Changed 3 years ago by anonymous

Yes i try. And this works for me. Okay change this line in script ;)

wget --no-check-certificate -O /tmp/cloudflare.domain "https://www.cloudflare.com/api_json.html?a=rec_edit&z=$HOSTNAME&email=$EMAIL&tkn=$API&ttl=1&id=your_token_id&type=A&name=your_record_name&content=$CurrentIP"

comment:11 Changed 3 years ago by chris5560

Hi,
I'm maintaining ddns-scripts since version 2.x and I need some explanations to see if its possible to implement cloudflare into this scripts. If I'm right inside the above url there are 6 parameters to be set: $HOSTNAME, $EMAIL, $API, your_token_id, your_record_name and $CurrentIP.
Are they nearby static to use a custom url inside ddns-scripts or are they changing on every request.
Thanks,
Christian

comment:12 Changed 3 years ago by sanshinron

Hi Christian,
In my url,

https://www.cloudflare.com/api_json.html?a=rec_edit&email=[USERNAME]&tkn=[PASSWORD]&type=A&z=[DOMAIN]&name=[SUBDOMAIN]&service_mode=0&ttl=1&id=[ID]&content=[IP]

all parameters that are in [] are changing (they are unique to your domain and account). That's why I've added them to /etc/config/ddns.
These changing parameters are:
email=[USERNAME] - cloudflare e-mail;
tkn=[PASSWORD] - cloudflare api key, you can get it from cloudflare.com/my-account/;
z=[DOMAIN] - domain to change, e.g. example.com;
name=[SUBDOMAIN] - subdomain to change, e.g. if you want to change home.example.com, put only 'home' in here;
id=[ID] - this is the record id from cloudflare. You can get it using api call from my previous post;
content=[IP] - updated ip.

All other parameters are not changing and can be hardcoded. These are:
a=rec_edit - type of operation - edit dns record,
service_mode=0 - it's supposed to be for SRV records only, but I had to put it in the call to get it to work;
ttl=1 - ttl of a record, 1 = automatic.

For more information you can check https://www.cloudflare.com/docs/client-api.html
Updating DNS records is in section 5.2

Paul

comment:13 Changed 3 years ago by chris5560

Hi Paul,
this looks like, that the "default" ddns-scripts could not fulfil this requirements.
Nearby all other DDNS provider using the same url , if you look into /usr/lib/ddns/services file.
What do you think, if it is possible to use a script for sending updates like it is currently possible for detecting local IP. So it should be possible to write a "snap-in" sending service specific updates.
I'm currently have no idea how to handle inside current ddns-scripts and inside luci-app-ddns, but there will be a way.
What do you think ?
Christian

comment:14 Changed 3 years ago by sanshinron

You're right, other DDNS services only use 4 parameters: username, password, domain and ip. Cloudflare however, apart from those 4, needs subdomain and record id. You would need to add these fields to luci-app-ddns.

Another way to approach this would be to make a script, which would split full domain name, e.g. 'home.example.com' into 'home' and 'example.com' and automatically recover record id from cloudflare api. If you did that it would be possible to use default ddns-scripts with cloudflare.

Despite this, I think it's worth the trouble. Correct me if I'm wrong, but cloudflare.com is currently the only way to get ddns in your own domain for FREE.

Paul

comment:15 Changed 3 years ago by chris5560

Paul,
as the next step I think one of us should open up a
ddns-scripts wish list
in the forum.
My current version based on 1.0 scripts with some extensions but
I see already other needs i.e. record types (cname, mx, etc.) to update/verify.
Might be we need dependencies to run it, like wget ssl and bind host.
What do you think ?
Christian

comment:16 Changed 3 years ago by chris5560

Paul,
I found a short term solution based on ddns-scripts 2.0.1-6.
I offer here 2 changes to existing scripts for testing:

/usr/lib/ddns/dynamic_dns_updater.sh at below line 162 new should be

# determine what update url we're using if a service_name is supplied
# otherwise update_url is set inside configuration (custom service)
# or update_script is set inside configuration (custom update script)
[ -n "$service_name" ] && get_service_url update_url
[ -z "$update_url" -a -z "$update_script" ] && critical_error "no update_url found/defined or no custom update_script defined"
[ -n "$update_script" -a ! -f "$update_script" ] && critical_error "custom update_script not found"

#kill old process if it exists & set new pid file

/usr/lib/ddns/dynamic_dns_functions.sh at below line 590 replace send_update() function with

send_update() {
	# $1	# IP to set at DDNS service provider
	local __IP

	# verify given IP / no private IPv4's / no IPv6 addr starting with fxxx of with ":"
	[ $use_ipv6 -eq 0 ] && __IP=$(echo $1 | grep -v -E "(^0|^10\.|^127|^172\.1[6-9]\.|^172\.2[0-9]\.|^172\.3[0-1]\.|^192\.168)")
	[ $use_ipv6 -eq 1 ] && __IP=$(echo $1 | grep "^[0-9a-eA-E]")
	[ -z "$__IP" ] && critical_error "Invalid or no IP '$1' given"

	if [ -z "$service_name" -a -n "$update_script" ]; then
		verbose_echo " custom update =: parsing script '$update_script'"
		. $update_script
	else
		local __URL __ANSWER __ERR __USER __PASS

		# do replaces in URL
		__urlencode __USER "$username"	# encode username, might be email or something like this
		__urlencode __PASS "$password"	# encode password, might have special chars for security reason
		__URL=$(echo $update_url | sed -e "s#\[USERNAME\]#$__USER#g" -e "s#\[PASSWORD\]#$__PASS#g" \
					       -e "s#\[DOMAIN\]#$domain#g" -e "s#\[IP\]#$__IP#g")
		[ $use_https -ne 0 ] && __URL=$(echo $__URL | sed -e 's#^http:#https:#')

		__do_transfer __ANSWER "$__URL"
		__ERR=$?
		[ $__ERR -gt 0 ] && {
			verbose_echo "\n!!!!!!!!! ERROR =: Error sending update to DDNS Provider\n"
			return 1
		}
		verbose_echo "   update send =: DDNS Provider answered\n$__ANSWER"
		return 0
	fi
}

Inside /etc/config/ddns insert a new option update_script '/path/to/script' and remove option service_name

The idea behind this is to offer custom scripts for special services like cloudflare.update also located inside /usr/lib/ddns directory.
Inside these scripts you can do all actions you need and can still access all existing variables and functions out of dynamic_dns_functions.
Options to be set inside /etc/config/ddns shoud start with the service name the scripts is for like
cloudflare_subdomain, cloudflare_xyz
This hopefully makes it easier in later versions of scripts or luci app to identify them.
Would you provide such cloudflare.update script ?

If you agree this short term solution, I will create a pull request to update both scripts in trunk.

Thanks
Christian

Last edited 3 years ago by chris5560 (previous) (diff)

comment:17 Changed 3 years ago by chris5560

Paul,
I upload here three files starting with 20141002-...
If you like to test for me, copy them to /usr/lib/ddns and remove the "20141002-"
you need two options inside /etc/config/ddns:
option update_script '/usr/lib/ddns/ddns_cloudflare.update'
option cloudflare_rec_id '...' with your record id filled in.

As you can see the update script also produces for testing a /tmp/log/cloudflare.readid file.
this should be the answer getting from cloudflare when reading the all records.
could you please send me this file via direct mail (look at the head of dynamic_ddns_updater.sh) so I can check if it's possible to extract the id via script.

Thanks for your support
Christian

Changed 3 years ago by chris5560

Changed 3 years ago by chris5560

Changed 3 years ago by chris5560

comment:18 Changed 3 years ago by chris5560

Paul,
I complete the script for cloudflare updates.
It now (should) read the rec_id from cloudflare.
So no longer need additional options inside /etc/config/ddns
I attach it here.
ATTENTION
dynamic_dns_functions.sh and dynamic_dns_updater.sh tested.
update_cloudflare.sh completely untested against cloudflare servers.
The extraction was tested based on documentation of client API response documentation.
Hopefully I made no typing errors.

Thanks for testing
Christian

Changed 3 years ago by chris5560

comment:19 Changed 3 years ago by sanshinron

Today I'm kinda busy installing Windows 10 and all the apps after fresh install, but I will test your new script tomorrow.

Paul

comment:20 Changed 3 years ago by chris5560

Hi Paul,

any news ?

It was just merged a new version of ddns-scripts on trunk.
Attached you find a new Version of update_cloudflare.sh that should work with the new ddns-scripts 2.1.0-1 version.
In handling of cloudflare communication are no changes, only minor changes for compatibility to the modified functions in ddns-scripts.

Christian

Changed 3 years ago by chris5560

comment:21 Changed 3 years ago by sanshinron

So I've pasted ddns_cloudflare.update, dynamic_dns_updater.sh and latest update_cloudflare.sh into /usr/lib/ddns, changed my dns through cloudflare.com website to 8.8.8.8, commented the cloudflare line in services and restarted my router. After it started, the ip was changed, so I think your script works properly.
Great job, Chris.

BTW, I am on Attitude Adjustment 12.09.

comment:22 Changed 3 years ago by chris5560

Hi sanshinron,

thanks for feedback.
Did you install the whole ddns-script 2.0.1-1 package on AA 12.09 ?
You normally need the dynamic_dns_updater.sh AND dynamic_dns_functions.sh AND only update_cloudflare.sh. The ddns_cloudflare.update is outdated.
Best is to install the whole ddns-script package, because the files inside /usr/lib/ddns depends on each other.

Christian

comment:23 Changed 3 years ago by sanshinron

No, I still have the old 1.0.xx package from AA and it seems to work. Guess the ddns_cloudflare.update just don't get used.

comment:24 Changed 3 years ago by chris5560

I recompile on aa1209. Attached you find the complete package.
You can install with opkg install [pkgname].
It will install over the current 1.0 version without changing your current config file.
Modify your config according to ddns.sample for the usage of update_script /usr/lib/ddns/update_cloudflare.sh
Enable log_file to get output of cloudflare logged so I can have a look on it.
Don't forget /etc/init.d/ddns enable for autostart.
You can start/stop with /etc/init.d/ddns start or stop
You could send me the log via private mail if you like.
I need the whole cloudflare output to add a check, if the scripts analyze correctly and if the send update was successful or not.
Thanks for your testing.
Christian

Last edited 3 years ago by chris5560 (previous) (diff)

Changed 3 years ago by chris5560

comment:25 Changed 3 years ago by AaronTa

Using 2.1.0-3 here... I found that the cloudflare provider didn't work.

I edited it back to a known working config of:

"cloudflare.com" "http://www.cloudflare.com/api_json.html?a=DIUP&email=[USERNAME]&tkn=[PASSWORD]&hosts=[DOMAIN]&ip=[IP]"

This works perfectly for me, whereas the built-in one for DDNS Scripts failed completely. Kept telling me that my Cloudflare record didn't exist, when in fact it most certainly did.

Don't know why people are saying the above solution is not working, but its working here, so as the old saying goes, don't fix what ain't broke.

comment:26 follow-up: Changed 3 years ago by chris5560

Hi AaronTa,

the script was coded according to cloudflare client api https://www.cloudflare.com/docs/client-api.html.
I don't find your given a=DIUP as an option inside update url.

It would be nice to send me the logfile via direct mail, so I can have a look what's going wrong.
Same for the working URL.

Thanks for your support.
Christian

comment:27 in reply to: ↑ 26 Changed 3 years ago by aaronta

Replying to chris5560:

Hi AaronTa,

the script was coded according to cloudflare client api https://www.cloudflare.com/docs/client-api.html.
I don't find your given a=DIUP as an option inside update url.

It would be nice to send me the logfile via direct mail, so I can have a look what's going wrong.
Same for the working URL.

Thanks for your support.
Christian

What's the easiest way to get hold of you mate? Won't let me DM you through the forum.

I believe DIUP was used way back when, used to be documented I believe... either way, seems to be the most reliable way I've found so far (and easiest) to do record updates, at least for DDNS purposes.

comment:28 Changed 3 years ago by aaronta

FYI - https://web.archive.org/web/20120822010012/http://www.cloudflare.com/docs/client-api.html

section 3.3.10

DIUP is the action used to update an IPv4 A record, only. Which is all I'm using.

Looks like it was last around in 2012, at least documented, but they've left the DIUP action there.

I have the log file ready to send from trying your script, once you send through a way to contact you. Cheers.

comment:29 Changed 3 years ago by chris5560

Hi,
have a look into /usr/lib/ddns/update_cloudflare.sh.
In the header you find my direct mail.
Christian

comment:30 Changed 2 years ago by nbd

  • Resolution set to moved_to_github
  • Status changed from new to closed

ddns-scripts is maintained here: https://github.com/openwrt/packages

Add Comment

Modify Ticket

Action
as closed .
The resolution will be deleted. Next status will be 'reopened'.
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.