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.

157 lines
3.7 KiB

  1. #!/usr/bin/env sh
  2. # Supports IONOS DNS API Beta v1.0.0
  3. #
  4. # Usage:
  5. # Export IONOS_PREFIX and IONOS_SECRET before calling acme.sh:
  6. #
  7. # $ export IONOS_PREFIX="..."
  8. # $ export IONOS_SECRET="..."
  9. #
  10. # $ acme.sh --issue --dns dns_ionos ...
  11. IONOS_API="https://api.hosting.ionos.com/dns"
  12. IONOS_ROUTE_ZONES="/v1/zones"
  13. IONOS_TXT_TTL=60 # minimum accepted by API
  14. IONOS_TXT_PRIO=10
  15. dns_ionos_add() {
  16. fulldomain=$1
  17. txtvalue=$2
  18. _ionos_init
  19. _body="{\"name\":\"$_sub_domain.$_domain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"ttl\":$IONOS_TXT_TTL,\"prio\":$IONOS_TXT_PRIO,\"disabled\":false}"
  20. if _ionos_rest PATCH "$IONOS_ROUTE_ZONES/$_zone_id" "$_body" && [ -z "$response" ]; then
  21. _info "TXT record has been created successfully."
  22. return 0
  23. fi
  24. return 1
  25. }
  26. dns_ionos_rm() {
  27. fulldomain=$1
  28. txtvalue=$2
  29. _ionos_init
  30. if ! _ionos_get_record "$fulldomain" "$_zone_id"; then
  31. _err "Could not find _acme-challenge TXT record."
  32. return 1
  33. fi
  34. if _ionos_rest DELETE "$IONOS_ROUTE_ZONES/$_zone_id/records/$_record_id" && [ -z "$response" ]; then
  35. _info "TXT record has been deleted successfully."
  36. return 0
  37. fi
  38. return 1
  39. }
  40. _ionos_init() {
  41. IONOS_PREFIX="${IONOS_PREFIX:-$(_readaccountconf_mutable IONOS_PREFIX)}"
  42. IONOS_SECRET="${IONOS_SECRET:-$(_readaccountconf_mutable IONOS_SECRET)}"
  43. if [ -z "$IONOS_PREFIX" ] || [ -z "$IONOS_SECRET" ]; then
  44. _err "You didn't specify an IONOS api prefix and secret yet."
  45. _err "Read https://beta.developer.hosting.ionos.de/docs/getstarted to learn how to get a prefix and secret."
  46. _err ""
  47. _err "Then set them before calling acme.sh:"
  48. _err "\$ export IONOS_PREFIX=\"...\""
  49. _err "\$ export IONOS_SECRET=\"...\""
  50. _err "\$ acme.sh --issue -d ... --dns dns_ionos"
  51. return 1
  52. fi
  53. _saveaccountconf_mutable IONOS_PREFIX "$IONOS_PREFIX"
  54. _saveaccountconf_mutable IONOS_SECRET "$IONOS_SECRET"
  55. if ! _get_root "$fulldomain"; then
  56. _err "Cannot find this domain in your IONOS account."
  57. return 1
  58. fi
  59. }
  60. _get_root() {
  61. domain=$1
  62. i=2
  63. p=1
  64. if _ionos_rest GET "$IONOS_ROUTE_ZONES"; then
  65. response="$(echo "$response" | tr -d "\n" | sed 's/{/\n&/g')"
  66. while true; do
  67. h=$(printf "%s" "$domain" | cut -d . -f $i-100)
  68. if [ -z "$h" ]; then
  69. return 1
  70. fi
  71. _zone="$(echo "$response" | _egrep_o "{.*\"name\":\s*\"$h\".*}")"
  72. if [ "$_zone" ]; then
  73. _zone_id=$(printf "%s\n" "$_zone" | _egrep_o "\"id\":\s*\"[a-fA-F0-9-]+\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"')
  74. if [ "$_zone_id" ]; then
  75. _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
  76. _domain=$h
  77. return 0
  78. fi
  79. return 1
  80. fi
  81. p=$i
  82. i=$(_math "$i" + 1)
  83. done
  84. fi
  85. return 1
  86. }
  87. _ionos_get_record() {
  88. fulldomain=$1
  89. zone_id=$2
  90. if _ionos_rest GET "$IONOS_ROUTE_ZONES/$zone_id?recordName=$fulldomain&recordType=TXT"; then
  91. response="$(echo "$response" | tr -d "\n")"
  92. _record="$(echo "$response" | _egrep_o "{\"name\":\s*\"$fulldomain\".*}")"
  93. if [ "$_record" ]; then
  94. _record_id=$(printf "%s\n" "$_record" | _egrep_o "\"id\":\s*\"[a-fA-F0-9-]+\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"')
  95. return 0
  96. fi
  97. fi
  98. return 1
  99. }
  100. _ionos_rest() {
  101. method="$1"
  102. route="$2"
  103. data="$3"
  104. IONOS_API_KEY="$(printf "%s.%s" "$IONOS_PREFIX" "$IONOS_SECRET")"
  105. export _H1="X-API-Key: $IONOS_API_KEY"
  106. if [ "$method" != "GET" ]; then
  107. export _H2="Accept: application/json"
  108. export _H3="Content-Type: application/json"
  109. response="$(_post "$data" "$IONOS_API$route" "" "$method")"
  110. else
  111. export _H2="Accept: */*"
  112. response="$(_get "$IONOS_API$route")"
  113. fi
  114. if [ "$?" != "0" ]; then
  115. _err "Error $route"
  116. return 1
  117. fi
  118. return 0
  119. }