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