You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

138 lines
5.4 KiB

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