update_cloudflare_com_v1.sh (6231B)
1 # 2 #.Distributed under the terms of the GNU General Public License (GPL) version 2.0 3 # 4 # script for sending updates to cloudflare.com 5 #.2014-2017 Christian Schoenebeck <christian dot schoenebeck at gmail dot com> 6 # many thanks to Paul for testing and feedback during development 7 # 8 # This script is parsed by dynamic_dns_functions.sh inside send_update() function 9 # 10 # using following options from /etc/config/ddns 11 # option username - your cloudflare e-mail 12 # option password - cloudflare api key, you can get it from cloudflare.com/my-account/ 13 # option domain - your full hostname to update, in cloudflare its subdomain.domain 14 # i.e. myhost.example.com where myhost is the subdomain and example.com is your domain 15 # 16 # variable __IP already defined with the ip-address to use for update 17 # 18 [ $use_https -eq 0 ] && write_log 14 "Cloudflare only support updates via Secure HTTP (HTTPS). Please correct configuration!" 19 [ -z "$username" ] && write_log 14 "Service section not configured correctly! Missing 'username'" 20 [ -z "$password" ] && write_log 14 "Service section not configured correctly! Missing 'password'" 21 22 local __RECID __URL __KEY __KEYS __FOUND __SUBDOM __DOMAIN __FQDN 23 24 # split __SUBDOM __DOMAIN from $domain 25 # given data: 26 # @example.com for "domain record" 27 # host.sub@example.com for a "host record" 28 __SUBDOM=$(printf %s "$domain" | cut -d@ -f1) 29 __DOMAIN=$(printf %s "$domain" | cut -d@ -f2) 30 31 # Cloudflare v1 needs: 32 # __DOMAIN = the base domain i.e. example.com 33 # __SUBDOM = the host.sub to change if a "host record" or blank if domain record 34 # __FQDN = the FQDN to detect record_id to change 35 # i.e. example.com for the "domain record" or host.sub.example.com for "host record" 36 if [ -z "$__SUBDOM" -o "$__SUBDOM" = "$__DOMAIN" ]; then 37 __SUBDOM="" 38 __FQDN="$__DOMAIN" 39 else 40 __FQDN="${__SUBDOM}.${__DOMAIN}" 41 fi 42 43 # parse OpenWrt script with 44 # functions for parsing and generating json 45 . /usr/share/libubox/jshn.sh 46 47 # function copied from /usr/share/libubox/jshn.sh 48 # from BB14.09 for backward compatibility to AA12.09 49 type "json_get_keys" >/dev/null 2>&1 || json_get_keys() { 50 local __dest="$1" 51 local _tbl_cur 52 53 if [ -n "$2" ]; then 54 json_get_var _tbl_cur "$2" 55 else 56 _json_get_var _tbl_cur JSON_CUR 57 fi 58 local __var="${JSON_PREFIX}KEYS_${_tbl_cur}" 59 eval "export -- \"$__dest=\${$__var}\"; [ -n \"\${$__var+x}\" ]" 60 } 61 62 # function to "sed" unwanted string parts from DATFILE 63 cleanup() { 64 # based on the sample output on cloudflare.com homepage we need to do some cleanup 65 sed -i 's/^[ \t]*//;s/[ \t]*$//' $DATFILE # remove invisible chars at beginning and end of lines 66 sed -i '/^-$/d' $DATFILE # remove lines with "-" (dash) 67 sed -i '/^$/d' $DATFILE # remove empty lines 68 sed -i "#'##g" $DATFILE # remove "'" (single quote) 69 } 70 71 [ -n "$rec_id" ] && __RECID="$rec_id" || { 72 # build url according to cloudflare client api at https://www.cloudflare.com/docs/client-api.html 73 # to "rec_load_all" to detect rec_id needed for update 74 __URL="https://www.cloudflare.com/api_json.html" # https://www.cloudflare.com/api_json.html 75 __URL="${__URL}?a=rec_load_all" # -d 'a=rec_load_all' 76 __URL="${__URL}&tkn=$password" # -d 'tkn=8afbe6dea02407989af4dd4c97bb6e25' 77 __URL="${__URL}&email=$username" # -d 'email=sample@example.com' 78 __URL="${__URL}&z=$__DOMAIN" # -d 'z=example.com' 79 80 # lets request the data 81 do_transfer "$__URL" || return 1 82 83 cleanup # cleanup dat file 84 json_load "$(cat $DATFILE)" # lets extract data 85 __FOUND=0 # found record indicator 86 json_get_var __RES "result" # cloudflare result of last request 87 json_get_var __MSG "msg" # cloudflare error message 88 [ "$__RES" != "success" ] && { 89 write_log 4 "'rec_load_all' failed with error: \n$__MSG" 90 return 1 91 } 92 93 json_select "response" 94 json_select "recs" 95 json_select "objs" 96 json_get_keys __KEYS 97 for __KEY in $__KEYS; do 98 local __ZONE __DISPLAY __NAME __TYPE 99 json_select "$__KEY" 100 # json_get_var __ZONE "zone_name" # for debugging 101 # json_get_var __DISPLAY "display_name" # for debugging 102 json_get_var __NAME "name" 103 json_get_var __TYPE "type" 104 if [ "$__NAME" = "$__FQDN" ]; then 105 # we must verify IPv4 and IPv6 because there might be both for the same host 106 [ \( $use_ipv6 -eq 0 -a "$__TYPE" = "A" \) -o \( $use_ipv6 -eq 1 -a "$__TYPE" = "AAAA" \) ] && { 107 __FOUND=1 # mark found 108 break # found leave for loop 109 } 110 fi 111 json_select .. 112 done 113 [ $__FOUND -eq 0 ] && { 114 # we don't need to continue trying to update cloudflare because record to update does not exist 115 # user has to setup record first outside ddns-scripts 116 write_log 14 "No valid record found at Cloudflare setup. Please create first!" 117 } 118 json_get_var __RECID "rec_id" # last thing to do get rec_id 119 json_cleanup # cleanup 120 write_log 7 "rec_id '$__RECID' detected for host/domain '$__FQDN'" 121 } 122 123 # build url according to cloudflare client api at https://www.cloudflare.com/docs/client-api.html 124 # for "rec_edit" to update IP address 125 __URL="https://www.cloudflare.com/api_json.html" # https://www.cloudflare.com/api_json.html 126 __URL="${__URL}?a=rec_edit" # -d 'a=rec_edit' 127 __URL="${__URL}&tkn=$password" # -d 'tkn=8afbe6dea02407989af4dd4c97bb6e25' 128 __URL="${__URL}&id=$__RECID" # -d 'id=9001' 129 __URL="${__URL}&email=$username" # -d 'email=sample@example.com' 130 __URL="${__URL}&z=$__DOMAIN" # -d 'z=example.com' 131 132 [ $use_ipv6 -eq 0 ] && __URL="${__URL}&type=A" # -d 'type=A' (IPv4) 133 [ $use_ipv6 -eq 1 ] && __URL="${__URL}&type=AAAA" # -d 'type=AAAA' (IPv6) 134 135 # handle subdomain or domain record 136 [ -n "$__SUBDOM" ] && __URL="${__URL}&name=$__SUBDOM" # -d 'name=sub' (HOST/SUBDOMAIN) 137 [ -z "$__SUBDOM" ] && __URL="${__URL}&name=$__DOMAIN" # -d 'name=example.com'(DOMAIN) 138 139 __URL="${__URL}&content=$__IP" # -d 'content=1.2.3.4' 140 __URL="${__URL}&service_mode=0" # -d 'service_mode=0' 141 __URL="${__URL}&ttl=1" # -d 'ttl=1' 142 143 # lets do the update 144 do_transfer "$__URL" || return 1 145 146 cleanup # cleanup tmp file 147 json_load "$(cat $DATFILE)" # lets extract data 148 json_get_var __RES "result" # cloudflare result of last request 149 json_get_var __MSG "msg" # cloudflare error message 150 [ "$__RES" != "success" ] && { 151 write_log 4 "'rec_edit' failed with error:\n$__MSG" 152 return 1 153 } 154 write_log 7 "Update of rec_id '$__RECID' successful" 155 return 0