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.

338 lines
7.8 KiB

  1. #!/usr/bin/env sh
  2. # shellcheck disable=SC2034
  3. dns_dyn_info='Dyn.com
  4. Domains: dynect.net
  5. Site: Dyn.com
  6. Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_dyn
  7. Options:
  8. DYN_Customer Customer
  9. DYN_Username API Username
  10. DYN_Password Secret
  11. Author: Gerd Naschenweng <https://github.com/magicdude4eva>
  12. '
  13. # Dyn Managed DNS API
  14. # https://help.dyn.com/dns-api-knowledge-base/
  15. #
  16. # It is recommended to add a "Dyn Managed DNS" user specific for API access.
  17. # The "Zones & Records Permissions" required by this script are:
  18. # --
  19. # RecordAdd
  20. # RecordUpdate
  21. # RecordDelete
  22. # RecordGet
  23. # ZoneGet
  24. # ZoneAddNode
  25. # ZoneRemoveNode
  26. # ZonePublish
  27. # --
  28. DYN_API="https://api.dynect.net/REST"
  29. #REST_API
  30. ######## Public functions #####################
  31. #Usage: add _acme-challenge.www.domain.com "Challenge-code"
  32. dns_dyn_add() {
  33. fulldomain="$1"
  34. txtvalue="$2"
  35. DYN_Customer="${DYN_Customer:-$(_readaccountconf_mutable DYN_Customer)}"
  36. DYN_Username="${DYN_Username:-$(_readaccountconf_mutable DYN_Username)}"
  37. DYN_Password="${DYN_Password:-$(_readaccountconf_mutable DYN_Password)}"
  38. if [ -z "$DYN_Customer" ] || [ -z "$DYN_Username" ] || [ -z "$DYN_Password" ]; then
  39. DYN_Customer=""
  40. DYN_Username=""
  41. DYN_Password=""
  42. _err "You must export variables: DYN_Customer, DYN_Username and DYN_Password"
  43. return 1
  44. fi
  45. #save the config variables to the account conf file.
  46. _saveaccountconf_mutable DYN_Customer "$DYN_Customer"
  47. _saveaccountconf_mutable DYN_Username "$DYN_Username"
  48. _saveaccountconf_mutable DYN_Password "$DYN_Password"
  49. if ! _dyn_get_authtoken; then
  50. return 1
  51. fi
  52. if [ -z "$_dyn_authtoken" ]; then
  53. _dyn_end_session
  54. return 1
  55. fi
  56. if ! _dyn_get_zone; then
  57. _dyn_end_session
  58. return 1
  59. fi
  60. if ! _dyn_add_record; then
  61. _dyn_end_session
  62. return 1
  63. fi
  64. if ! _dyn_publish_zone; then
  65. _dyn_end_session
  66. return 1
  67. fi
  68. _dyn_end_session
  69. return 0
  70. }
  71. #Usage: fulldomain txtvalue
  72. #Remove the txt record after validation.
  73. dns_dyn_rm() {
  74. fulldomain="$1"
  75. txtvalue="$2"
  76. DYN_Customer="${DYN_Customer:-$(_readaccountconf_mutable DYN_Customer)}"
  77. DYN_Username="${DYN_Username:-$(_readaccountconf_mutable DYN_Username)}"
  78. DYN_Password="${DYN_Password:-$(_readaccountconf_mutable DYN_Password)}"
  79. if [ -z "$DYN_Customer" ] || [ -z "$DYN_Username" ] || [ -z "$DYN_Password" ]; then
  80. DYN_Customer=""
  81. DYN_Username=""
  82. DYN_Password=""
  83. _err "You must export variables: DYN_Customer, DYN_Username and DYN_Password"
  84. return 1
  85. fi
  86. if ! _dyn_get_authtoken; then
  87. return 1
  88. fi
  89. if [ -z "$_dyn_authtoken" ]; then
  90. _dyn_end_session
  91. return 1
  92. fi
  93. if ! _dyn_get_zone; then
  94. _dyn_end_session
  95. return 1
  96. fi
  97. if ! _dyn_get_record_id; then
  98. _dyn_end_session
  99. return 1
  100. fi
  101. if [ -z "$_dyn_record_id" ]; then
  102. _dyn_end_session
  103. return 1
  104. fi
  105. if ! _dyn_rm_record; then
  106. _dyn_end_session
  107. return 1
  108. fi
  109. if ! _dyn_publish_zone; then
  110. _dyn_end_session
  111. return 1
  112. fi
  113. _dyn_end_session
  114. return 0
  115. }
  116. #################### Private functions below ##################################
  117. #get Auth-Token
  118. _dyn_get_authtoken() {
  119. _info "Start Dyn API Session"
  120. data="{\"customer_name\":\"$DYN_Customer\", \"user_name\":\"$DYN_Username\", \"password\":\"$DYN_Password\"}"
  121. dyn_url="$DYN_API/Session/"
  122. method="POST"
  123. _debug data "$data"
  124. _debug dyn_url "$dyn_url"
  125. export _H1="Content-Type: application/json"
  126. response="$(_post "$data" "$dyn_url" "" "$method")"
  127. sessionstatus="$(printf "%s\n" "$response" | _egrep_o '"status" *: *"[^"]*' | _head_n 1 | sed 's#^"status" *: *"##')"
  128. _debug response "$response"
  129. _debug sessionstatus "$sessionstatus"
  130. if [ "$sessionstatus" = "success" ]; then
  131. _dyn_authtoken="$(printf "%s\n" "$response" | _egrep_o '"token" *: *"[^"]*' | _head_n 1 | sed 's#^"token" *: *"##')"
  132. _info "Token received"
  133. _debug _dyn_authtoken "$_dyn_authtoken"
  134. return 0
  135. fi
  136. _dyn_authtoken=""
  137. _err "get token failed"
  138. return 1
  139. }
  140. #fulldomain=_acme-challenge.www.domain.com
  141. #returns
  142. # _dyn_zone=domain.com
  143. _dyn_get_zone() {
  144. i=2
  145. while true; do
  146. domain="$(printf "%s" "$fulldomain" | cut -d . -f "$i-100")"
  147. if [ -z "$domain" ]; then
  148. break
  149. fi
  150. dyn_url="$DYN_API/Zone/$domain/"
  151. export _H1="Auth-Token: $_dyn_authtoken"
  152. export _H2="Content-Type: application/json"
  153. response="$(_get "$dyn_url" "" "")"
  154. sessionstatus="$(printf "%s\n" "$response" | _egrep_o '"status" *: *"[^"]*' | _head_n 1 | sed 's#^"status" *: *"##')"
  155. _debug dyn_url "$dyn_url"
  156. _debug response "$response"
  157. _debug sessionstatus "$sessionstatus"
  158. if [ "$sessionstatus" = "success" ]; then
  159. _dyn_zone="$domain"
  160. return 0
  161. fi
  162. i=$(_math "$i" + 1)
  163. done
  164. _dyn_zone=""
  165. _err "get zone failed"
  166. return 1
  167. }
  168. #add TXT record
  169. _dyn_add_record() {
  170. _info "Adding TXT record"
  171. data="{\"rdata\":{\"txtdata\":\"$txtvalue\"},\"ttl\":\"300\"}"
  172. dyn_url="$DYN_API/TXTRecord/$_dyn_zone/$fulldomain/"
  173. method="POST"
  174. export _H1="Auth-Token: $_dyn_authtoken"
  175. export _H2="Content-Type: application/json"
  176. response="$(_post "$data" "$dyn_url" "" "$method")"
  177. sessionstatus="$(printf "%s\n" "$response" | _egrep_o '"status" *: *"[^"]*' | _head_n 1 | sed 's#^"status" *: *"##')"
  178. _debug response "$response"
  179. _debug sessionstatus "$sessionstatus"
  180. if [ "$sessionstatus" = "success" ]; then
  181. _info "TXT Record successfully added"
  182. return 0
  183. fi
  184. _err "add TXT record failed"
  185. return 1
  186. }
  187. #publish the zone
  188. _dyn_publish_zone() {
  189. _info "Publishing zone"
  190. data="{\"publish\":\"true\"}"
  191. dyn_url="$DYN_API/Zone/$_dyn_zone/"
  192. method="PUT"
  193. export _H1="Auth-Token: $_dyn_authtoken"
  194. export _H2="Content-Type: application/json"
  195. response="$(_post "$data" "$dyn_url" "" "$method")"
  196. sessionstatus="$(printf "%s\n" "$response" | _egrep_o '"status" *: *"[^"]*' | _head_n 1 | sed 's#^"status" *: *"##')"
  197. _debug response "$response"
  198. _debug sessionstatus "$sessionstatus"
  199. if [ "$sessionstatus" = "success" ]; then
  200. _info "Zone published"
  201. return 0
  202. fi
  203. _err "publish zone failed"
  204. return 1
  205. }
  206. #get record_id of TXT record so we can delete the record
  207. _dyn_get_record_id() {
  208. _info "Getting record_id of TXT record"
  209. dyn_url="$DYN_API/TXTRecord/$_dyn_zone/$fulldomain/"
  210. export _H1="Auth-Token: $_dyn_authtoken"
  211. export _H2="Content-Type: application/json"
  212. response="$(_get "$dyn_url" "" "")"
  213. sessionstatus="$(printf "%s\n" "$response" | _egrep_o '"status" *: *"[^"]*' | _head_n 1 | sed 's#^"status" *: *"##')"
  214. _debug response "$response"
  215. _debug sessionstatus "$sessionstatus"
  216. if [ "$sessionstatus" = "success" ]; then
  217. _dyn_record_id="$(printf "%s\n" "$response" | _egrep_o "\"data\" *: *\[\"/REST/TXTRecord/$_dyn_zone/$fulldomain/[^\"]*" | _head_n 1 | sed "s#^\"data\" *: *\[\"/REST/TXTRecord/$_dyn_zone/$fulldomain/##")"
  218. _debug _dyn_record_id "$_dyn_record_id"
  219. return 0
  220. fi
  221. _dyn_record_id=""
  222. _err "getting record_id failed"
  223. return 1
  224. }
  225. #delete TXT record
  226. _dyn_rm_record() {
  227. _info "Deleting TXT record"
  228. dyn_url="$DYN_API/TXTRecord/$_dyn_zone/$fulldomain/$_dyn_record_id/"
  229. method="DELETE"
  230. _debug dyn_url "$dyn_url"
  231. export _H1="Auth-Token: $_dyn_authtoken"
  232. export _H2="Content-Type: application/json"
  233. response="$(_post "" "$dyn_url" "" "$method")"
  234. sessionstatus="$(printf "%s\n" "$response" | _egrep_o '"status" *: *"[^"]*' | _head_n 1 | sed 's#^"status" *: *"##')"
  235. _debug response "$response"
  236. _debug sessionstatus "$sessionstatus"
  237. if [ "$sessionstatus" = "success" ]; then
  238. _info "TXT record successfully deleted"
  239. return 0
  240. fi
  241. _err "delete TXT record failed"
  242. return 1
  243. }
  244. #logout
  245. _dyn_end_session() {
  246. _info "End Dyn API Session"
  247. dyn_url="$DYN_API/Session/"
  248. method="DELETE"
  249. _debug dyn_url "$dyn_url"
  250. export _H1="Auth-Token: $_dyn_authtoken"
  251. export _H2="Content-Type: application/json"
  252. response="$(_post "" "$dyn_url" "" "$method")"
  253. _debug response "$response"
  254. _dyn_authtoken=""
  255. return 0
  256. }