2 # -*- mode: sh; tab-width: 2; indent-tabs-mode: s; coding: utf-8 -*-
5 # DirectAdmin 1.41.0 API
6 # The DirectAdmin interface has it's own Let's encrypt functionality, but this
7 # script can be used to generate certificates for names which are not hosted on
10 # User must provide login data and URL to DirectAdmin incl. port.
11 # You can create login key, by using the Login Keys function
12 # ( https://da.example.com:8443/CMD_LOGIN_KEYS ), which only has access to
13 # - CMD_API_DNS_CONTROL
14 # - CMD_API_SHOW_DOMAINS
16 # See also https://www.directadmin.com/api.php and
17 # https://www.directadmin.com/features.php?id=1298
19 # Report bugs to https://github.com/TigerP/acme.sh/issues
22 # export DA_Api="https://remoteUser:remotePassword@da.example.com:8443"
23 # export DA_Api_Insecure=1
25 # Set DA_Api_Insecure to 1 for insecure and 0 for secure -> difference is
26 # whether ssl cert is checked for validity (0) or whether it is just accepted
29 ######## Public functions #####################
31 # Usage: dns_myapi_add _acme-challenge.www.example.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
32 # Used to add txt record
36 _debug
"Calling: dns_da_add() '${fulldomain}' '${txtvalue}'"
37 _DA_credentials
&& _DA_getDomainInfo
&& _DA_addTxt
40 # Usage: dns_da_rm _acme-challenge.www.example.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
41 # Used to remove the txt record after validation
45 _debug
"Calling: dns_da_rm() '${fulldomain}' '${txtvalue}'"
46 _DA_credentials
&& _DA_getDomainInfo
&& _DA_rmTxt
49 #################### Private functions below ##################################
50 # Usage: _DA_credentials
51 # It will check if the needed settings are available
53 DA_Api
="${DA_Api:-$(_readaccountconf_mutable DA_Api)}"
54 DA_Api_Insecure
="${DA_Api_Insecure:-$(_readaccountconf_mutable DA_Api_Insecure)}"
55 if [ -z "${DA_Api}" ] ||
[ -z "${DA_Api_Insecure}" ]; then
58 _err
"You haven't specified the DirectAdmin Login data, URL and whether you want check the DirectAdmin SSL cert. Please try again."
61 _saveaccountconf_mutable DA_Api
"${DA_Api}"
62 _saveaccountconf_mutable DA_Api_Insecure
"${DA_Api_Insecure}"
63 # Set whether curl should use secure or insecure mode
64 export HTTPS_INSECURE
="${DA_Api_Insecure}"
68 # Usage: _get_root _acme-challenge.www.example.com
69 # Split the full domain to a domain and subdomain
71 # _sub_domain=_acme-challenge.www
77 # Get a list of all the domains
78 # response will contain "list[]=example.com&list[]=example.org"
79 _da_api CMD_API_SHOW_DOMAINS
"" "${domain}"
81 h
=$
(printf "%s" "$domain" | cut
-d .
-f $i-100)
85 _debug
"The given domain $h is not valid"
88 if _contains
"$response" "$h" >/dev
/null
; then
89 _sub_domain
=$
(printf "%s" "$domain" | cut
-d .
-f 1-$p)
100 # Usage: _da_api CMD_API_* data example.com
101 # Use the DirectAdmin API and check the result
103 # response="error=0&text=Result text&details="
108 _debug
"$domain; $data"
109 response
="$(_post "$data" "$DA_Api/$cmd" "" "POST
")"
111 if [ "$?" != "0" ]; then
115 _debug response
"$response"
119 # Parse the result in general
120 # error=0&text=Records Deleted&details=
121 # error=1&text=Cannot View Dns Record&details=No domain provided
122 err_field
="$(_getfield "$response" 1 '&')"
123 txt_field
="$(_getfield "$response" 2 '&')"
124 details_field
="$(_getfield "$response" 3 '&')"
125 error
="$(_getfield "$err_field" 2 '=')"
126 text
="$(_getfield "$txt_field" 2 '=')"
127 details
="$(_getfield "$details_field" 2 '=')"
128 _debug
"error: ${error}, text: ${text}, details: ${details}"
129 if [ "$error" != "0" ]; then
130 _err
"error $response"
134 CMD_API_SHOW_DOMAINS
) ;;
139 # Usage: _DA_getDomainInfo
140 # Get the root zone if possible
141 _DA_getDomainInfo
() {
142 _debug
"First detect the root zone"
143 if ! _get_root
"$fulldomain"; then
144 _err
"invalid domain"
147 _debug
"The root domain: $_domain"
148 _debug
"The sub domain: $_sub_domain"
154 # Use the API to add a record
156 curData
="domain=${_domain}&action=add&type=TXT&name=${_sub_domain}&value=\"${txtvalue}\""
157 _debug
"Calling _DA_addTxt: '${curData}' '${DA_Api}/CMD_API_DNS_CONTROL'"
158 _da_api CMD_API_DNS_CONTROL
"${curData}" "${_domain}"
159 _debug
"Result of _DA_addTxt: '$response'"
160 if _contains
"${response}" 'error=0'; then
161 _debug
"Add TXT succeeded"
164 _debug
"Add TXT failed"
169 # Use the API to remove a record
171 curData
="domain=${_domain}&action=select&txtrecs0=name=${_sub_domain}&value=\"${txtvalue}\""
172 _debug
"Calling _DA_rmTxt: '${curData}' '${DA_Api}/CMD_API_DNS_CONTROL'"
173 if _da_api CMD_API_DNS_CONTROL
"${curData}" "${_domain}"; then
174 _debug
"Result of _DA_rmTxt: '$response'"
176 _err
"Result of _DA_rmTxt: '$response'"
178 if _contains
"${response}" 'error=0'; then
179 _debug
"RM TXT succeeded"
182 _debug
"RM TXT failed"