Browse Source

Merge remote-tracking branch 'remotes/source/dev' into deploy_nuster

# Conflicts:
#	deploy/README.md
pull/2171/head
CantonBolo 6 years ago
parent
commit
56818c9ad2
  1. 85
      README.md
  2. 63
      acme.sh
  3. 411
      deploy/README.md
  4. 140
      deploy/gcore_cdn.sh
  5. 58
      deploy/mailcow.sh
  6. 2
      deploy/nuster.sh
  7. 1335
      dnsapi/README.md
  8. 204
      dnsapi/dns_desec.sh
  9. 2
      dnsapi/dns_dgon.sh
  10. 2
      dnsapi/dns_gdnsdk.sh
  11. 19
      dnsapi/dns_namecom.sh
  12. 1
      dnsapi/dns_netcup.sh
  13. 244
      dnsapi/dns_openprovider.sh
  14. 164
      dnsapi/dns_ultra.sh
  15. 149
      dnsapi/dns_zone.sh

85
README.md

@ -290,88 +290,9 @@ If your DNS provider supports API access, we can use that API to automatically i
You don't have to do anything manually! You don't have to do anything manually!
### Currently acme.sh supports:
1. CloudFlare.com API
1. DNSPod.cn API
1. CloudXNS.com API
1. GoDaddy.com API
1. PowerDNS.com API
1. OVH, kimsufi, soyoustart and runabove API
1. nsupdate API
1. LuaDNS.com API
1. DNSMadeEasy.com API
1. AWS Route 53
1. aliyun.com(阿里云) API
1. ISPConfig 3.1 API
1. Alwaysdata.com API
1. Linode.com API
1. FreeDNS (https://freedns.afraid.org/)
1. cyon.ch
1. Domain-Offensive/Resellerinterface/Domainrobot API
1. Gandi LiveDNS API
1. Knot DNS API
1. DigitalOcean API (native)
1. ClouDNS.net API
1. Infoblox NIOS API (https://www.infoblox.com/)
1. VSCALE (https://vscale.io/)
1. Dynu API (https://www.dynu.com)
1. DNSimple API
1. NS1.com API
1. DuckDNS.org API
1. Name.com API
1. Dyn Managed DNS API
1. Yandex PDD API (https://pdd.yandex.ru)
1. Hurricane Electric DNS service (https://dns.he.net)
1. UnoEuro API (https://www.unoeuro.com/)
1. INWX (https://www.inwx.de/)
1. Servercow (https://servercow.de)
1. Namesilo (https://www.namesilo.com)
1. InternetX autoDNS API (https://internetx.com)
1. Azure DNS
1. selectel.com(selectel.ru) DNS API
1. zonomi.com DNS API
1. DreamHost.com API
1. DirectAdmin API
1. KingHost (https://www.kinghost.com.br/)
1. Zilore (https://zilore.com)
1. Loopia.se API
1. acme-dns (https://github.com/joohoi/acme-dns)
1. TELE3 (https://www.tele3.cz)
1. EUSERV.EU (https://www.euserv.eu)
1. DNSPod.com API (https://www.dnspod.com)
1. Google Cloud DNS API
1. ConoHa (https://www.conoha.jp)
1. netcup DNS API (https://www.netcup.de)
1. GratisDNS.dk (https://gratisdns.dk)
1. Namecheap API (https://www.namecheap.com/)
1. MyDNS.JP API (https://www.mydns.jp/)
1. hosting.de (https://www.hosting.de)
1. Neodigit.net API (https://www.neodigit.net)
1. Exoscale.com API (https://www.exoscale.com/)
1. PointDNS API (https://pointhq.com/)
1. Active24.cz API (https://www.active24.cz/)
1. do.de API (https://www.do.de/)
1. Nexcess API (https://www.nexcess.net)
1. Thermo.io API (https://www.thermo.io)
1. Futurehosting API (https://www.futurehosting.com)
1. Rackspace Cloud DNS (https://www.rackspace.com)
1. Online.net API (https://online.net/)
1. MyDevil.net (https://www.mydevil.net/)
1. Core-Networks.de (https://core-networks.de)
1. NederHost API (https://www.nederhost.nl/)
And:
**lexicon DNS API: https://github.com/Neilpang/acme.sh/wiki/How-to-use-lexicon-dns-api
(DigitalOcean, DNSimple, DNSMadeEasy, DNSPark, EasyDNS, Namesilo, NS1, PointHQ, Rage4 and Vultr etc.)**
**More APIs coming soon...**
If your DNS provider is not on the supported list above, you can write your own DNS API script easily. If you do, please consider submitting a [Pull Request](https://github.com/Neilpang/acme.sh/pulls) and contribute it to the project.
For more details: [How to use DNS API](dnsapi)
### Currently acme.sh supports most of the dns providers:
https://github.com/Neilpang/acme.sh/wiki/dnsapi
# 9. Use DNS manual mode: # 9. Use DNS manual mode:

63
acme.sh

@ -2111,7 +2111,7 @@ _startserver() {
echo 'HTTP/1.0 200 OK'; \ echo 'HTTP/1.0 200 OK'; \
echo 'Content-Length\: $_content_len'; \ echo 'Content-Length\: $_content_len'; \
echo ''; \ echo ''; \
printf '$content';" &
printf -- '$content';" &
serverproc="$!" serverproc="$!"
} }
@ -3750,8 +3750,9 @@ issue() {
_on_issue_err "$_post_hook" _on_issue_err "$_post_hook"
return 1 return 1
fi fi
Le_OrderFinalize="$(echo "$response" | tr -d '\r\n' | _egrep_o '"finalize" *: *"[^"]*"' | cut -d '"' -f 4)"
Le_LinkOrder="$(echo "$responseHeaders" | grep -i '^Location.*$' | _tail_n 1 | tr -d "\r\n" | cut -d " " -f 2)"
_debug Le_LinkOrder "$Le_LinkOrder"
Le_OrderFinalize="$(echo "$response" | _egrep_o '"finalize" *: *"[^"]*"' | cut -d '"' -f 4)"
_debug Le_OrderFinalize "$Le_OrderFinalize" _debug Le_OrderFinalize "$Le_OrderFinalize"
if [ -z "$Le_OrderFinalize" ]; then if [ -z "$Le_OrderFinalize" ]; then
_err "Create new order error. Le_OrderFinalize not found. $response" _err "Create new order error. Le_OrderFinalize not found. $response"
@ -3763,7 +3764,7 @@ issue() {
#for dns manual mode #for dns manual mode
_savedomainconf "Le_OrderFinalize" "$Le_OrderFinalize" _savedomainconf "Le_OrderFinalize" "$Le_OrderFinalize"
_authorizations_seg="$(echo "$response" | tr -d '\r\n' | _egrep_o '"authorizations" *: *\[[^\]*\]' | cut -d '[' -f 2 | tr -d ']' | tr -d '"')"
_authorizations_seg="$(echo "$response" | _egrep_o '"authorizations" *: *\[[^\]*\]' | cut -d '[' -f 2 | tr -d ']' | tr -d '"')"
_debug2 _authorizations_seg "$_authorizations_seg" _debug2 _authorizations_seg "$_authorizations_seg"
if [ -z "$_authorizations_seg" ]; then if [ -z "$_authorizations_seg" ]; then
_err "_authorizations_seg not found." _err "_authorizations_seg not found."
@ -3849,7 +3850,7 @@ $_authorizations_map"
thumbprint="$(__calc_account_thumbprint)" thumbprint="$(__calc_account_thumbprint)"
fi fi
entry="$(printf "%s\n" "$response" | _egrep_o '[^\{]*"type":"'$vtype'"[^\}]*')"
entry="$(echo "$response" | _egrep_o '[^\{]*"type":"'$vtype'"[^\}]*')"
_debug entry "$entry" _debug entry "$entry"
if [ -z "$entry" ]; then if [ -z "$entry" ]; then
_err "Error, can not get domain token entry $d" _err "Error, can not get domain token entry $d"
@ -3861,7 +3862,7 @@ $_authorizations_map"
_on_issue_err "$_post_hook" _on_issue_err "$_post_hook"
return 1 return 1
fi fi
token="$(printf "%s\n" "$entry" | _egrep_o '"token":"[^"]*' | cut -d : -f 2 | tr -d '"')"
token="$(echo "$entry" | _egrep_o '"token":"[^"]*' | cut -d : -f 2 | tr -d '"')"
_debug token "$token" _debug token "$token"
if [ -z "$token" ]; then if [ -z "$token" ]; then
@ -3871,9 +3872,9 @@ $_authorizations_map"
return 1 return 1
fi fi
if [ "$ACME_VERSION" = "2" ]; then if [ "$ACME_VERSION" = "2" ]; then
uri="$(printf "%s\n" "$entry" | _egrep_o '"url":"[^"]*' | cut -d '"' -f 4 | _head_n 1)"
uri="$(echo "$entry" | _egrep_o '"url":"[^"]*' | cut -d '"' -f 4 | _head_n 1)"
else else
uri="$(printf "%s\n" "$entry" | _egrep_o '"uri":"[^"]*' | cut -d '"' -f 4)"
uri="$(echo "$entry" | _egrep_o '"uri":"[^"]*' | cut -d '"' -f 4)"
fi fi
_debug uri "$uri" _debug uri "$uri"
@ -3931,21 +3932,21 @@ $_authorizations_map"
else else
txtdomain="_acme-challenge.$_d_alias" txtdomain="_acme-challenge.$_d_alias"
fi fi
dns_entries="${dns_entries}${_dns_root_d}${dvsep}_acme-challenge.$_dns_root_d$dvsep$txtdomain$dvsep$_currentRoot"
dns_entry="${_dns_root_d}${dvsep}_acme-challenge.$_dns_root_d$dvsep$txtdomain$dvsep$_currentRoot"
else else
txtdomain="_acme-challenge.$_dns_root_d" txtdomain="_acme-challenge.$_dns_root_d"
dns_entries="${dns_entries}${_dns_root_d}${dvsep}_acme-challenge.$_dns_root_d$dvsep$dvsep$_currentRoot"
dns_entry="${_dns_root_d}${dvsep}_acme-challenge.$_dns_root_d$dvsep$dvsep$_currentRoot"
fi fi
_debug txtdomain "$txtdomain" _debug txtdomain "$txtdomain"
txt="$(printf "%s" "$keyauthorization" | _digest "sha256" | _url_replace)" txt="$(printf "%s" "$keyauthorization" | _digest "sha256" | _url_replace)"
_debug txt "$txt" _debug txt "$txt"
d_api="$(_findHook "$_dns_root_d" dnsapi "$_currentRoot")" d_api="$(_findHook "$_dns_root_d" dnsapi "$_currentRoot")"
_debug d_api "$d_api" _debug d_api "$d_api"
dns_entries="$dns_entries$dvsep$txt${dvsep}$d_api
"
_debug2 "$dns_entries"
dns_entry="$dns_entry$dvsep$txt${dvsep}$d_api"
_debug2 dns_entry "$dns_entry"
if [ "$d_api" ]; then if [ "$d_api" ]; then
_info "Found domain api file: $d_api" _info "Found domain api file: $d_api"
else else
@ -3984,6 +3985,9 @@ $_authorizations_map"
_clearup _clearup
return 1 return 1
fi fi
dns_entries="$dns_entries$dns_entry
"
_debug2 "$dns_entries"
dnsadded='1' dnsadded='1'
fi fi
done done
@ -4194,7 +4198,7 @@ $_authorizations_map"
fi fi
if [ "$status" = "invalid" ]; then if [ "$status" = "invalid" ]; then
error="$(echo "$response" | tr -d "\r\n" | _egrep_o '"error":\{[^\}]*')"
error="$(echo "$response" | _egrep_o '"error":\{[^\}]*')"
_debug2 error "$error" _debug2 error "$error"
errordetail="$(echo "$error" | _egrep_o '"detail": *"[^"]*' | cut -d '"' -f 4)" errordetail="$(echo "$error" | _egrep_o '"detail": *"[^"]*' | cut -d '"' -f 4)"
_debug2 errordetail "$errordetail" _debug2 errordetail "$errordetail"
@ -4246,13 +4250,10 @@ $_authorizations_map"
_on_issue_err "$_post_hook" _on_issue_err "$_post_hook"
return 1 return 1
fi fi
Le_LinkOrder="$(echo "$responseHeaders" | grep -i '^Location.*$' | _tail_n 1 | tr -d "\r\n" | cut -d " " -f 2)"
if [ -z "$Le_LinkOrder" ]; then if [ -z "$Le_LinkOrder" ]; then
_err "Sign error, can not get order link location header"
_err "responseHeaders" "$responseHeaders"
_on_issue_err "$_post_hook"
return 1
Le_LinkOrder="$(echo "$responseHeaders" | grep -i '^Location.*$' | _tail_n 1 | tr -d "\r\n" | cut -d " " -f 2)"
fi fi
_savedomainconf "Le_LinkOrder" "$Le_LinkOrder" _savedomainconf "Le_LinkOrder" "$Le_LinkOrder"
_link_cert_retry=0 _link_cert_retry=0
@ -4260,7 +4261,7 @@ $_authorizations_map"
while [ "$_link_cert_retry" -lt "$_MAX_CERT_RETRY" ]; do while [ "$_link_cert_retry" -lt "$_MAX_CERT_RETRY" ]; do
if _contains "$response" "\"status\":\"valid\""; then if _contains "$response" "\"status\":\"valid\""; then
_debug "Order status is valid." _debug "Order status is valid."
Le_LinkCert="$(echo "$response" | tr -d '\r\n' | _egrep_o '"certificate" *: *"[^"]*"' | cut -d '"' -f 4)"
Le_LinkCert="$(echo "$response" | _egrep_o '"certificate" *: *"[^"]*"' | cut -d '"' -f 4)"
_debug Le_LinkCert "$Le_LinkCert" _debug Le_LinkCert "$Le_LinkCert"
if [ -z "$Le_LinkCert" ]; then if [ -z "$Le_LinkCert" ]; then
_err "Sign error, can not find Le_LinkCert" _err "Sign error, can not find Le_LinkCert"
@ -4278,6 +4279,14 @@ $_authorizations_map"
_on_issue_err "$_post_hook" _on_issue_err "$_post_hook"
return 1 return 1
fi fi
#the order is processing, so we are going to poll order status
if [ -z "$Le_LinkOrder" ]; then
_err "Sign error, can not get order link location header"
_err "responseHeaders" "$responseHeaders"
_on_issue_err "$_post_hook"
return 1
fi
_info "Polling order status: $Le_LinkOrder"
if ! _send_signed_request "$Le_LinkOrder"; then if ! _send_signed_request "$Le_LinkOrder"; then
_err "Sign failed, can not post to Le_LinkOrder cert:$Le_LinkOrder." _err "Sign failed, can not post to Le_LinkOrder cert:$Le_LinkOrder."
_err "$response" _err "$response"
@ -5195,7 +5204,7 @@ _deactivate() {
_err "Can not get domain new order." _err "Can not get domain new order."
return 1 return 1
fi fi
_authorizations_seg="$(echo "$response" | tr -d '\r\n' | _egrep_o '"authorizations" *: *\[[^\]*\]' | cut -d '[' -f 2 | tr -d ']' | tr -d '"')"
_authorizations_seg="$(echo "$response" | _egrep_o '"authorizations" *: *\[[^\]*\]' | cut -d '[' -f 2 | tr -d ']' | tr -d '"')"
_debug2 _authorizations_seg "$_authorizations_seg" _debug2 _authorizations_seg "$_authorizations_seg"
if [ -z "$_authorizations_seg" ]; then if [ -z "$_authorizations_seg" ]; then
_err "_authorizations_seg not found." _err "_authorizations_seg not found."
@ -5241,16 +5250,16 @@ _deactivate() {
fi fi
_debug "Trigger validation." _debug "Trigger validation."
vtype="$VTYPE_DNS" vtype="$VTYPE_DNS"
entry="$(printf "%s\n" "$response" | _egrep_o '[^\{]*"type":"'$vtype'"[^\}]*')"
entry="$(echo "$response" | _egrep_o '[^\{]*"type":"'$vtype'"[^\}]*')"
_debug entry "$entry" _debug entry "$entry"
if [ -z "$entry" ]; then if [ -z "$entry" ]; then
_err "Error, can not get domain token $d" _err "Error, can not get domain token $d"
return 1 return 1
fi fi
token="$(printf "%s\n" "$entry" | _egrep_o '"token":"[^"]*' | cut -d : -f 2 | tr -d '"')"
token="$(echo "$entry" | _egrep_o '"token":"[^"]*' | cut -d : -f 2 | tr -d '"')"
_debug token "$token" _debug token "$token"
uri="$(printf "%s\n" "$entry" | _egrep_o "\"$_URL_NAME\":\"[^\"]*" | cut -d : -f 2,3 | tr -d '"')"
uri="$(echo "$entry" | _egrep_o "\"$_URL_NAME\":\"[^\"]*" | cut -d : -f 2,3 | tr -d '"')"
_debug uri "$uri" _debug uri "$uri"
keyauthorization="$token.$thumbprint" keyauthorization="$token.$thumbprint"
@ -5272,11 +5281,11 @@ _deactivate() {
break break
fi fi
_vtype="$(printf "%s\n" "$entry" | _egrep_o '"type": *"[^"]*"' | cut -d : -f 2 | tr -d '"')"
_vtype="$(echo "$entry" | _egrep_o '"type": *"[^"]*"' | cut -d : -f 2 | tr -d '"')"
_debug _vtype "$_vtype" _debug _vtype "$_vtype"
_info "Found $_vtype" _info "Found $_vtype"
uri="$(printf "%s\n" "$entry" | _egrep_o "\"$_URL_NAME\":\"[^\"]*" | cut -d : -f 2,3 | tr -d '"')"
uri="$(echo "$entry" | _egrep_o "\"$_URL_NAME\":\"[^\"]*" | cut -d : -f 2,3 | tr -d '"')"
_debug uri "$uri" _debug uri "$uri"
if [ "$_d_type" ] && [ "$_d_type" != "$_vtype" ]; then if [ "$_d_type" ] && [ "$_d_type" != "$_vtype" ]; then

411
deploy/README.md

@ -1,413 +1,6 @@
# Using deploy api # Using deploy api
Before you can deploy your cert, you must [issue the cert first](https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert).
deploy hook usage:
Here are the scripts to deploy the certs/key to the server/services.
https://github.com/Neilpang/acme.sh/wiki/deployhooks
## 1. Deploy the certs to your cpanel host
If you want to deploy using cpanel UAPI see 7.
(cpanel deploy hook is not finished yet, this is just an example.)
Then you can deploy now:
```sh
export DEPLOY_CPANEL_USER=myusername
export DEPLOY_CPANEL_PASSWORD=PASSWORD
acme.sh --deploy -d example.com --deploy-hook cpanel
```
## 2. Deploy ssl cert on kong proxy engine based on api
Before you can deploy your cert, you must [issue the cert first](https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert).
Currently supports Kong-v0.10.x.
```sh
acme.sh --deploy -d ftp.example.com --deploy-hook kong
```
## 3. Deploy the cert to remote server through SSH access
The ssh deploy plugin allows you to deploy certificates to a remote host
using SSH command to connect to the remote server. The ssh plugin is invoked
with the following command...
```sh
acme.sh --deploy -d example.com --deploy-hook ssh
```
Prior to running this for the first time you must tell the plugin where
and how to deploy the certificates. This is done by exporting the following
environment variables. This is not required for subsequent runs as the
values are stored by acme.sh in the domain configuration files.
Required...
```
export DEPLOY_SSH_USER=username
```
Optional...
```
export DEPLOY_SSH_CMD=custom ssh command
export DEPLOY_SSH_SERVER=url or ip address of remote host
export DEPLOY_SSH_KEYFILE=filename for private key
export DEPLOY_SSH_CERTFILE=filename for certificate file
export DEPLOY_SSH_CAFILE=filename for intermediate CA file
export DEPLOY_SSH_FULLCHAIN=filename for fullchain file
export DEPLOY_SSH_REMOTE_CMD=command to execute on remote host
export DEPLOY_SSH_BACKUP=yes or no
```
**DEPLOY_SSH_USER**
Username at the remote host that SSH will login with. Note that
SSH must be able to login to remote host without a password... SSH Keys
must have been exchanged with the remote host. Validate and test that you
can login to USER@URL from the host running acme.sh before using this script.
The USER@URL at the remote server must also have has permissions to write to
the target location of the certificate files and to execute any commands
(e.g. to stop/start services).
**DEPLOY_SSH_CMD**
You can customize the ssh command used to connect to the remote host. For example
if you need to connect to a specific port at the remote server you can set this
to, for example, "ssh -p 22" or to use `sshpass` to provide password inline
instead of exchanging ssh keys (this is not recommended, using keys is
more secure).
**DEPLOY_SSH_SERVER**
URL or IP Address of the remote server. If not provided then the domain
name provided on the acme.sh --deploy command line is used.
**DEPLOY_SSH_KEYFILE**
Target filename for the private key issued by LetsEncrypt.
**DEPLOY_SSH_CERTFILE**
Target filename for the certificate issued by LetsEncrypt.
If this is the same as the previous filename (for keyfile) then it is
appended to the same file.
**DEPLOY_SSH_CAFILE**
Target filename for the CA intermediate certificate issued by LetsEncrypt.
If this is the same as a previous filename (for keyfile or certfile) then
it is appended to the same file.
**DEPLOY_SSH_FULLCHAIN**
Target filename for the fullchain certificate issued by LetsEncrypt.
If this is the same as a previous filename (for keyfile, certfile or
cafile) then it is appended to the same file.
**DEPLOY_SSH_REMOTE_CMD**
Command to execute on the remote server after copying any certificates. This
could be any additional command required for example to stop and restart
the service.
**DEPLOY_SSH_BACKUP**
Before writing a certificate file to the remote server the existing
certificate will be copied to a backup directory on the remote server.
These are placed in a hidden directory in the home directory of the SSH
user
```sh
~/.acme_ssh_deploy/[domain name]-backup-[timestamp]
```
Any backups older than 180 days will be deleted when new certificates
are deployed. This defaults to "yes" set to "no" to disable backup.
###Examples using SSH deploy
The following example illustrates deploying certificates to a QNAP NAS
(tested with QTS version 4.2.3)
```sh
export DEPLOY_SSH_USER="admin"
export DEPLOY_SSH_KEYFILE="/etc/stunnel/stunnel.pem"
export DEPLOY_SSH_CERTFILE="/etc/stunnel/stunnel.pem"
export DEPLOY_SSH_CAFILE="/etc/stunnel/uca.pem"
export DEPLOY_SSH_REMOTE_CMD="/etc/init.d/stunnel.sh restart"
acme.sh --deploy -d qnap.example.com --deploy-hook ssh
```
Note how in this example both the private key and certificate point to
the same file. This will result in the certificate being appended
to the same file as the private key... a common requirement of several
services.
The next example illustrates deploying certificates to a Unifi
Controller (tested with version 5.4.11).
```sh
export DEPLOY_SSH_USER="root"
export DEPLOY_SSH_KEYFILE="/var/lib/unifi/unifi.example.com.key"
export DEPLOY_SSH_FULLCHAIN="/var/lib/unifi/unifi.example.com.cer"
export DEPLOY_SSH_REMOTE_CMD="openssl pkcs12 -export \
-inkey /var/lib/unifi/unifi.example.com.key \
-in /var/lib/unifi/unifi.example.com.cer \
-out /var/lib/unifi/unifi.example.com.p12 \
-name ubnt -password pass:temppass \
&& keytool -importkeystore -deststorepass aircontrolenterprise \
-destkeypass aircontrolenterprise \
-destkeystore /var/lib/unifi/keystore \
-srckeystore /var/lib/unifi/unifi.example.com.p12 \
-srcstoretype PKCS12 -srcstorepass temppass -alias ubnt -noprompt \
&& service unifi restart"
acme.sh --deploy -d unifi.example.com --deploy-hook ssh
```
In this example we execute several commands on the remote host
after the certificate files have been copied... to generate a pkcs12 file
compatible with Unifi, to import it into the Unifi keystore and then finally
to restart the service.
Note also that once the certificate is imported
into the keystore the individual certificate files are no longer
required. We could if we desired delete those files immediately. If we
do that then we should disable backup at the remote host (as there are
no files to backup -- they were erased during deployment). For example...
```sh
export DEPLOY_SSH_BACKUP=no
# modify the end of the remote command...
&& rm /var/lib/unifi/unifi.example.com.key \
/var/lib/unifi/unifi.example.com.cer \
/var/lib/unifi/unifi.example.com.p12 \
&& service unifi restart
```
## 4. Deploy the cert to local vsftpd server
```sh
acme.sh --deploy -d ftp.example.com --deploy-hook vsftpd
```
The default vsftpd conf file is `/etc/vsftpd.conf`, if your vsftpd conf is not in the default location, you can specify one:
```sh
export DEPLOY_VSFTPD_CONF="/etc/vsftpd.conf"
acme.sh --deploy -d ftp.example.com --deploy-hook vsftpd
```
The default command to restart vsftpd server is `service vsftpd restart`, if it doesn't work, you can specify one:
```sh
export DEPLOY_VSFTPD_RELOAD="/etc/init.d/vsftpd restart"
acme.sh --deploy -d ftp.example.com --deploy-hook vsftpd
```
## 5. Deploy the cert to local exim4 server
```sh
acme.sh --deploy -d ftp.example.com --deploy-hook exim4
```
The default exim4 conf file is `/etc/exim/exim.conf`, if your exim4 conf is not in the default location, you can specify one:
```sh
export DEPLOY_EXIM4_CONF="/etc/exim4/exim4.conf.template"
acme.sh --deploy -d ftp.example.com --deploy-hook exim4
```
The default command to restart exim4 server is `service exim4 restart`, if it doesn't work, you can specify one:
```sh
export DEPLOY_EXIM4_RELOAD="/etc/init.d/exim4 restart"
acme.sh --deploy -d ftp.example.com --deploy-hook exim4
```
## 6. Deploy the cert to OSX Keychain
```sh
acme.sh --deploy -d ftp.example.com --deploy-hook keychain
```
## 7. Deploy to cpanel host using UAPI
This hook is using UAPI and works in cPanel & WHM version 56 or newer.
```
acme.sh --deploy -d example.com --deploy-hook cpanel_uapi
```
DEPLOY_CPANEL_USER is required only if you run the script as root and it should contain cpanel username.
```sh
export DEPLOY_CPANEL_USER=username
acme.sh --deploy -d example.com --deploy-hook cpanel_uapi
```
Please note, that the cpanel_uapi hook will deploy only the first domain when your certificate will automatically renew. Therefore you should issue a separate certificate for each domain.
## 8. Deploy the cert to your FRITZ!Box router
You must specify the credentials that have administrative privileges on the FRITZ!Box in order to deploy the certificate, plus the URL of your FRITZ!Box, through the following environment variables:
```sh
$ export DEPLOY_FRITZBOX_USERNAME=my_username
$ export DEPLOY_FRITZBOX_PASSWORD=the_password
$ export DEPLOY_FRITZBOX_URL=https://fritzbox.example.com
```
After the first deployment, these values will be stored in your $HOME/.acme.sh/account.conf. You may now deploy the certificate like this:
```sh
acme.sh --deploy -d fritzbox.example.com --deploy-hook fritzbox
```
## 9. Deploy the cert to strongswan
```sh
acme.sh --deploy -d ftp.example.com --deploy-hook strongswan
```
## 10. Deploy the cert to HAProxy
You must specify the path where you want the concatenated key and certificate chain written.
```sh
export DEPLOY_HAPROXY_PEM_PATH=/etc/haproxy
```
You may optionally define the command to reload HAProxy. The value shown below will be used as the default if you don't set this environment variable.
```sh
export DEPLOY_HAPROXY_RELOAD="/usr/sbin/service haproxy restart"
```
You can then deploy the certificate as follows
```sh
acme.sh --deploy -d haproxy.example.com --deploy-hook haproxy
```
The path for the PEM file will be stored with the domain configuration and will be available when renewing, so that deploy will happen automatically when renewed.
## 11. Deploy your cert to Gitlab pages
You must define the API key and the informations for the project and Gitlab page you are updating the certificate for.
```sh
# The token can be created in your user settings under "Access Tokens"
export GITLAB_TOKEN="xxxxxxxxxxx"
# The project ID is displayed on the home page of the project
export GITLAB_PROJECT_ID=12345678
# The domain must match the one defined for the Gitlab page, without "https://"
export GITLAB_DOMAIN="www.mydomain.com"
```
You can then deploy the certificate as follows
```sh
acme.sh --deploy -d www.mydomain.com --deploy-hook gitlab
```
## 12. Deploy your cert to Hashicorp Vault
```sh
export VAULT_PREFIX="acme"
```
You can then deploy the certificate as follows
```sh
acme.sh --deploy -d www.mydomain.com --deploy-hook vault_cli
```
Your certs will be saved in Vault using this structure:
```sh
vault write "${VAULT_PREFIX}/${domain}/cert.pem" value=@"..."
vault write "${VAULT_PREFIX}/${domain}/cert.key" value=@"..."
vault write "${VAULT_PREFIX}/${domain}/chain.pem" value=@"..."
vault write "${VAULT_PREFIX}/${domain}/fullchain.pem" value=@"..."
```
You might be using Fabio load balancer (which can get certs from
Vault). It needs a bit different structure of your certs in Vault. It
gets certs only from keys that were saved in `prefix/domain`, like this:
```bash
vault write <PREFIX>/www.domain.com cert=@cert.pem key=@key.pem
```
If you want to save certs in Vault this way just set "FABIO" env
variable to anything (ex: "1") before running `acme.sh`:
```sh
export FABIO="1"
```
## 13. Deploy your certificate to Qiniu.com
使用 acme.sh 部署到七牛之前,需要确保部署的域名已打开 HTTPS 功能,您可以访问[融合 CDN - 域名管理](https://portal.qiniu.com/cdn/domain) 设置。
另外还需要先导出 AK/SK 环境变量,您可以访问[密钥管理](https://portal.qiniu.com/user/key) 获得。
```sh
$ export QINIU_AK="foo"
$ export QINIU_SK="bar"
```
完成准备工作之后,您就可以通过下面的命令开始部署 SSL 证书到七牛上:
```sh
$ acme.sh --deploy -d example.com --deploy-hook qiniu
```
假如您部署的证书为泛域名证书,您还需要设置 `QINIU_CDN_DOMAIN` 变量,指定实际需要部署的域名(请注意泛域名前的点):
```sh
$ export QINIU_CDN_DOMAIN=".cdn.example.com"
$ acme.sh --deploy -d example.com --deploy-hook qiniu
```
### English version
You should create AccessKey/SecretKey pair in https://portal.qiniu.com/user/key
before deploying your certificate, and please ensure you have enabled HTTPS for
your domain name. You can enable it in https://portal.qiniu.com/cdn/domain.
```sh
$ export QINIU_AK="foo"
$ export QINIU_SK="bar"
```
then you can deploy certificate by following command:
```sh
$ acme.sh --deploy -d example.com --deploy-hook qiniu
```
(Optional), If you are using wildcard certificate,
you may need export `QINIU_CDN_DOMAIN` to specify which domain
you want to update (please note the leading dot):
```sh
$ export QINIU_CDN_DOMAIN=".cdn.example.com"
$ acme.sh --deploy -d example.com --deploy-hook qiniu
```
## 14. Deploy your cert on MyDevil.net
Once you have acme.sh installed and certificate issued (see info in [DNS API](../dnsapi/README.md#61-use-mydevilnet)), you can install it by following command:
```sh
acme.sh --deploy --deploy-hook mydevil -d example.com
```
That will remove old certificate and install new one.
## 15. Deploy the cert to nuster
You must specify the path where you want the concatenated key and certificate chain written.
```sh
export DEPLOY_NUSTER_PEM_PATH=/etc/nuster
```
You may optionally define the command to reload nuster. The value shown below will be used as the default if you don't set this environment variable.
```sh
export DEPLOY_NUSTER_RELOAD="/usr/sbin/service nuster restart"
```
You can then deploy the certificate as follows
```sh
acme.sh --deploy -d nuster.example.com --deploy-hook nuster
```
The path for the PEM file will be stored with the domain configuration and will be available when renewing, so that deploy will happen automatically when renewed.

140
deploy/gcore_cdn.sh

@ -0,0 +1,140 @@
#!/usr/bin/env sh
# Here is the script to deploy the cert to G-Core CDN service (https://gcorelabs.com/ru/) using the G-Core Labs API (https://docs.gcorelabs.com/cdn/).
# Uses command line curl for send requests and jq for parse responses.
# Returns 0 when success.
#
# Written by temoffey <temofffey@gmail.com>
# Public domain, 2019
#export DEPLOY_GCORE_CDN_USERNAME=myusername
#export DEPLOY_GCORE_CDN_PASSWORD=mypassword
######## Public functions #####################
#domain keyfile certfile cafile fullchain
gcore_cdn_deploy() {
_cdomain="$1"
_ckey="$2"
_ccert="$3"
_cca="$4"
_cfullchain="$5"
_debug _cdomain "$_cdomain"
_debug _ckey "$_ckey"
_debug _ccert "$_ccert"
_debug _cca "$_cca"
_debug _cfullchain "$_cfullchain"
_fullchain=$(tr '\n\r' '@#' <"$_cfullchain" | sed 's/@/\\n/g;s/#/\\r/g')
_key=$(tr '\n\r' '@#' <"$_ckey" | sed 's/@/\\n/g;s/#/\\r/g')
_debug _fullchain "$_fullchain"
_debug _key "$_key"
if [ -z "$DEPLOY_GCORE_CDN_USERNAME" ]; then
if [ -z "$Le_Deploy_gcore_cdn_username" ]; then
_err "Please define the target username: export DEPLOY_GCORE_CDN_USERNAME=username"
return 1
fi
else
Le_Deploy_gcore_cdn_username="$DEPLOY_GCORE_CDN_USERNAME"
_savedomainconf Le_Deploy_gcore_cdn_username "$Le_Deploy_gcore_cdn_username"
fi
if [ -z "$DEPLOY_GCORE_CDN_PASSWORD" ]; then
if [ -z "$Le_Deploy_gcore_cdn_password" ]; then
_err "Please define the target password: export DEPLOY_GCORE_CDN_PASSWORD=password"
return 1
fi
else
Le_Deploy_gcore_cdn_password="$DEPLOY_GCORE_CDN_PASSWORD"
_savedomainconf Le_Deploy_gcore_cdn_password "$Le_Deploy_gcore_cdn_password"
fi
_info "Get authorization token"
_request="{\"username\":\"$Le_Deploy_gcore_cdn_username\",\"password\":\"$Le_Deploy_gcore_cdn_password\"}"
_debug _request "$_request"
export _H1="Content-Type:application/json"
_response=$(_post "$_request" "https://api.gcdn.co/auth/signin")
_debug _response "$_response"
_regex=".*\"token\":\"\([-._0-9A-Za-z]*\)\".*$"
_debug _regex "$_regex"
_token=$(echo "$_response" | sed -n "s/$_regex/\1/p")
_debug _token "$_token"
if [ -z "$_token" ]; then
_err "Error G-Core Labs API authorization"
return 1
fi
_info "Find CDN resource with cname $_cdomain"
export _H2="Authorization:Token $_token"
_response=$(_get "https://api.gcdn.co/resources")
_debug _response "$_response"
_regex=".*(\"id\".*?\"cname\":\"$_cdomain\".*?})"
_regex="^.*\"cname\":\"$_cdomain\".*$"
_debug _regex "$_regex"
_resource=$(echo "$_response" | sed 's/},{/},\n{/g' | _egrep_o "$_regex")
_debug _resource "$_resource"
_regex=".*\"id\":\([0-9]*\),.*$"
_debug _regex "$_regex"
_resourceId=$(echo "$_resource" | sed -n "s/$_regex/\1/p")
_debug _resourceId "$_resourceId"
_regex=".*\"sslData\":\([0-9]*\)}.*$"
_debug _regex "$_regex"
_sslDataOld=$(echo "$_resource" | sed -n "s/$_regex/\1/p")
_debug _sslDataOld "$_sslDataOld"
_regex=".*\"originGroup\":\([0-9]*\),.*$"
_debug _regex "$_regex"
_originGroup=$(echo "$_resource" | sed -n "s/$_regex/\1/p")
_debug _originGroup "$_originGroup"
if [ -z "$_resourceId" ] || [ -z "$_originGroup" ]; then
_err "Not found CDN resource with cname $_cdomain"
return 1
fi
_info "Add new SSL certificate"
_date=$(date "+%d.%m.%Y %H:%M:%S")
_request="{\"name\":\"$_cdomain ($_date)\",\"sslCertificate\":\"$_fullchain\",\"sslPrivateKey\":\"$_key\"}"
_debug _request "$_request"
_response=$(_post "$_request" "https://api.gcdn.co/sslData")
_debug _response "$_response"
_regex=".*\"id\":\([0-9]*\),.*$"
_debug _regex "$_regex"
_sslDataAdd=$(echo "$_response" | sed -n "s/$_regex/\1/p")
_debug _sslDataAdd "$_sslDataAdd"
if [ -z "$_sslDataAdd" ]; then
_err "Error new SSL certificate add"
return 1
fi
_info "Update CDN resource"
_request="{\"originGroup\":$_originGroup,\"sslData\":$_sslDataAdd}"
_debug _request "$_request"
_response=$(_post "$_request" "https://api.gcdn.co/resources/$_resourceId" '' "PUT")
_debug _response "$_response"
_regex=".*\"sslData\":\([0-9]*\)}.*$"
_debug _regex "$_regex"
_sslDataNew=$(echo "$_response" | sed -n "s/$_regex/\1/p")
_debug _sslDataNew "$_sslDataNew"
if [ "$_sslDataNew" != "$_sslDataAdd" ]; then
_err "Error CDN resource update"
return 1
fi
if [ -z "$_sslDataOld" ] || [ "$_sslDataOld" = "null" ]; then
_info "Not found old SSL certificate"
else
_info "Delete old SSL certificate"
_response=$(_post '' "https://api.gcdn.co/sslData/$_sslDataOld" '' "DELETE")
_debug _response "$_response"
fi
_info "Certificate successfully deployed"
return 0
}

58
deploy/mailcow.sh

@ -0,0 +1,58 @@
#!/usr/bin/env sh
#Here is a script to deploy cert to mailcow.
#returns 0 means success, otherwise error.
######## Public functions #####################
#domain keyfile certfile cafile fullchain
mailcow_deploy() {
_cdomain="$1"
_ckey="$2"
_ccert="$3"
_cca="$4"
_cfullchain="$5"
_debug _cdomain "$_cdomain"
_debug _ckey "$_ckey"
_debug _ccert "$_ccert"
_debug _cca "$_cca"
_debug _cfullchain "$_cfullchain"
_mailcow_path="${DEPLOY_MAILCOW_PATH}"
if [ -z "$_mailcow_path" ]; then
_err "Mailcow path is not found, please define DEPLOY_MAILCOW_PATH."
return 1
fi
_ssl_path="${_mailcow_path}/data/assets/ssl/"
if [ ! -d "$_ssl_path" ]; then
_err "Cannot find mailcow ssl path: $_ssl_path"
return 1
fi
_info "Copying key and cert"
_real_key="$_ssl_path/key.pem"
if ! cat "$_ckey" >"$_real_key"; then
_err "Error: write key file to: $_real_key"
return 1
fi
_real_fullchain="$_ssl_path/cert.pem"
if ! cat "$_cfullchain" >"$_real_fullchain"; then
_err "Error: write cert file to: $_real_fullchain"
return 1
fi
DEFAULT_MAILCOW_RELOAD="cd ${_mailcow_path} && docker-compose restart postfix-mailcow dovecot-mailcow nginx-mailcow"
_reload="${DEPLOY_MAILCOW_RELOAD:-$DEFAULT_MAILCOW_RELOAD}"
_info "Run reload: $_reload"
if eval "$_reload"; then
_info "Reload success!"
fi
return 0
}

2
deploy/nuster.sh

@ -45,7 +45,7 @@ nuster_deploy() {
chmod 600 "$_pem_full_path" chmod 600 "$_pem_full_path"
_info "Certificate successfully deployed" _info "Certificate successfully deployed"
# restart HAProxy
# restart nuster
_info "Run reload: $_reload" _info "Run reload: $_reload"
if eval "$_reload"; then if eval "$_reload"; then
_info "Reload success!" _info "Reload success!"

1335
dnsapi/README.md
File diff suppressed because it is too large
View File

204
dnsapi/dns_desec.sh

@ -0,0 +1,204 @@
#!/usr/bin/env sh
#
# deSEC.io Domain API
#
# Author: Zheng Qian
#
# deSEC API doc
# https://desec.readthedocs.io/en/latest/
REST_API="https://desec.io/api/v1/domains"
######## Public functions #####################
#Usage: dns_desec_add _acme-challenge.foobar.dedyn.io "d41d8cd98f00b204e9800998ecf8427e"
dns_desec_add() {
fulldomain=$1
txtvalue=$2
_info "Using desec.io api"
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
DEDYN_TOKEN="${DEDYN_TOKEN:-$(_readaccountconf_mutable DEDYN_TOKEN)}"
DEDYN_NAME="${DEDYN_NAME:-$(_readaccountconf_mutable DEDYN_NAME)}"
if [ -z "$DEDYN_TOKEN" ] || [ -z "$DEDYN_NAME" ]; then
DEDYN_TOKEN=""
DEDYN_NAME=""
_err "You don't specify DEDYN_TOKEN and DEDYN_NAME yet."
_err "Please create you key and try again."
_err "e.g."
_err "export DEDYN_TOKEN=d41d8cd98f00b204e9800998ecf8427e"
_err "export DEDYN_NAME=foobar.dedyn.io"
return 1
fi
#save the api token and name to the account conf file.
_saveaccountconf_mutable DEDYN_TOKEN "$DEDYN_TOKEN"
_saveaccountconf_mutable DEDYN_NAME "$DEDYN_NAME"
_debug "First detect the root zone"
if ! _get_root "$fulldomain" "$REST_API/"; then
_err "invalid domain"
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
# Get existing TXT record
_debug "Getting txt records"
txtvalues="\"\\\"$txtvalue\\\"\""
_desec_rest GET "$REST_API/$DEDYN_NAME/rrsets/$_sub_domain/TXT/"
if [ "$_code" = "200" ]; then
oldtxtvalues="$(echo "$response" | _egrep_o "\"records\":\\[\"\\S*\"\\]" | cut -d : -f 2 | tr -d "[]\\\\\"" | sed "s/,/ /g")"
_debug "existing TXT found"
_debug oldtxtvalues "$oldtxtvalues"
if [ -n "$oldtxtvalues" ]; then
for oldtxtvalue in $oldtxtvalues; do
txtvalues="$txtvalues, \"\\\"$oldtxtvalue\\\"\""
done
fi
fi
_debug txtvalues "$txtvalues"
_info "Adding record"
body="[{\"subname\":\"$_sub_domain\", \"type\":\"TXT\", \"records\":[$txtvalues], \"ttl\":60}]"
if _desec_rest PUT "$REST_API/$DEDYN_NAME/rrsets/" "$body"; then
if _contains "$response" "$txtvalue"; then
_info "Added, OK"
return 0
else
_err "Add txt record error."
return 1
fi
fi
_err "Add txt record error."
return 1
}
#Usage: fulldomain txtvalue
#Remove the txt record after validation.
dns_desec_rm() {
fulldomain=$1
txtvalue=$2
_info "Using desec.io api"
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
DEDYN_TOKEN="${DEDYN_TOKEN:-$(_readaccountconf_mutable DEDYN_TOKEN)}"
DEDYN_NAME="${DEDYN_NAME:-$(_readaccountconf_mutable DEDYN_NAME)}"
if [ -z "$DEDYN_TOKEN" ] || [ -z "$DEDYN_NAME" ]; then
DEDYN_TOKEN=""
DEDYN_NAME=""
_err "You don't specify DEDYN_TOKEN and DEDYN_NAME yet."
_err "Please create you key and try again."
_err "e.g."
_err "export DEDYN_TOKEN=d41d8cd98f00b204e9800998ecf8427e"
_err "export DEDYN_NAME=foobar.dedyn.io"
return 1
fi
_debug "First detect the root zone"
if ! _get_root "$fulldomain" "$REST_API/"; then
_err "invalid domain"
return 1
fi
_debug _sub_domain "$_sub_domain"
_debug _domain "$_domain"
# Get existing TXT record
_debug "Getting txt records"
txtvalues=""
_desec_rest GET "$REST_API/$DEDYN_NAME/rrsets/$_sub_domain/TXT/"
if [ "$_code" = "200" ]; then
oldtxtvalues="$(echo "$response" | _egrep_o "\"records\":\\[\"\\S*\"\\]" | cut -d : -f 2 | tr -d "[]\\\\\"" | sed "s/,/ /g")"
_debug "existing TXT found"
_debug oldtxtvalues "$oldtxtvalues"
if [ -n "$oldtxtvalues" ]; then
for oldtxtvalue in $oldtxtvalues; do
if [ "$txtvalue" != "$oldtxtvalue" ]; then
txtvalues="$txtvalues, \"\\\"$oldtxtvalue\\\"\""
fi
done
fi
fi
txtvalues="$(echo "$txtvalues" | cut -c3-)"
_debug txtvalues "$txtvalues"
_info "Deleting record"
body="[{\"subname\":\"$_sub_domain\", \"type\":\"TXT\", \"records\":[$txtvalues], \"ttl\":60}]"
_desec_rest PUT "$REST_API/$DEDYN_NAME/rrsets/" "$body"
if [ "$_code" = "200" ]; then
_info "Deleted, OK"
return 0
fi
_err "Delete txt record error."
return 1
}
#################### Private functions below ##################################
_desec_rest() {
m="$1"
ep="$2"
data="$3"
export _H1="Authorization: Token $DEDYN_TOKEN"
export _H2="Accept: application/json"
export _H3="Content-Type: application/json"
if [ "$m" != "GET" ]; then
_secure_debug2 data "$data"
response="$(_post "$data" "$ep" "" "$m")"
else
response="$(_get "$ep")"
fi
_ret="$?"
_code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")"
_debug "http response code $_code"
_secure_debug2 response "$response"
if [ "$_ret" != "0" ]; then
_err "error $ep"
return 1
fi
response="$(printf "%s" "$response" | _normalizeJson)"
return 0
}
#_acme-challenge.www.domain.com
#returns
# _sub_domain=_acme-challenge.www
# _domain=domain.com
_get_root() {
domain="$1"
ep="$2"
i=2
p=1
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
_debug h "$h"
if [ -z "$h" ]; then
#not valid
return 1
fi
if ! _desec_rest GET "$ep"; then
return 1
fi
if _contains "$response" "\"name\":\"$h\"" >/dev/null; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_domain=$h
return 0
fi
p=$i
i=$(_math "$i" + 1)
done
return 1
}

2
dnsapi/dns_dgon.sh

@ -178,7 +178,7 @@ dns_dgon_rm() {
## _domain="domain.com" ## _domain="domain.com"
_get_base_domain() { _get_base_domain() {
# args # args
fulldomain="$(echo "$1" | tr '[:upper:]' '[:lower:]')"
fulldomain="$(echo "$1" | _lower_case)"
_debug fulldomain "$fulldomain" _debug fulldomain "$fulldomain"
# domain max legal length = 253 # domain max legal length = 253

2
dnsapi/dns_gdnsdk.sh

@ -137,7 +137,7 @@ _mypost() {
_get_domain() { _get_domain() {
_myget 'action=dns_primarydns' _myget 'action=dns_primarydns'
_domains=$(echo "$_result" | _egrep_o ' domain="[[:alnum:].-_]+' | sed 's/^.*"//')
_domains=$(echo "$_result" | _egrep_o ' domain="[[:alnum:]._-]+' | sed 's/^.*"//')
if [ -z "$_domains" ]; then if [ -z "$_domains" ]; then
_err "Primary domain list not found!" _err "Primary domain list not found!"
return 1 return 1

19
dnsapi/dns_namecom.sh

@ -13,6 +13,8 @@ dns_namecom_add() {
fulldomain=$1 fulldomain=$1
txtvalue=$2 txtvalue=$2
Namecom_Username="${Namecom_Username:-$(_readaccountconf_mutable Namecom_Username)}"
Namecom_Token="${Namecom_Token:-$(_readaccountconf_mutable Namecom_Token)}"
# First we need name.com credentials. # First we need name.com credentials.
if [ -z "$Namecom_Username" ]; then if [ -z "$Namecom_Username" ]; then
Namecom_Username="" Namecom_Username=""
@ -27,10 +29,11 @@ dns_namecom_add() {
_err "Please specify that in your environment variable." _err "Please specify that in your environment variable."
return 1 return 1
fi fi
_debug Namecom_Username "$Namecom_Username"
_secure_debug Namecom_Token "$Namecom_Token"
# Save them in configuration. # Save them in configuration.
_saveaccountconf Namecom_Username "$Namecom_Username"
_saveaccountconf Namecom_Token "$Namecom_Token"
_saveaccountconf_mutable Namecom_Username "$Namecom_Username"
_saveaccountconf_mutable Namecom_Token "$Namecom_Token"
# Login in using API # Login in using API
if ! _namecom_login; then if ! _namecom_login; then
@ -46,7 +49,7 @@ dns_namecom_add() {
# Add TXT record. # Add TXT record.
_namecom_addtxt_json="{\"host\":\"$_sub_domain\",\"type\":\"TXT\",\"answer\":\"$txtvalue\",\"ttl\":\"300\"}" _namecom_addtxt_json="{\"host\":\"$_sub_domain\",\"type\":\"TXT\",\"answer\":\"$txtvalue\",\"ttl\":\"300\"}"
if _namecom_rest POST "domains/$_domain/records" "$_namecom_addtxt_json"; then if _namecom_rest POST "domains/$_domain/records" "$_namecom_addtxt_json"; then
_retvalue=$(printf "%s\n" "$response" | _egrep_o "\"$_sub_domain\"")
_retvalue=$(echo "$response" | _egrep_o "\"$_sub_domain\"")
if [ "$_retvalue" ]; then if [ "$_retvalue" ]; then
_info "Successfully added TXT record, ready for validation." _info "Successfully added TXT record, ready for validation."
return 0 return 0
@ -63,6 +66,8 @@ dns_namecom_rm() {
fulldomain=$1 fulldomain=$1
txtvalue=$2 txtvalue=$2
Namecom_Username="${Namecom_Username:-$(_readaccountconf_mutable Namecom_Username)}"
Namecom_Token="${Namecom_Token:-$(_readaccountconf_mutable Namecom_Token)}"
if ! _namecom_login; then if ! _namecom_login; then
return 1 return 1
fi fi
@ -75,7 +80,7 @@ dns_namecom_rm() {
# Get the record id. # Get the record id.
if _namecom_rest GET "domains/$_domain/records"; then if _namecom_rest GET "domains/$_domain/records"; then
_record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":[0-9]+,\"domainName\":\"$_domain\",\"host\":\"$_sub_domain\",\"fqdn\":\"$fulldomain.\",\"type\":\"TXT\",\"answer\":\"$txtvalue\"" | cut -d \" -f 3 | _egrep_o [0-9]+)
_record_id=$(echo "$response" | _egrep_o "\"id\":[0-9]+,\"domainName\":\"$_domain\",\"host\":\"$_sub_domain\",\"fqdn\":\"$fulldomain.\",\"type\":\"TXT\",\"answer\":\"$txtvalue\"" | cut -d \" -f 3 | _egrep_o [0-9]+)
_debug record_id "$_record_id" _debug record_id "$_record_id"
if [ "$_record_id" ]; then if [ "$_record_id" ]; then
_info "Successfully retrieved the record id for ACME challenge." _info "Successfully retrieved the record id for ACME challenge."
@ -126,10 +131,12 @@ _namecom_login() {
_namecom_auth=$(printf "%s:%s" "$Namecom_Username" "$Namecom_Token" | _base64) _namecom_auth=$(printf "%s:%s" "$Namecom_Username" "$Namecom_Token" | _base64)
if _namecom_rest GET "hello"; then if _namecom_rest GET "hello"; then
retcode=$(printf "%s\n" "$response" | _egrep_o "\"username\"\:\"$Namecom_Username\"")
retcode=$(echo "$response" | _egrep_o "\"username\"\:\"$Namecom_Username\"")
if [ "$retcode" ]; then if [ "$retcode" ]; then
_info "Successfully logged in." _info "Successfully logged in."
else else
_err "$response"
_err "Please add your ip to api whitelist"
_err "Logging in failed." _err "Logging in failed."
return 1 return 1
fi fi

1
dnsapi/dns_netcup.sh

@ -8,6 +8,7 @@ end="https://ccp.netcup.net/run/webservice/servers/endpoint.php?JSON"
client="" client=""
dns_netcup_add() { dns_netcup_add() {
_debug NC_Apikey "$NC_Apikey"
login login
if [ "$NC_Apikey" = "" ] || [ "$NC_Apipw" = "" ] || [ "$NC_CID" = "" ]; then if [ "$NC_Apikey" = "" ] || [ "$NC_Apipw" = "" ] || [ "$NC_CID" = "" ]; then
_err "No Credentials given" _err "No Credentials given"

244
dnsapi/dns_openprovider.sh

@ -0,0 +1,244 @@
#!/usr/bin/env sh
# This is the OpenProvider API wrapper for acme.sh
#
# Author: Sylvia van Os
# Report Bugs here: https://github.com/Neilpang/acme.sh/issues/2104
#
# export OPENPROVIDER_USER="username"
# export OPENPROVIDER_PASSWORDHASH="hashed_password"
#
# Usage:
# acme.sh --issue --dns dns_openprovider -d example.com
OPENPROVIDER_API="https://api.openprovider.eu/"
#OPENPROVIDER_API="https://api.cte.openprovider.eu/" # Test API
######## Public functions #####################
#Usage: dns_openprovider_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_openprovider_add() {
fulldomain="$1"
txtvalue="$2"
OPENPROVIDER_USER="${OPENPROVIDER_USER:-$(_readaccountconf_mutable OPENPROVIDER_USER)}"
OPENPROVIDER_PASSWORDHASH="${OPENPROVIDER_PASSWORDHASH:-$(_readaccountconf_mutable OPENPROVIDER_PASSWORDHASH)}"
if [ -z "$OPENPROVIDER_USER" ] || [ -z "$OPENPROVIDER_PASSWORDHASH" ]; then
_err "You didn't specify the openprovider user and/or password hash."
return 1
fi
# save the username and password to the account conf file.
_saveaccountconf_mutable OPENPROVIDER_USER "$OPENPROVIDER_USER"
_saveaccountconf_mutable OPENPROVIDER_PASSWORDHASH "$OPENPROVIDER_PASSWORDHASH"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _domain_name "$_domain_name"
_debug _domain_extension "$_domain_extension"
_debug "Getting current records"
existing_items=""
results_retrieved=0
while true; do
_openprovider_request "$(printf '<searchZoneRecordDnsRequest><name>%s.%s</name><offset>%s</offset></searchZoneRecordDnsRequest>' "$_domain_name" "$_domain_extension" "$results_retrieved")"
items="$response"
while true; do
item="$(echo "$items" | _egrep_o '<openXML>.*<\/openXML>' | sed -n 's/.*\(<item>.*<\/item>\).*/\1/p')"
_debug existing_items "$existing_items"
_debug results_retrieved "$results_retrieved"
_debug item "$item"
if [ -z "$item" ]; then
break
fi
items="$(echo "$items" | sed "s|${item}||")"
results_retrieved="$(_math "$results_retrieved" + 1)"
new_item="$(echo "$item" | sed -n 's/.*<item>.*\(<name>\(.*\)\.'"$_domain_name"'\.'"$_domain_extension"'<\/name>.*\(<type>.*<\/type>\).*\(<value>.*<\/value>\).*\(<prio>.*<\/prio>\).*\(<ttl>.*<\/ttl>\)\).*<\/item>.*/<item><name>\2<\/name>\3\4\5\6<\/item>/p')"
if [ -z "$new_item" ]; then
# Base record
new_item="$(echo "$item" | sed -n 's/.*<item>.*\(<name>\(.*\)'"$_domain_name"'\.'"$_domain_extension"'<\/name>.*\(<type>.*<\/type>\).*\(<value>.*<\/value>\).*\(<prio>.*<\/prio>\).*\(<ttl>.*<\/ttl>\)\).*<\/item>.*/<item><name>\2<\/name>\3\4\5\6<\/item>/p')"
fi
if [ -z "$(echo "$new_item" | _egrep_o ".*<type>(A|AAAA|CNAME|MX|SPF|SRV|TXT|TLSA|SSHFP|CAA)<\/type>.*")" ]; then
_debug "not an allowed record type, skipping" "$new_item"
continue
fi
existing_items="$existing_items$new_item"
done
total="$(echo "$response" | _egrep_o '<total>.*?<\/total>' | sed -n 's/.*<total>\(.*\)<\/total>.*/\1/p')"
_debug total "$total"
if [ "$results_retrieved" -eq "$total" ]; then
break
fi
done
_debug "Creating acme record"
acme_record="$(echo "$fulldomain" | sed -e "s/.$_domain_name.$_domain_extension$//")"
_openprovider_request "$(printf '<modifyZoneDnsRequest><domain><name>%s</name><extension>%s</extension></domain><type>master</type><records><array>%s<item><name>%s</name><type>TXT</type><value>%s</value><ttl>86400</ttl></item></array></records></modifyZoneDnsRequest>' "$_domain_name" "$_domain_extension" "$existing_items" "$acme_record" "$txtvalue")"
return 0
}
#Usage: fulldomain txtvalue
#Remove the txt record after validation.
dns_openprovider_rm() {
fulldomain="$1"
txtvalue="$2"
OPENPROVIDER_USER="${OPENPROVIDER_USER:-$(_readaccountconf_mutable OPENPROVIDER_USER)}"
OPENPROVIDER_PASSWORDHASH="${OPENPROVIDER_PASSWORDHASH:-$(_readaccountconf_mutable OPENPROVIDER_PASSWORDHASH)}"
if [ -z "$OPENPROVIDER_USER" ] || [ -z "$OPENPROVIDER_PASSWORDHASH" ]; then
_err "You didn't specify the openprovider user and/or password hash."
return 1
fi
# save the username and password to the account conf file.
_saveaccountconf_mutable OPENPROVIDER_USER "$OPENPROVIDER_USER"
_saveaccountconf_mutable OPENPROVIDER_PASSWORDHASH "$OPENPROVIDER_PASSWORDHASH"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _domain_name "$_domain_name"
_debug _domain_extension "$_domain_extension"
_debug "Getting current records"
existing_items=""
results_retrieved=0
while true; do
_openprovider_request "$(printf '<searchZoneRecordDnsRequest><name>%s.%s</name><offset>%s</offset></searchZoneRecordDnsRequest>' "$_domain_name" "$_domain_extension" "$results_retrieved")"
# Remove acme records from items
items="$response"
while true; do
item="$(echo "$items" | _egrep_o '<openXML>.*<\/openXML>' | sed -n 's/.*\(<item>.*<\/item>\).*/\1/p')"
_debug existing_items "$existing_items"
_debug results_retrieved "$results_retrieved"
_debug item "$item"
if [ -z "$item" ]; then
break
fi
items="$(echo "$items" | sed "s|${item}||")"
results_retrieved="$(_math "$results_retrieved" + 1)"
if ! echo "$item" | grep -v "$fulldomain"; then
_debug "acme record, skipping" "$item"
continue
fi
new_item="$(echo "$item" | sed -n 's/.*<item>.*\(<name>\(.*\)\.'"$_domain_name"'\.'"$_domain_extension"'<\/name>.*\(<type>.*<\/type>\).*\(<value>.*<\/value>\).*\(<prio>.*<\/prio>\).*\(<ttl>.*<\/ttl>\)\).*<\/item>.*/<item><name>\2<\/name>\3\4\5\6<\/item>/p')"
if [ -z "$new_item" ]; then
# Base record
new_item="$(echo "$item" | sed -n 's/.*<item>.*\(<name>\(.*\)'"$_domain_name"'\.'"$_domain_extension"'<\/name>.*\(<type>.*<\/type>\).*\(<value>.*<\/value>\).*\(<prio>.*<\/prio>\).*\(<ttl>.*<\/ttl>\)\).*<\/item>.*/<item><name>\2<\/name>\3\4\5\6<\/item>/p')"
fi
if [ -z "$(echo "$new_item" | _egrep_o ".*<type>(A|AAAA|CNAME|MX|SPF|SRV|TXT|TLSA|SSHFP|CAA)<\/type>.*")" ]; then
_debug "not an allowed record type, skipping" "$new_item"
continue
fi
existing_items="$existing_items$new_item"
done
total="$(echo "$response" | _egrep_o '<total>.*?<\/total>' | sed -n 's/.*<total>\(.*\)<\/total>.*/\1/p')"
_debug total "$total"
if [ "$results_retrieved" -eq "$total" ]; then
break
fi
done
_debug "Removing acme record"
_openprovider_request "$(printf '<modifyZoneDnsRequest><domain><name>%s</name><extension>%s</extension></domain><type>master</type><records><array>%s</array></records></modifyZoneDnsRequest>' "$_domain_name" "$_domain_extension" "$existing_items")"
return 0
}
#################### Private functions below ##################################
#_acme-challenge.www.domain.com
#returns
# _domain_name=domain
# _domain_extension=com
_get_root() {
domain=$1
i=2
results_retrieved=0
while true; do
h=$(echo "$domain" | cut -d . -f $i-100)
_debug h "$h"
if [ -z "$h" ]; then
#not valid
return 1
fi
_openprovider_request "$(printf '<searchDomainRequest><domainNamePattern>%s</domainNamePattern><offset>%s</offset></searchDomainRequest>' "$(echo "$h" | cut -d . -f 1)" "$results_retrieved")"
items="$response"
while true; do
item="$(echo "$items" | _egrep_o '<openXML>.*<\/openXML>' | sed -n 's/.*\(<domain>.*<\/domain>\).*/\1/p')"
_debug existing_items "$existing_items"
_debug results_retrieved "$results_retrieved"
_debug item "$item"
if [ -z "$item" ]; then
break
fi
items="$(echo "$items" | sed "s|${item}||")"
results_retrieved="$(_math "$results_retrieved" + 1)"
_domain_name="$(echo "$item" | sed -n 's/.*<domain>.*<name>\(.*\)<\/name>.*<\/domain>.*/\1/p')"
_domain_extension="$(echo "$item" | sed -n 's/.*<domain>.*<extension>\(.*\)<\/extension>.*<\/domain>.*/\1/p')"
_debug _domain_name "$_domain_name"
_debug _domain_extension "$_domain_extension"
if [ "$_domain_name.$_domain_extension" = "$h" ]; then
return 0
fi
done
total="$(echo "$response" | _egrep_o '<total>.*?<\/total>' | sed -n 's/.*<total>\(.*\)<\/total>.*/\1/p')"
_debug total "$total"
if [ "$results_retrieved" -eq "$total" ]; then
results_retrieved=0
i="$(_math "$i" + 1)"
fi
done
return 1
}
_openprovider_request() {
request_xml=$1
xml_prefix='<?xml version="1.0" encoding="UTF-8"?>'
xml_content=$(printf '<openXML><credentials><username>%s</username><hash>%s</hash></credentials>%s</openXML>' "$OPENPROVIDER_USER" "$OPENPROVIDER_PASSWORDHASH" "$request_xml")
response="$(_post "$(echo "$xml_prefix$xml_content" | tr -d '\n')" "$OPENPROVIDER_API" "" "POST" "application/xml")"
_debug response "$response"
if ! _contains "$response" "<openXML><reply><code>0</code>.*</reply></openXML>"; then
_err "API request failed."
return 1
fi
}

164
dnsapi/dns_ultra.sh

@ -0,0 +1,164 @@
#!/usr/bin/env sh
#
# ULTRA_USR="your_user_goes_here"
#
# ULTRA_PWD="some_password_goes_here"
ULTRA_API="https://restapi.ultradns.com/v2/"
#Usage: add _acme-challenge.www.domain.com "some_long_string_of_characters_go_here_from_lets_encrypt"
dns_ultra_add() {
fulldomain=$1
txtvalue=$2
export txtvalue
ULTRA_USR="${ULTRA_USR:-$(_readaccountconf_mutable ULTRA_USR)}"
ULTRA_PWD="${ULTRA_PWD:-$(_readaccountconf_mutable ULTRA_PWD)}"
if [ -z "$ULTRA_USR" ] || [ -z "$ULTRA_PWD" ]; then
ULTRA_USR=""
ULTRA_PWD=""
_err "You didn't specify an UltraDNS username and password yet"
return 1
fi
# save the username and password to the account conf file.
_saveaccountconf_mutable ULTRA_USR "$ULTRA_USR"
_saveaccountconf_mutable ULTRA_PWD "$ULTRA_PWD"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _domain_id "${_domain_id}"
_debug _sub_domain "${_sub_domain}"
_debug _domain "${_domain}"
_debug "Getting txt records"
_ultra_rest GET "zones/${_domain_id}/rrsets/TXT?q=value:${fulldomain}"
if printf "%s" "$response" | grep \"totalCount\" >/dev/null; then
_err "Error, it would appear that this record already exists. Please review existing TXT records for this domain."
return 1
fi
_info "Adding record"
if _ultra_rest POST "zones/$_domain_id/rrsets/TXT/${_sub_domain}" '{"ttl":300,"rdata":["'"${txtvalue}"'"]}'; then
if _contains "$response" "Successful"; then
_info "Added, OK"
return 0
elif _contains "$response" "Resource Record of type 16 with these attributes already exists"; then
_info "Already exists, OK"
return 0
else
_err "Add txt record error."
return 1
fi
fi
_err "Add txt record error."
}
dns_ultra_rm() {
fulldomain=$1
txtvalue=$2
export txtvalue
ULTRA_USR="${ULTRA_USR:-$(_readaccountconf_mutable ULTRA_USR)}"
ULTRA_PWD="${ULTRA_PWD:-$(_readaccountconf_mutable ULTRA_PWD)}"
if [ -z "$ULTRA_USR" ] || [ -z "$ULTRA_PWD" ]; then
ULTRA_USR=""
ULTRA_PWD=""
_err "You didn't specify an UltraDNS username and password yet"
return 1
fi
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug _domain_id "${_domain_id}"
_debug _sub_domain "${_sub_domain}"
_debug _domain "${domain}"
_debug "Getting TXT records"
_ultra_rest GET "zones/${_domain_id}/rrsets?q=kind:RECORDS+owner:${_sub_domain}"
if ! printf "%s" "$response" | grep \"resultInfo\" >/dev/null; then
_err "There was an error in obtaining the resource records for ${_domain_id}"
return 1
fi
count=$(echo "$response" | _egrep_o "\"returnedCount\":[^,]*" | cut -d: -f2 | cut -d'}' -f1)
_debug count "${count}"
if [ "${count}" = "" ]; then
_info "Text record is not present, will not delete anything."
else
if ! _ultra_rest DELETE "zones/$_domain_id/rrsets/TXT/${_sub_domain}" '{"ttl":300,"rdata":["'"${txtvalue}"'"]}'; then
_err "Deleting the record did not succeed, please verify/check."
return 1
fi
_contains "$response" ""
fi
}
#################### Private functions below ##################################
#_acme-challenge.www.domain.com
#returns
# _sub_domain=_acme-challenge.www
# _domain=domain.com
# _domain_id=sdjkglgdfewsdfg
_get_root() {
domain=$1
i=2
p=1
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
_debug h "$h"
_debug response "$response"
if [ -z "$h" ]; then
#not valid
return 1
fi
if ! _ultra_rest GET "zones"; then
return 1
fi
if _contains "${response}" "${h}." >/dev/null; then
_domain_id=$(echo "$response" | _egrep_o "${h}")
if [ "$_domain_id" ]; then
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
_domain="${h}"
_debug sub_domain "${_sub_domain}"
_debug domain "${_domain}"
return 0
fi
return 1
fi
p=$i
i=$(_math "$i" + 1)
done
return 1
}
_ultra_rest() {
m=$1
ep="$2"
data="$3"
_debug "$ep"
_debug TOKEN "${AUTH_TOKEN}"
_ultra_login
export _H1="Content-Type: application/json"
export _H2="Authorization: Bearer ${AUTH_TOKEN}"
if [ "$m" != "GET" ]; then
_debug data "${data}"
response="$(_post "${data}" "${ULTRA_API}"/"${ep}" "" "${m}")"
else
response="$(_get "$ULTRA_API/$ep")"
fi
}
_ultra_login() {
export _H1=""
export _H2=""
AUTH_TOKEN=$(_post "grant_type=password&username=${ULTRA_USR}&password=${ULTRA_PWD}" "${ULTRA_API}authorization/token" | cut -d, -f3 | cut -d\" -f4)
export AUTH_TOKEN
}

149
dnsapi/dns_zone.sh

@ -0,0 +1,149 @@
#!/usr/bin/env sh
# Zone.ee dns API
# https://help.zone.eu/kb/zoneid-api-v2/
# required ZONE_Username and ZONE_Key
ZONE_Api="https://api.zone.eu/v2"
######## Public functions #####################
#Usage: dns_zone_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
dns_zone_add() {
fulldomain=$1
txtvalue=$2
_info "Using zone.ee dns api"
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
ZONE_Username="${ZONE_Username:-$(_readaccountconf_mutable ZONE_Username)}"
ZONE_Key="${ZONE_Key:-$(_readaccountconf_mutable ZONE_Key)}"
if [ -z "$ZONE_Username" ] || [ -z "$ZONE_Key" ]; then
ZONE_Username=""
ZONE_Key=""
_err "Zone api key and username must be present."
return 1
fi
_saveaccountconf_mutable ZONE_Username "$ZONE_Username"
_saveaccountconf_mutable ZONE_Key "$ZONE_Key"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug "Adding txt record"
if _zone_rest POST "dns/${_domain}/txt" "{\"name\": \"$fulldomain\", \"destination\": \"$txtvalue\"}"; then
if printf -- "%s" "$response" | grep "$fulldomain" >/dev/null; then
_info "Added, OK"
return 0
else
_err "Adding txt record error."
return 1
fi
else
_err "Adding txt record error."
fi
}
#Usage: fulldomain txtvalue
#Remove the txt record after validation.
dns_zone_rm() {
fulldomain=$1
txtvalue=$2
_info "Using zone.ee dns api"
_debug fulldomain "$fulldomain"
_debug txtvalue "$txtvalue"
ZONE_Username="${ZONE_Username:-$(_readaccountconf_mutable ZONE_Username)}"
ZONE_Key="${ZONE_Key:-$(_readaccountconf_mutable ZONE_Key)}"
if [ -z "$ZONE_Username" ] || [ -z "$ZONE_Key" ]; then
ZONE_Username=""
ZONE_Key=""
_err "Zone api key and username must be present."
return 1
fi
_saveaccountconf_mutable ZONE_Username "$ZONE_Username"
_saveaccountconf_mutable ZONE_Key "$ZONE_Key"
_debug "First detect the root zone"
if ! _get_root "$fulldomain"; then
_err "invalid domain"
return 1
fi
_debug "Getting txt records"
_debug _domain "$_domain"
_zone_rest GET "dns/${_domain}/txt"
if printf "%s" "$response" | grep \"error\" >/dev/null; then
_err "Error"
return 1
fi
count=$(printf "%s\n" "$response" | _egrep_o "\"name\":\"$fulldomain\"" | wc -l)
_debug count "$count"
if [ "$count" = "0" ]; then
_info "Nothing to remove."
else
record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\"[^\"]*\",\"resource_url\":\"[^\"]*\",\"name\":\"$fulldomain\"," | cut -d : -f2 | cut -d , -f1 | tr -d \" | _head_n 1)
if [ -z "$record_id" ]; then
_err "No id found to remove."
return 1
fi
if ! _zone_rest DELETE "dns/${_domain}/txt/$record_id"; then
_err "Record deleting error."
return 1
fi
_info "Record deleted"
return 0
fi
}
#################### Private functions below ##################################
_zone_rest() {
m=$1
ep="$2"
data="$3"
_debug "$ep"
realm="$(printf "%s" "$ZONE_Username:$ZONE_Key" | _base64)"
export _H1="Authorization: Basic $realm"
export _H2="Content-Type: application/json"
if [ "$m" != "GET" ]; then
_debug data "$data"
response="$(_post "$data" "$ZONE_Api/$ep" "" "$m")"
else
response="$(_get "$ZONE_Api/$ep")"
fi
if [ "$?" != "0" ]; then
_err "error $ep"
return 1
fi
_debug2 response "$response"
return 0
}
_get_root() {
domain=$1
i=2
while true; do
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
_debug h "$h"
if [ -z "$h" ]; then
return 1
fi
if ! _zone_rest GET "dns/$h/a"; then
return 1
fi
if _contains "$response" "\"name\":\"$h\"" >/dev/null; then
_domain=$h
return 0
fi
i=$(_math "$i" + 1)
done
return 0
}
Loading…
Cancel
Save