|
--- ddclient.orig 2013-09-26 01:06:12.399990673 +0100 |
|
+++ ddclient 2013-09-26 06:25:36.768189452 +0100 |
|
@@ -13,12 +13,17 @@ |
|
# Support for multiple IP numbers added by |
|
# Astaro AG, Ingo Schwarze <ischwarze-OOs/[email protected]> September 16, 2008 |
|
# |
|
+# Modified to work with Cloudflare by Robert Ian Hawdon 2012-07-16: http://robertianhawdon.me.uk/ |
|
+# |
|
+# Further modified to work with Cloudflare by Peter Roberts 2013-9-26, 2014-6-22: blog.peter-r.co.uk |
|
+# |
|
###################################################################### |
|
-require 5.004; |
|
+require 5.014; |
|
use strict; |
|
use Getopt::Long; |
|
use Sys::Hostname; |
|
use IO::Socket; |
|
+use JSON::Any; |
|
|
|
my $version = "3.8.0"; |
|
my $programd = $0; |
|
@@ -416,6 +421,14 @@ |
|
'warned-min-interval' => setv(T_ANY, 0, 1, 0, 0, undef), |
|
'warned-min-error-interval' => setv(T_ANY, 0, 1, 0, 0, undef), |
|
}, |
|
+ 'cloudflare-common-defaults' => { |
|
+ 'server' => setv(T_FQDNP, 1, 0, 1, 'www.cloudflare.com', undef), |
|
+ 'zone' => setv(T_FQDN, 1, 0, 1, '', undef), |
|
+ 'static' => setv(T_BOOL, 0, 1, 1, 0, undef), |
|
+ 'wildcard' => setv(T_BOOL, 0, 1, 1, 0, undef), |
|
+ 'mx' => setv(T_OFQDN, 0, 1, 1, '', undef), |
|
+ 'backupmx' => setv(T_BOOL, 0, 1, 1, 0, undef), |
|
+ }, |
|
); |
|
my %services = ( |
|
'dyndns1' => { |
|
@@ -529,6 +542,17 @@ |
|
$variables{'service-common-defaults'}, |
|
), |
|
}, |
|
+ 'cloudflare' => { |
|
+ 'updateable' => undef, |
|
+ 'update' => \&nic_cloudflare_update, |
|
+ 'examples' => \&nic_cloudflare_examples, |
|
+ 'variables' => merge( |
|
+ { 'server' => setv(T_FQDNP, 1, 0, 1, 'www.cloudflare.com', undef) }, |
|
+ { 'min-interval' => setv(T_DELAY, 0, 0, 1, interval('5m'), 0),}, |
|
+ $variables{'cloudflare-common-defaults'}, |
|
+ $variables{'service-common-defaults'}, |
|
+ ), |
|
+ }, |
|
); |
|
$variables{'merged'} = merge($variables{'global-defaults'}, |
|
$variables{'service-common-defaults'}, |
|
@@ -3386,7 +3410,128 @@ |
|
} |
|
|
|
###################################################################### |
|
-# vim: ai ts=4 sw=4 tw=78 : |
|
|
|
+###################################################################### |
|
+## nic_cloudflare_examples |
|
+## |
|
+## written by Ian Pye |
|
+## |
|
+###################################################################### |
|
+sub nic_cloudflare_examples { |
|
+ return <<EoEXAMPLE; |
|
+o 'cloudflare' |
|
+ |
|
+The 'cloudflare' protocol is used by DNS service offered by www.cloudflare.com. |
|
+ |
|
+Configuration variables applicable to the 'cloudflare' protocol are: |
|
+ protocol=cloudflare ## |
|
+ server=fqdn.of.service ## defaults to www.cloudflare.com |
|
+ zone=dns.zone ## your domain |
|
+ login=service-login ## login name and password registered with the service |
|
+ password=service-password ## |
|
+ fully.qualified.host ## the host registered with the service. |
|
+ |
|
+Example ${program}.conf file entries: |
|
+ ## single host update |
|
+ protocol=cloudflare, |
|
+ zone=dns-zone, \\ |
|
+ login=my-cloudflare.com-login, \\ |
|
+ password=my-cloudflare.com-api-key \\ |
|
+ myhost.com |
|
+ |
|
+ ## multiple host update to the custom DNS service |
|
+ protocol=cloudflare, |
|
+ zone=dns.zone \\ |
|
+ login=my-cloudflare.com-login, \\ |
|
+ password=my-cloudflare.com-api-key \\ |
|
+ my-toplevel-domain.com,my-other-domain.com |
|
+EoEXAMPLE |
|
+} |
|
+###################################################################### |
|
+## nic_cloudflare_update |
|
+###################################################################### |
|
+sub nic_cloudflare_update { |
|
+ debug("\nnic_cloudflare_update -------------------"); |
|
+ |
|
+ ## group hosts with identical attributes together |
|
+ my %groups = group_hosts_by([ @_ ], [ qw(ssh login password server wildcard mx backupmx zone) ]); |
|
+ |
|
+ ## update each set of hosts that had similar configurations |
|
+ foreach my $sig (keys %groups) { |
|
+ my @hosts = @{$groups{$sig}}; |
|
+ my $hosts = join(',', @hosts); |
|
+ my $key = $hosts[0]; |
|
+ my $ip = $config{$key}{'wantip'}; |
|
+ |
|
+ # FQDNs |
|
+ for my $domain (@hosts) { |
|
+ my $hostname = $domain =~ s/\.$config{$key}{zone}$//r; |
|
+ delete $config{$domain}{'wantip'}; |
|
+ |
|
+ info("setting IP address to %s for %s", $ip, $domain); |
|
+ verbose("UPDATE:","updating %s", $domain); |
|
+ |
|
+ # Get domain ID |
|
+ my $url = "https://$config{$key}{'server'}/api_json.html?a=rec_load_all"; |
|
+ $url .= "&z=".$config{$key}{'zone'}; |
|
+ $url .= "&email=".$config{$key}{'login'}; |
|
+ $url .= "&tkn=".$config{$key}{'password'}; |
|
+ |
|
+ my $reply = geturl(opt('proxy'), $url); |
|
+ unless ($reply) { |
|
+ failed("updating %s: Could not connect to %s.", $domain, $config{$key}{'server'}); |
|
+ last; |
|
+ } |
|
+ last if !header_ok($domain, $reply); |
|
+ |
|
+ # Strip header |
|
+ $reply =~ s/^.*?\n\n//s; |
|
+ my $response = JSON::Any->jsonToObj($reply); |
|
+ if ($response->{result} eq 'error') { |
|
+ failed ("%s", $response->{msg}); |
|
+ next; |
|
+ } |
|
+ |
|
+ # Pull the ID out of the json, messy |
|
+ my ($id) = map { $_->{name} eq $domain ? $_->{rec_id} : () } @{ $response->{response}->{recs}->{objs} }; |
|
+ unless($id) { |
|
+ failed("updating %s: No domain ID found.", $domain); |
|
+ next; |
|
+ } |
|
+ |
|
+ # Set domain |
|
+ $url = "https://$config{$key}{'server'}/api_json.html?a=rec_edit&type=A&ttl=1"; |
|
+ $url .= "&name=$hostname"; |
|
+ $url .= "&z=".$config{$key}{'zone'}; |
|
+ $url .= "&id=".$id; |
|
+ $url .= "&email=".$config{$key}{'login'}; |
|
+ $url .= "&tkn=".$config{$key}{'password'}; |
|
+ $url .= "&content="; |
|
+ $url .= "$ip" if $ip; |
|
+ |
|
+ $reply = geturl(opt('proxy'), $url); |
|
+ unless ($reply) { |
|
+ failed("updating %s: Could not connect to %s.", $domain, $config{$domain}{'server'}); |
|
+ last; |
|
+ } |
|
+ last if !header_ok($domain, $reply); |
|
+ |
|
+ # Strip header |
|
+ $reply =~ s/^.*?\n\n//s; |
|
+ $response = JSON::Any->jsonToObj($reply); |
|
+ if ($response->{result} eq 'error') { |
|
+ failed ("%s", $response->{msg}); |
|
+ } else { |
|
+ success ("%s -- Updated Successfully to %s", $domain, $ip); |
|
+ |
|
+ } |
|
+ |
|
+ # Cache |
|
+ $config{$key}{'ip'} = $ip; |
|
+ $config{$key}{'mtime'} = $now; |
|
+ $config{$key}{'status'} = 'good'; |
|
+ } |
|
+ } |
|
+} |
|
|
|
__END__ |