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.

179 lines
3.9 KiB

  1. #!/usr/bin/env sh
  2. #PowerDNS Mysql backend
  3. #
  4. #
  5. PDNS_Host="example.com"
  6. PDNS_Port=3306
  7. PDNS_User="username"
  8. PDNS_Pass="password"
  9. PDNS_Database="powerdns"
  10. PDNS_Ttl=60
  11. DEFAULT_PDNS_TTL=60
  12. ######## Public functions #####################
  13. #Usage: add _acme-challenge.www.domain.com "123456789ABCDEF0000000000000000000000000000000000000"
  14. #fulldomain
  15. #txtvalue
  16. dns_pdns-mysql_add() {
  17. fulldomain=$1
  18. txtvalue=$2
  19. if [ -z "$PDNS_Host" ]; then
  20. PDNS_Url=""
  21. _err "You didn't specify PowerDNS Mysql address."
  22. _err "Please set PDNS_Host and try again."
  23. return 1
  24. fi
  25. if [ -z "$PDNS_Port" ]; then
  26. PDNS_Url=""
  27. _err "You didn't specify PowerDNS Mysql Port."
  28. _err "Please set PDNS_Port and try again."
  29. return 1
  30. fi
  31. if [ -z "$PDNS_User" ]; then
  32. PDNS_User=""
  33. _err "You didn't specify PowerDNS Mysql username."
  34. _err "Please set PDNS_User and try again."
  35. return 1
  36. fi
  37. if [ -z "$PDNS_Pass" ]; then
  38. PDNS_Pass=""
  39. _err "You didn't specify PowerDNS Mysql password."
  40. _err "Please set PDNS_Pass and try again."
  41. return 1
  42. fi
  43. if [ -z "$PDNS_Database" ]; then
  44. PDNS_Database=""
  45. _err "You didn't specify PowerDNS Mysql database."
  46. _err "Please set PDNS_Database and try again."
  47. return 1
  48. fi
  49. if [ -z "$PDNS_Ttl" ]; then
  50. PDNS_Ttl="$DEFAULT_PDNS_TTL"
  51. fi
  52. #save the api addr and key to the account conf file.
  53. _saveaccountconf PDNS_Host "$PDNS_Host"
  54. _saveaccountconf PDNS_Port "$PDNS_Port"
  55. _saveaccountconf PDNS_User "$PDNS_User"
  56. _saveaccountconf PDNS_Pass "$PDNS_Pass"
  57. _saveaccountconf PDNS_Database "$PDNS_Database"
  58. if [ "$PDNS_Ttl" != "$DEFAULT_PDNS_TTL" ]; then
  59. _saveaccountconf PDNS_Ttl "$PDNS_Ttl"
  60. fi
  61. _debug "Detect root zone"
  62. if ! _get_root "$fulldomain"; then
  63. _err "invalid domain"
  64. return 1
  65. fi
  66. _debug _domain "$_domain"
  67. if ! set_record "$_domain" "$fulldomain" "$txtvalue"; then
  68. return 1
  69. fi
  70. return 0
  71. }
  72. #fulldomain
  73. dns_pdns-mysql_rm() {
  74. fulldomain=$1
  75. _debug "Detect root zone"
  76. if ! _get_root "$fulldomain"; then
  77. _err "invalid domain"
  78. return 1
  79. fi
  80. _debug _domain "$_domain"
  81. if ! rm_record "$_domain" "$fulldomain"; then
  82. return 1
  83. fi
  84. return 0
  85. }
  86. set_record() {
  87. _info "Adding record"
  88. root=$1
  89. full=$2
  90. txtvalue=$3
  91. if ! _pdns_rest "PATCH" "/api/v1/servers/$PDNS_User/zones/$root." "{\"rrsets\": [{\"changetype\": \"REPLACE\", \"name\": \"$full.\", \"type\": \"TXT\", \"ttl\": $PDNS_Ttl, \"records\": [{\"name\": \"$full.\", \"type\": \"TXT\", \"content\": \"\\\"$txtvalue\\\"\", \"disabled\": false, \"ttl\": $PDNS_Ttl}]}]}"; then
  92. _err "Set txt record error."
  93. return 1
  94. fi
  95. if ! notify_slaves "$root"; then
  96. return 1
  97. fi
  98. return 0
  99. }
  100. rm_record() {
  101. _info "Remove record"
  102. root=$1
  103. full=$2
  104. if ! _pdns_rest "PATCH" "/api/v1/servers/$PDNS_User/zones/$root." "{\"rrsets\": [{\"changetype\": \"DELETE\", \"name\": \"$full.\", \"type\": \"TXT\"}]}"; then
  105. _err "Delete txt record error."
  106. return 1
  107. fi
  108. if ! notify_slaves "$root"; then
  109. return 1
  110. fi
  111. return 0
  112. }
  113. notify_slaves() {
  114. root=$1
  115. if ! _pdns_rest "PUT" "/api/v1/servers/$PDNS_User/zones/$root./notify"; then
  116. _err "Notify slaves error."
  117. return 1
  118. fi
  119. return 0
  120. }
  121. #################### Private functions below ##################################
  122. #_acme-challenge.www.domain.com
  123. #returns
  124. # _domain=domain.com
  125. _get_root() {
  126. domain=$1
  127. i=1
  128. _pdns_domains=$(mysql -ss "-h${PDNS_Host}" "-P${PDNS_Port}" "-u${PDNS_User}" "-p${PDNS_Pass}" -e "SELECT name FROM ${PDNS_Database}.domains")
  129. if _pdns_rest "GET" "/api/v1/servers/$PDNS_User/zones"; then
  130. _zones_response="$response"
  131. fi
  132. while true; do
  133. h=$(printf "%s" "$domain" | cut -d . -f $i-100)
  134. if [ -z "$h" ]; then
  135. return 1
  136. fi
  137. if _contains "$_zones_response" "\"name\": \"$h.\""; then
  138. _domain="$h"
  139. return 0
  140. fi
  141. i=$(_math $i + 1)
  142. done
  143. _debug "$domain not found"
  144. return 1
  145. }