dns_opusdns.sh 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. #!/usr/bin/env sh
  2. # shellcheck disable=SC2034
  3. dns_opusdns_info='OpusDNS.com
  4. Site: OpusDNS.com
  5. Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_opusdns
  6. Options:
  7. OPUSDNS_API_Key API Key. Can be created at https://dashboard.opusdns.com/settings/api-keys
  8. OPUSDNS_API_Endpoint API Endpoint URL. Default "https://api.opusdns.com". Optional.
  9. OPUSDNS_TTL TTL for DNS challenge records in seconds. Default "60". Optional.
  10. Issues: github.com/acmesh-official/acme.sh/issues/XXXX
  11. Author: OpusDNS Team <https://github.com/opusdns>
  12. '
  13. OPUSDNS_API_Endpoint_Default="https://api.opusdns.com"
  14. OPUSDNS_TTL_Default=60
  15. ######## Public functions ###########
  16. # Add DNS TXT record
  17. dns_opusdns_add() {
  18. fulldomain=$1
  19. txtvalue=$2
  20. _info "Using OpusDNS DNS API"
  21. _debug fulldomain "$fulldomain"
  22. _debug txtvalue "$txtvalue"
  23. if ! _opusdns_init; then
  24. return 1
  25. fi
  26. if ! _get_zone "$fulldomain"; then
  27. return 1
  28. fi
  29. _info "Zone: $_zone, Record: $_record_name"
  30. if ! _opusdns_api PATCH "/v1/dns/$_zone/records" "{\"ops\":[{\"op\":\"upsert\",\"record\":{\"name\":\"$_record_name\",\"type\":\"TXT\",\"ttl\":$OPUSDNS_TTL,\"rdata\":\"\\\"$txtvalue\\\"\"}}]}"; then
  31. _err "Failed to add TXT record"
  32. return 1
  33. fi
  34. _info "TXT record added successfully"
  35. return 0
  36. }
  37. # Remove DNS TXT record
  38. dns_opusdns_rm() {
  39. fulldomain=$1
  40. txtvalue=$2
  41. _info "Removing OpusDNS DNS record"
  42. _debug fulldomain "$fulldomain"
  43. _debug txtvalue "$txtvalue"
  44. if ! _opusdns_init; then
  45. return 1
  46. fi
  47. if ! _get_zone "$fulldomain"; then
  48. _err "Zone not found, cleanup skipped"
  49. return 0
  50. fi
  51. _info "Zone: $_zone, Record: $_record_name"
  52. if ! _opusdns_api PATCH "/v1/dns/$_zone/records" "{\"ops\":[{\"op\":\"remove\",\"record\":{\"name\":\"$_record_name\",\"type\":\"TXT\",\"ttl\":$OPUSDNS_TTL,\"rdata\":\"\\\"$txtvalue\\\"\"}}]}"; then
  53. _err "Warning: Failed to remove TXT record"
  54. return 0
  55. fi
  56. _info "TXT record removed successfully"
  57. return 0
  58. }
  59. ######## Private functions ###########
  60. # Initialize and validate configuration
  61. _opusdns_init() {
  62. OPUSDNS_API_Key="${OPUSDNS_API_Key:-$(_readaccountconf_mutable OPUSDNS_API_Key)}"
  63. OPUSDNS_API_Endpoint="${OPUSDNS_API_Endpoint:-$(_readaccountconf_mutable OPUSDNS_API_Endpoint)}"
  64. OPUSDNS_TTL="${OPUSDNS_TTL:-$(_readaccountconf_mutable OPUSDNS_TTL)}"
  65. if [ -z "$OPUSDNS_API_Key" ]; then
  66. _err "OPUSDNS_API_Key not set"
  67. return 1
  68. fi
  69. [ -z "$OPUSDNS_API_Endpoint" ] && OPUSDNS_API_Endpoint="$OPUSDNS_API_Endpoint_Default"
  70. [ -z "$OPUSDNS_TTL" ] && OPUSDNS_TTL="$OPUSDNS_TTL_Default"
  71. _saveaccountconf_mutable OPUSDNS_API_Key "$OPUSDNS_API_Key"
  72. _saveaccountconf_mutable OPUSDNS_API_Endpoint "$OPUSDNS_API_Endpoint"
  73. _saveaccountconf_mutable OPUSDNS_TTL "$OPUSDNS_TTL"
  74. _debug "Endpoint: $OPUSDNS_API_Endpoint"
  75. return 0
  76. }
  77. # Make API request
  78. # Usage: _opusdns_api METHOD PATH [DATA]
  79. _opusdns_api() {
  80. method=$1
  81. path=$2
  82. data=$3
  83. export _H1="X-Api-Key: $OPUSDNS_API_Key"
  84. export _H2="Content-Type: application/json"
  85. url="$OPUSDNS_API_Endpoint$path"
  86. _debug2 "API: $method $url"
  87. [ -n "$data" ] && _debug2 "Data: $data"
  88. if [ -n "$data" ]; then
  89. response=$(_post "$data" "$url" "" "$method")
  90. else
  91. response=$(_get "$url")
  92. fi
  93. if [ $? -ne 0 ]; then
  94. _err "API request failed"
  95. _debug "Response: $response"
  96. return 1
  97. fi
  98. _debug2 "Response: $response"
  99. return 0
  100. }
  101. # Detect zone from FQDN
  102. # Sets: _zone, _record_name
  103. _get_zone() {
  104. domain=$(echo "$1" | sed 's/\.$//')
  105. _debug "Finding zone for: $domain"
  106. i=1
  107. p=1
  108. while true; do
  109. h=$(printf "%s" "$domain" | cut -d . -f "$i"-100)
  110. if [ -z "$h" ]; then
  111. _err "No valid zone found for: $domain"
  112. return 1
  113. fi
  114. _debug "Trying: $h"
  115. if _opusdns_api GET "/v1/dns/$h" && _contains "$response" '"dnssec_status"'; then
  116. _zone="$h"
  117. _record_name=$(printf "%s" "$domain" | cut -d . -f 1-"$p")
  118. [ -z "$_record_name" ] && _record_name="@"
  119. return 0
  120. fi
  121. p="$i"
  122. i=$(_math "$i" + 1)
  123. done
  124. }