Merge remote-tracking branch 'upstream/master'
commit
4ab6786163
@ -1 +1,74 @@
|
||||
#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).
|
||||
|
||||
Here are the scripts to deploy the certs/key to the server/services.
|
||||
|
||||
## 1. Deploy the certs to your cpanel host.
|
||||
|
||||
(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).
|
||||
|
||||
(TODO)
|
||||
|
||||
## 3. Deploy the cert to remote server through SSH access.
|
||||
|
||||
(TODO)
|
||||
|
||||
## 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
|
||||
```
|
||||
|
||||
|
@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#Here is a script to deploy cert to dovecot server.
|
||||
|
||||
#returns 0 means success, otherwise error.
|
||||
|
||||
######## Public functions #####################
|
||||
|
||||
#domain keyfile certfile cafile fullchain
|
||||
apache_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"
|
||||
|
||||
_err "Deploy cert to apache server, Not implemented yet"
|
||||
return 1
|
||||
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#Here is the script to deploy the cert to your cpanel account by the cpanel APIs.
|
||||
|
||||
#returns 0 means success, otherwise error.
|
||||
|
||||
#export DEPLOY_CPANEL_USER=myusername
|
||||
#export DEPLOY_CPANEL_PASSWORD=PASSWORD
|
||||
|
||||
######## Public functions #####################
|
||||
|
||||
#domain keyfile certfile cafile fullchain
|
||||
cpanel_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"
|
||||
|
||||
_err "Not implemented yet"
|
||||
return 1
|
||||
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#Here is a script to deploy cert to dovecot server.
|
||||
|
||||
#returns 0 means success, otherwise error.
|
||||
|
||||
######## Public functions #####################
|
||||
|
||||
#domain keyfile certfile cafile fullchain
|
||||
dovecot_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"
|
||||
|
||||
_err "Not implemented yet"
|
||||
return 1
|
||||
|
||||
}
|
@ -0,0 +1,114 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#Here is a script to deploy cert to exim4 server.
|
||||
|
||||
#returns 0 means success, otherwise error.
|
||||
|
||||
#DEPLOY_EXIM4_CONF="/etc/exim/exim.conf"
|
||||
#DEPLOY_EXIM4_RELOAD="service exim4 restart"
|
||||
|
||||
######## Public functions #####################
|
||||
|
||||
#domain keyfile certfile cafile fullchain
|
||||
exim4_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"
|
||||
|
||||
_ssl_path="/etc/acme.sh/exim4"
|
||||
if ! mkdir -p "$_ssl_path"; then
|
||||
_err "Can not create folder:$_ssl_path"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_info "Copying key and cert"
|
||||
_real_key="$_ssl_path/exim4.key"
|
||||
if ! cat "$_ckey" >"$_real_key"; then
|
||||
_err "Error: write key file to: $_real_key"
|
||||
return 1
|
||||
fi
|
||||
_real_fullchain="$_ssl_path/exim4.pem"
|
||||
if ! cat "$_cfullchain" >"$_real_fullchain"; then
|
||||
_err "Error: write key file to: $_real_fullchain"
|
||||
return 1
|
||||
fi
|
||||
|
||||
DEFAULT_EXIM4_RELOAD="service exim4 restart"
|
||||
_reload="${DEPLOY_EXIM4_RELOAD:-$DEFAULT_EXIM4_RELOAD}"
|
||||
|
||||
if [ -z "$IS_RENEW" ]; then
|
||||
DEFAULT_EXIM4_CONF="/etc/exim/exim.conf"
|
||||
if [ ! -f "$DEFAULT_EXIM4_CONF" ]; then
|
||||
DEFAULT_EXIM4_CONF="/etc/exim4/exim4.conf.template"
|
||||
fi
|
||||
_exim4_conf="${DEPLOY_EXIM4_CONF:-$DEFAULT_EXIM4_CONF}"
|
||||
_debug _exim4_conf "$_exim4_conf"
|
||||
if [ ! -f "$_exim4_conf" ]; then
|
||||
if [ -z "$DEPLOY_EXIM4_CONF" ]; then
|
||||
_err "exim4 conf is not found, please define DEPLOY_EXIM4_CONF"
|
||||
return 1
|
||||
else
|
||||
_err "It seems that the specified exim4 conf is not valid, please check."
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
if [ ! -w "$_exim4_conf" ]; then
|
||||
_err "The file $_exim4_conf is not writable, please change the permission."
|
||||
return 1
|
||||
fi
|
||||
_backup_conf="$DOMAIN_BACKUP_PATH/exim4.conf.bak"
|
||||
_info "Backup $_exim4_conf to $_backup_conf"
|
||||
cp "$_exim4_conf" "$_backup_conf"
|
||||
|
||||
_info "Modify exim4 conf: $_exim4_conf"
|
||||
if _setopt "$_exim4_conf" "tls_certificate" "=" "$_real_fullchain" \
|
||||
&& _setopt "$_exim4_conf" "tls_privatekey" "=" "$_real_key"; then
|
||||
_info "Set config success!"
|
||||
else
|
||||
_err "Config exim4 server error, please report bug to us."
|
||||
_info "Restoring exim4 conf"
|
||||
if cat "$_backup_conf" >"$_exim4_conf"; then
|
||||
_info "Restore conf success"
|
||||
eval "$_reload"
|
||||
else
|
||||
_err "Opps, error restore exim4 conf, please report bug to us."
|
||||
fi
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
_info "Run reload: $_reload"
|
||||
if eval "$_reload"; then
|
||||
_info "Reload success!"
|
||||
if [ "$DEPLOY_EXIM4_CONF" ]; then
|
||||
_savedomainconf DEPLOY_EXIM4_CONF "$DEPLOY_EXIM4_CONF"
|
||||
else
|
||||
_cleardomainconf DEPLOY_EXIM4_CONF
|
||||
fi
|
||||
if [ "$DEPLOY_EXIM4_RELOAD" ]; then
|
||||
_savedomainconf DEPLOY_EXIM4_RELOAD "$DEPLOY_EXIM4_RELOAD"
|
||||
else
|
||||
_cleardomainconf DEPLOY_EXIM4_RELOAD
|
||||
fi
|
||||
return 0
|
||||
else
|
||||
_err "Reload error, restoring"
|
||||
if cat "$_backup_conf" >"$_exim4_conf"; then
|
||||
_info "Restore conf success"
|
||||
eval "$_reload"
|
||||
else
|
||||
_err "Opps, error restore exim4 conf, please report bug to us."
|
||||
fi
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#Here is a script to deploy cert to haproxy server.
|
||||
|
||||
#returns 0 means success, otherwise error.
|
||||
|
||||
######## Public functions #####################
|
||||
|
||||
#domain keyfile certfile cafile fullchain
|
||||
haproxy_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"
|
||||
|
||||
_err "deploy cert to haproxy server, Not implemented yet"
|
||||
return 1
|
||||
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#Here is a script to deploy cert to mysqld server.
|
||||
|
||||
#returns 0 means success, otherwise error.
|
||||
|
||||
######## Public functions #####################
|
||||
|
||||
#domain keyfile certfile cafile fullchain
|
||||
mysqld_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"
|
||||
|
||||
_err "deploy cert to mysqld server, Not implemented yet"
|
||||
return 1
|
||||
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#Here is a script to deploy cert to nginx server.
|
||||
|
||||
#returns 0 means success, otherwise error.
|
||||
|
||||
######## Public functions #####################
|
||||
|
||||
#domain keyfile certfile cafile fullchain
|
||||
nginx_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"
|
||||
|
||||
_err "deploy cert to nginx server, Not implemented yet"
|
||||
return 1
|
||||
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#Here is a script to deploy cert to opensshd server.
|
||||
|
||||
#returns 0 means success, otherwise error.
|
||||
|
||||
######## Public functions #####################
|
||||
|
||||
#domain keyfile certfile cafile fullchain
|
||||
opensshd_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"
|
||||
|
||||
_err "deploy cert to opensshd server, Not implemented yet"
|
||||
return 1
|
||||
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#Here is a script to deploy cert to pureftpd server.
|
||||
|
||||
#returns 0 means success, otherwise error.
|
||||
|
||||
######## Public functions #####################
|
||||
|
||||
#domain keyfile certfile cafile fullchain
|
||||
pureftpd_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"
|
||||
|
||||
_err "deploy cert to pureftpd server, Not implemented yet"
|
||||
return 1
|
||||
|
||||
}
|
@ -0,0 +1,110 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#Here is a script to deploy cert to vsftpd server.
|
||||
|
||||
#returns 0 means success, otherwise error.
|
||||
|
||||
#DEPLOY_VSFTPD_CONF="/etc/vsftpd.conf"
|
||||
#DEPLOY_VSFTPD_RELOAD="service vsftpd restart"
|
||||
|
||||
######## Public functions #####################
|
||||
|
||||
#domain keyfile certfile cafile fullchain
|
||||
vsftpd_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"
|
||||
|
||||
_ssl_path="/etc/acme.sh/vsftpd"
|
||||
if ! mkdir -p "$_ssl_path"; then
|
||||
_err "Can not create folder:$_ssl_path"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_info "Copying key and cert"
|
||||
_real_key="$_ssl_path/vsftpd.key"
|
||||
if ! cat "$_ckey" >"$_real_key"; then
|
||||
_err "Error: write key file to: $_real_key"
|
||||
return 1
|
||||
fi
|
||||
_real_fullchain="$_ssl_path/vsftpd.chain.pem"
|
||||
if ! cat "$_cfullchain" >"$_real_fullchain"; then
|
||||
_err "Error: write key file to: $_real_fullchain"
|
||||
return 1
|
||||
fi
|
||||
|
||||
DEFAULT_VSFTPD_RELOAD="service vsftpd restart"
|
||||
_reload="${DEPLOY_VSFTPD_RELOAD:-$DEFAULT_VSFTPD_RELOAD}"
|
||||
|
||||
if [ -z "$IS_RENEW" ]; then
|
||||
DEFAULT_VSFTPD_CONF="/etc/vsftpd.conf"
|
||||
_vsftpd_conf="${DEPLOY_VSFTPD_CONF:-$DEFAULT_VSFTPD_CONF}"
|
||||
if [ ! -f "$_vsftpd_conf" ]; then
|
||||
if [ -z "$DEPLOY_VSFTPD_CONF" ]; then
|
||||
_err "vsftpd conf is not found, please define DEPLOY_VSFTPD_CONF"
|
||||
return 1
|
||||
else
|
||||
_err "It seems that the specified vsftpd conf is not valid, please check."
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
if [ ! -w "$_vsftpd_conf" ]; then
|
||||
_err "The file $_vsftpd_conf is not writable, please change the permission."
|
||||
return 1
|
||||
fi
|
||||
_backup_conf="$DOMAIN_BACKUP_PATH/vsftpd.conf.bak"
|
||||
_info "Backup $_vsftpd_conf to $_backup_conf"
|
||||
cp "$_vsftpd_conf" "$_backup_conf"
|
||||
|
||||
_info "Modify vsftpd conf: $_vsftpd_conf"
|
||||
if _setopt "$_vsftpd_conf" "rsa_cert_file" "=" "$_real_fullchain" \
|
||||
&& _setopt "$_vsftpd_conf" "rsa_private_key_file" "=" "$_real_key" \
|
||||
&& _setopt "$_vsftpd_conf" "ssl_enable" "=" "YES"; then
|
||||
_info "Set config success!"
|
||||
else
|
||||
_err "Config vsftpd server error, please report bug to us."
|
||||
_info "Restoring vsftpd conf"
|
||||
if cat "$_backup_conf" >"$_vsftpd_conf"; then
|
||||
_info "Restore conf success"
|
||||
eval "$_reload"
|
||||
else
|
||||
_err "Opps, error restore vsftpd conf, please report bug to us."
|
||||
fi
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
_info "Run reload: $_reload"
|
||||
if eval "$_reload"; then
|
||||
_info "Reload success!"
|
||||
if [ "$DEPLOY_VSFTPD_CONF" ]; then
|
||||
_savedomainconf DEPLOY_VSFTPD_CONF "$DEPLOY_VSFTPD_CONF"
|
||||
else
|
||||
_cleardomainconf DEPLOY_VSFTPD_CONF
|
||||
fi
|
||||
if [ "$DEPLOY_VSFTPD_RELOAD" ]; then
|
||||
_savedomainconf DEPLOY_VSFTPD_RELOAD "$DEPLOY_VSFTPD_RELOAD"
|
||||
else
|
||||
_cleardomainconf DEPLOY_VSFTPD_RELOAD
|
||||
fi
|
||||
return 0
|
||||
else
|
||||
_err "Reload error, restoring"
|
||||
if cat "$_backup_conf" >"$_vsftpd_conf"; then
|
||||
_info "Restore conf success"
|
||||
eval "$_reload"
|
||||
else
|
||||
_err "Opps, error restore vsftpd conf, please report bug to us."
|
||||
fi
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
@ -0,0 +1,328 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
########
|
||||
# Custom cyon.ch DNS API for use with [acme.sh](https://github.com/Neilpang/acme.sh)
|
||||
#
|
||||
# Usage: acme.sh --issue --dns dns_cyon -d www.domain.com
|
||||
#
|
||||
# Dependencies:
|
||||
# -------------
|
||||
# - oathtool (When using 2 Factor Authentication)
|
||||
#
|
||||
# Issues:
|
||||
# -------
|
||||
# Any issues / questions / suggestions can be posted here:
|
||||
# https://github.com/noplanman/cyon-api/issues
|
||||
#
|
||||
# Author: Armando Lüscher <armando@noplanman.ch>
|
||||
########
|
||||
|
||||
dns_cyon_add() {
|
||||
_cyon_load_credentials \
|
||||
&& _cyon_load_parameters "$@" \
|
||||
&& _cyon_print_header "add" \
|
||||
&& _cyon_login \
|
||||
&& _cyon_change_domain_env \
|
||||
&& _cyon_add_txt \
|
||||
&& _cyon_logout
|
||||
}
|
||||
|
||||
dns_cyon_rm() {
|
||||
_cyon_load_credentials \
|
||||
&& _cyon_load_parameters "$@" \
|
||||
&& _cyon_print_header "delete" \
|
||||
&& _cyon_login \
|
||||
&& _cyon_change_domain_env \
|
||||
&& _cyon_delete_txt \
|
||||
&& _cyon_logout
|
||||
}
|
||||
|
||||
#########################
|
||||
### PRIVATE FUNCTIONS ###
|
||||
#########################
|
||||
|
||||
_cyon_load_credentials() {
|
||||
# Convert loaded password to/from base64 as needed.
|
||||
if [ "${CY_Password_B64}" ]; then
|
||||
CY_Password="$(printf "%s" "${CY_Password_B64}" | _dbase64 "multiline")"
|
||||
elif [ "${CY_Password}" ]; then
|
||||
CY_Password_B64="$(printf "%s" "${CY_Password}" | _base64)"
|
||||
fi
|
||||
|
||||
if [ -z "${CY_Username}" ] || [ -z "${CY_Password}" ]; then
|
||||
# Dummy entries to satify script checker.
|
||||
CY_Username=""
|
||||
CY_Password=""
|
||||
CY_OTP_Secret=""
|
||||
|
||||
_err ""
|
||||
_err "You haven't set your cyon.ch login credentials yet."
|
||||
_err "Please set the required cyon environment variables."
|
||||
_err ""
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Save the login credentials to the account.conf file.
|
||||
_debug "Save credentials to account.conf"
|
||||
_saveaccountconf CY_Username "${CY_Username}"
|
||||
_saveaccountconf CY_Password_B64 "$CY_Password_B64"
|
||||
if [ ! -z "${CY_OTP_Secret}" ]; then
|
||||
_saveaccountconf CY_OTP_Secret "$CY_OTP_Secret"
|
||||
else
|
||||
_clearaccountconf CY_OTP_Secret
|
||||
fi
|
||||
}
|
||||
|
||||
_cyon_is_idn() {
|
||||
_idn_temp="$(printf "%s" "${1}" | tr -d "0-9a-zA-Z.,-_")"
|
||||
_idn_temp2="$(printf "%s" "${1}" | grep -o "xn--")"
|
||||
[ "$_idn_temp" ] || [ "$_idn_temp2" ]
|
||||
}
|
||||
|
||||
_cyon_load_parameters() {
|
||||
# Read the required parameters to add the TXT entry.
|
||||
# shellcheck disable=SC2018,SC2019
|
||||
fulldomain="$(printf "%s" "${1}" | tr "A-Z" "a-z")"
|
||||
fulldomain_idn="${fulldomain}"
|
||||
|
||||
# Special case for IDNs, as cyon needs a domain environment change,
|
||||
# which uses the "pretty" instead of the punycode version.
|
||||
if _cyon_is_idn "${fulldomain}"; then
|
||||
if ! _exists idn; then
|
||||
_err "Please install idn to process IDN names."
|
||||
_err ""
|
||||
return 1
|
||||
fi
|
||||
|
||||
fulldomain="$(idn -u "${fulldomain}")"
|
||||
fulldomain_idn="$(idn -a "${fulldomain}")"
|
||||
fi
|
||||
|
||||
_debug fulldomain "${fulldomain}"
|
||||
_debug fulldomain_idn "${fulldomain_idn}"
|
||||
|
||||
txtvalue="${2}"
|
||||
_debug txtvalue "${txtvalue}"
|
||||
|
||||
# This header is required for curl calls.
|
||||
_H1="X-Requested-With: XMLHttpRequest"
|
||||
export _H1
|
||||
}
|
||||
|
||||
_cyon_print_header() {
|
||||
if [ "${1}" = "add" ]; then
|
||||
_info ""
|
||||
_info "+---------------------------------------------+"
|
||||
_info "| Adding DNS TXT entry to your cyon.ch domain |"
|
||||
_info "+---------------------------------------------+"
|
||||
_info ""
|
||||
_info " * Full Domain: ${fulldomain}"
|
||||
_info " * TXT Value: ${txtvalue}"
|
||||
_info ""
|
||||
elif [ "${1}" = "delete" ]; then
|
||||
_info ""
|
||||
_info "+-------------------------------------------------+"
|
||||
_info "| Deleting DNS TXT entry from your cyon.ch domain |"
|
||||
_info "+-------------------------------------------------+"
|
||||
_info ""
|
||||
_info " * Full Domain: ${fulldomain}"
|
||||
_info ""
|
||||
fi
|
||||
}
|
||||
|
||||
_cyon_get_cookie_header() {
|
||||
printf "Cookie: %s" "$(grep "cyon=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o 'cyon=[^;]*;' | tr -d ';')"
|
||||
}
|
||||
|
||||
_cyon_login() {
|
||||
_info " - Logging in..."
|
||||
|
||||
username_encoded="$(printf "%s" "${CY_Username}" | _url_encode)"
|
||||
password_encoded="$(printf "%s" "${CY_Password}" | _url_encode)"
|
||||
|
||||
login_url="https://my.cyon.ch/auth/index/dologin-async"
|
||||
login_data="$(printf "%s" "username=${username_encoded}&password=${password_encoded}&pathname=%2F")"
|
||||
|
||||
login_response="$(_post "$login_data" "$login_url")"
|
||||
_debug login_response "${login_response}"
|
||||
|
||||
# Bail if login fails.
|
||||
if [ "$(printf "%s" "${login_response}" | _cyon_get_response_success)" != "success" ]; then
|
||||
_err " $(printf "%s" "${login_response}" | _cyon_get_response_message)"
|
||||
_err ""
|
||||
return 1
|
||||
fi
|
||||
|
||||
_info " success"
|
||||
|
||||
# NECESSARY!! Load the main page after login, to get the new cookie.
|
||||
_H2="$(_cyon_get_cookie_header)"
|
||||
export _H2
|
||||
|
||||
_get "https://my.cyon.ch/" >/dev/null
|
||||
|
||||
# todo: instead of just checking if the env variable is defined, check if we actually need to do a 2FA auth request.
|
||||
|
||||
# 2FA authentication with OTP?
|
||||
if [ ! -z "${CY_OTP_Secret}" ]; then
|
||||
_info " - Authorising with OTP code..."
|
||||
|
||||
if ! _exists oathtool; then
|
||||
_err "Please install oathtool to use 2 Factor Authentication."
|
||||
_err ""
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Get OTP code with the defined secret.
|
||||
otp_code="$(oathtool --base32 --totp "${CY_OTP_Secret}" 2>/dev/null)"
|
||||
|
||||
login_otp_url="https://my.cyon.ch/auth/multi-factor/domultifactorauth-async"
|
||||
login_otp_data="totpcode=${otp_code}&pathname=%2F&rememberme=0"
|
||||
|
||||
login_otp_response="$(_post "$login_otp_data" "$login_otp_url")"
|
||||
_debug login_otp_response "${login_otp_response}"
|
||||
|
||||
# Bail if OTP authentication fails.
|
||||
if [ "$(printf "%s" "${login_otp_response}" | _cyon_get_response_success)" != "success" ]; then
|
||||
_err " $(printf "%s" "${login_otp_response}" | _cyon_get_response_message)"
|
||||
_err ""
|
||||
return 1
|
||||
fi
|
||||
|
||||
_info " success"
|
||||
fi
|
||||
|
||||
_info ""
|
||||
}
|
||||
|
||||
_cyon_logout() {
|
||||
_info " - Logging out..."
|
||||
|
||||
_get "https://my.cyon.ch/auth/index/dologout" >/dev/null
|
||||
|
||||
_info " success"
|
||||
_info ""
|
||||
}
|
||||
|
||||
_cyon_change_domain_env() {
|
||||
_info " - Changing domain environment..."
|
||||
|
||||
# Get the "example.com" part of the full domain name.
|
||||
domain_env="$(printf "%s" "${fulldomain}" | sed -E -e 's/.*\.(.*\..*)$/\1/')"
|
||||
_debug "Changing domain environment to ${domain_env}"
|
||||
|
||||
gloo_item_key="$(_get "https://my.cyon.ch/domain/" | tr '\n' ' ' | sed -E -e "s/.*data-domain=\"${domain_env}\"[^<]*data-itemkey=\"([^\"]*).*/\1/")"
|
||||
_debug gloo_item_key "${gloo_item_key}"
|
||||
|
||||
domain_env_url="https://my.cyon.ch/user/environment/setdomain/d/${domain_env}/gik/${gloo_item_key}"
|
||||
|
||||
domain_env_response="$(_get "${domain_env_url}")"
|
||||
_debug domain_env_response "${domain_env_response}"
|
||||
|
||||
if ! _cyon_check_if_2fa_missed "${domain_env_response}"; then return 1; fi
|
||||
|
||||
domain_env_success="$(printf "%s" "${domain_env_response}" | _egrep_o '"authenticated":\w*' | cut -d : -f 2)"
|
||||
|
||||
# Bail if domain environment change fails.
|
||||
if [ "${domain_env_success}" != "true" ]; then
|
||||
_err " $(printf "%s" "${domain_env_response}" | _cyon_get_response_message)"
|
||||
_err ""
|
||||
return 1
|
||||
fi
|
||||
|
||||
_info " success"
|
||||
_info ""
|
||||
}
|
||||
|
||||
_cyon_add_txt() {
|
||||
_info " - Adding DNS TXT entry..."
|
||||
|
||||
add_txt_url="https://my.cyon.ch/domain/dnseditor/add-record-async"
|
||||
add_txt_data="zone=${fulldomain_idn}.&ttl=900&type=TXT&value=${txtvalue}"
|
||||
|
||||
add_txt_response="$(_post "$add_txt_data" "$add_txt_url")"
|
||||
_debug add_txt_response "${add_txt_response}"
|
||||
|
||||
if ! _cyon_check_if_2fa_missed "${add_txt_response}"; then return 1; fi
|
||||
|
||||
add_txt_message="$(printf "%s" "${add_txt_response}" | _cyon_get_response_message)"
|
||||
add_txt_status="$(printf "%s" "${add_txt_response}" | _cyon_get_response_status)"
|
||||
|
||||
# Bail if adding TXT entry fails.
|
||||
if [ "${add_txt_status}" != "true" ]; then
|
||||
_err " ${add_txt_message}"
|
||||
_err ""
|
||||
return 1
|
||||
fi
|
||||
|
||||
_info " success (TXT|${fulldomain_idn}.|${txtvalue})"
|
||||
_info ""
|
||||
}
|
||||
|
||||
_cyon_delete_txt() {
|
||||
_info " - Deleting DNS TXT entry..."
|
||||
|
||||
list_txt_url="https://my.cyon.ch/domain/dnseditor/list-async"
|
||||
|
||||
list_txt_response="$(_get "${list_txt_url}" | sed -e 's/data-hash/\\ndata-hash/g')"
|
||||
_debug list_txt_response "${list_txt_response}"
|
||||
|
||||
if ! _cyon_check_if_2fa_missed "${list_txt_response}"; then return 1; fi
|
||||
|
||||
# Find and delete all acme challenge entries for the $fulldomain.
|
||||
_dns_entries="$(printf "%b\n" "${list_txt_response}" | sed -n 's/data-hash=\\"\([^"]*\)\\" data-identifier=\\"\([^"]*\)\\".*/\1 \2/p')"
|
||||
|
||||
printf "%s" "${_dns_entries}" | while read -r _hash _identifier; do
|
||||
dns_type="$(printf "%s" "$_identifier" | cut -d'|' -f1)"
|
||||
dns_domain="$(printf "%s" "$_identifier" | cut -d'|' -f2)"
|
||||
|
||||
if [ "${dns_type}" != "TXT" ] || [ "${dns_domain}" != "${fulldomain_idn}." ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
hash_encoded="$(printf "%s" "${_hash}" | _url_encode)"
|
||||
identifier_encoded="$(printf "%s" "${_identifier}" | _url_encode)"
|
||||
|
||||
delete_txt_url="https://my.cyon.ch/domain/dnseditor/delete-record-async"
|
||||
delete_txt_data="$(printf "%s" "hash=${hash_encoded}&identifier=${identifier_encoded}")"
|
||||
|
||||
delete_txt_response="$(_post "$delete_txt_data" "$delete_txt_url")"
|
||||
_debug delete_txt_response "${delete_txt_response}"
|
||||
|
||||
if ! _cyon_check_if_2fa_missed "${delete_txt_response}"; then return 1; fi
|
||||
|
||||
delete_txt_message="$(printf "%s" "${delete_txt_response}" | _cyon_get_response_message)"
|
||||
delete_txt_status="$(printf "%s" "${delete_txt_response}" | _cyon_get_response_status)"
|
||||
|
||||
# Skip if deleting TXT entry fails.
|
||||
if [ "${delete_txt_status}" != "true" ]; then
|
||||
_err " ${delete_txt_message} (${_identifier})"
|
||||
else
|
||||
_info " success (${_identifier})"
|
||||
fi
|
||||
done
|
||||
|
||||
_info " done"
|
||||
_info ""
|
||||
}
|
||||
|
||||
_cyon_get_response_message() {
|
||||
_egrep_o '"message":"[^"]*"' | cut -d : -f 2 | tr -d '"'
|
||||
}
|
||||
|
||||
_cyon_get_response_status() {
|
||||
_egrep_o '"status":\w*' | cut -d : -f 2
|
||||
}
|
||||
|
||||
_cyon_get_response_success() {
|
||||
_egrep_o '"onSuccess":"[^"]*"' | cut -d : -f 2 | tr -d '"'
|
||||
}
|
||||
|
||||
_cyon_check_if_2fa_missed() {
|
||||
# Did we miss the 2FA?
|
||||
if test "${1#*multi_factor_form}" != "${1}"; then
|
||||
_err " Missed OTP authentication!"
|
||||
_err ""
|
||||
return 1
|
||||
fi
|
||||
}
|
@ -0,0 +1,148 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# DNS API for Domain-Offensive / Resellerinterface / Domainrobot
|
||||
|
||||
# Report bugs at https://github.com/seidler2547/acme.sh/issues
|
||||
|
||||
# set these environment variables to match your customer ID and password:
|
||||
# DO_PID="KD-1234567"
|
||||
# DO_PW="cdfkjl3n2"
|
||||
|
||||
DO_URL="https://soap.resellerinterface.de/"
|
||||
|
||||
######## Public functions #####################
|
||||
|
||||
#Usage: dns_myapi_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||
dns_do_add() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
if _dns_do_authenticate; then
|
||||
_info "Adding TXT record to ${_domain} as ${fulldomain}"
|
||||
_dns_do_soap createRR origin "${_domain}" name "${fulldomain}" type TXT data "${txtvalue}" ttl 300
|
||||
if _contains "${response}" '>success<'; then
|
||||
return 0
|
||||
fi
|
||||
_err "Could not create resource record, check logs"
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
#fulldomain
|
||||
dns_do_rm() {
|
||||
fulldomain=$1
|
||||
if _dns_do_authenticate; then
|
||||
if _dns_do_list_rrs; then
|
||||
_dns_do_had_error=0
|
||||
for _rrid in ${_rr_list}; do
|
||||
_info "Deleting resource record $_rrid for $_domain"
|
||||
_dns_do_soap deleteRR origin "${_domain}" rrid "${_rrid}"
|
||||
if ! _contains "${response}" '>success<'; then
|
||||
_dns_do_had_error=1
|
||||
_err "Could not delete resource record for ${_domain}, id ${_rrid}"
|
||||
fi
|
||||
done
|
||||
return $_dns_do_had_error
|
||||
fi
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
#################### Private functions below ##################################
|
||||
_dns_do_authenticate() {
|
||||
_info "Authenticating as ${DO_PID}"
|
||||
_dns_do_soap authPartner partner "${DO_PID}" password "${DO_PW}"
|
||||
if _contains "${response}" '>success<'; then
|
||||
_get_root "$fulldomain"
|
||||
_debug "_domain $_domain"
|
||||
return 0
|
||||
else
|
||||
_err "Authentication failed, are DO_PID and DO_PW set correctly?"
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
_dns_do_list_rrs() {
|
||||
_dns_do_soap getRRList origin "${_domain}"
|
||||
if ! _contains "${response}" 'SOAP-ENC:Array'; then
|
||||
_err "getRRList origin ${_domain} failed"
|
||||
return 1
|
||||
fi
|
||||
_rr_list="$(echo "${response}" \
|
||||
| tr -d "\n\r\t" \
|
||||
| sed -e 's/<item xsi:type="ns2:Map">/\n/g' \
|
||||
| grep ">$(_regexcape "$fulldomain")</value>" \
|
||||
| sed -e 's/<\/item>/\n/g' \
|
||||
| grep '>id</key><value' \
|
||||
| _egrep_o '>[0-9]{1,16}<' \
|
||||
| tr -d '><')"
|
||||
[ "${_rr_list}" ]
|
||||
}
|
||||
|
||||
_dns_do_soap() {
|
||||
func="$1"
|
||||
shift
|
||||
# put the parameters to xml
|
||||
body="<tns:${func} xmlns:tns=\"${DO_URL}\">"
|
||||
while [ "$1" ]; do
|
||||
_k="$1"
|
||||
shift
|
||||
_v="$1"
|
||||
shift
|
||||
body="$body<$_k>$_v</$_k>"
|
||||
done
|
||||
body="$body</tns:${func}>"
|
||||
_debug2 "SOAP request ${body}"
|
||||
|
||||
# build SOAP XML
|
||||
_xml='<?xml version="1.0" encoding="UTF-8"?>
|
||||
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
|
||||
<env:Body>'"$body"'</env:Body>
|
||||
</env:Envelope>'
|
||||
|
||||
# set SOAP headers
|
||||
export _H1="SOAPAction: ${DO_URL}#${func}"
|
||||
|
||||
if ! response="$(_post "${_xml}" "${DO_URL}")"; then
|
||||
_err "Error <$1>"
|
||||
return 1
|
||||
fi
|
||||
_debug2 "SOAP response $response"
|
||||
|
||||
# retrieve cookie header
|
||||
_H2="$(_egrep_o 'Cookie: [^;]+' <"$HTTP_HEADER" | _head_n 1)"
|
||||
export _H2
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
_get_root() {
|
||||
domain=$1
|
||||
i=1
|
||||
|
||||
_dns_do_soap getDomainList
|
||||
_all_domains="$(echo "${response}" \
|
||||
| tr -d "\n\r\t " \
|
||||
| _egrep_o 'domain</key><value[^>]+>[^<]+' \
|
||||
| sed -e 's/^domain<\/key><value[^>]*>//g')"
|
||||
|
||||
while true; do
|
||||
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
|
||||
if [ -z "$h" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if _contains "${_all_domains}" "^$(_regexcape "$h")\$"; then
|
||||
_domain="$h"
|
||||
return 0
|
||||
fi
|
||||
|
||||
i=$(_math $i + 1)
|
||||
done
|
||||
_debug "$domain not found"
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
_regexcape() {
|
||||
echo "$1" | sed -e 's/\([]\.$*^[]\)/\\\1/g'
|
||||
}
|
@ -0,0 +1,123 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# Gandi LiveDNS v5 API
|
||||
# http://doc.livedns.gandi.net/
|
||||
# currently under beta
|
||||
#
|
||||
# Requires GANDI API KEY set in GANDI_LIVEDNS_KEY set as environment variable
|
||||
#
|
||||
#Author: Frédéric Crozat <fcrozat@suse.com>
|
||||
#Report Bugs here: https://github.com/fcrozat/acme.sh
|
||||
#
|
||||
######## Public functions #####################
|
||||
|
||||
GANDI_LIVEDNS_API="https://dns.beta.gandi.net/api/v5"
|
||||
|
||||
#Usage: dns_gandi_livedns_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||
dns_gandi_livedns_add() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
if [ -z "$GANDI_LIVEDNS_KEY" ]; then
|
||||
_err "No API key specifed for Gandi LiveDNS."
|
||||
_err "Create your key and export it as GANDI_LIVEDNS_KEY"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_saveaccountconf GANDI_LIVEDNS_KEY "$GANDI_LIVEDNS_KEY"
|
||||
|
||||
_debug "First detect the root zone"
|
||||
if ! _get_root "$fulldomain"; then
|
||||
_err "invalid domain"
|
||||
return 1
|
||||
fi
|
||||
_debug fulldomain "$fulldomain"
|
||||
_debug txtvalue "$txtvalue"
|
||||
_debug domain "$_domain"
|
||||
_debug sub_domain "$_sub_domain"
|
||||
|
||||
_gandi_livedns_rest PUT "domains/$_domain/records/$_sub_domain/TXT" "{\"rrset_ttl\": 300, \"rrset_values\":[\"$txtvalue\"]}" \
|
||||
&& _contains "$response" '{"message": "Zone Record Created"}' \
|
||||
&& _info "Add $(__green "success")"
|
||||
}
|
||||
|
||||
#Usage: fulldomain txtvalue
|
||||
#Remove the txt record after validation.
|
||||
dns_gandi_livedns_rm() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
_debug "First detect the root zone"
|
||||
if ! _get_root "$fulldomain"; then
|
||||
_err "invalid domain"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug fulldomain "$fulldomain"
|
||||
_debug domain "$_domain"
|
||||
_debug sub_domain "$_sub_domain"
|
||||
|
||||
_gandi_livedns_rest DELETE "domains/$_domain/records/$_sub_domain/TXT" ""
|
||||
|
||||
}
|
||||
|
||||
#################### Private functions below ##################################
|
||||
#_acme-challenge.www.domain.com
|
||||
#returns
|
||||
# _sub_domain=_acme-challenge.www
|
||||
# _domain=domain.com
|
||||
_get_root() {
|
||||
domain=$1
|
||||
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 ! _gandi_livedns_rest GET "domains/$h"; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if _contains "$response" '"code": 401'; then
|
||||
_err "$response"
|
||||
return 1
|
||||
elif _contains "$response" '"code": 404'; then
|
||||
_debug "$h not found"
|
||||
else
|
||||
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
|
||||
_domain="$h"
|
||||
return 0
|
||||
fi
|
||||
p="$i"
|
||||
i=$(_math "$i" + 1)
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
_gandi_livedns_rest() {
|
||||
m=$1
|
||||
ep="$2"
|
||||
data="$3"
|
||||
_debug "$ep"
|
||||
|
||||
export _H1="Content-Type: application/json"
|
||||
export _H2="X-Api-Key: $GANDI_LIVEDNS_KEY"
|
||||
|
||||
if [ "$m" = "GET" ]; then
|
||||
response="$(_get "$GANDI_LIVEDNS_API/$ep")"
|
||||
else
|
||||
_debug data "$data"
|
||||
response="$(_post "$data" "$GANDI_LIVEDNS_API/$ep" "" "$m")"
|
||||
fi
|
||||
|
||||
if [ "$?" != "0" ]; then
|
||||
_err "error $ep"
|
||||
return 1
|
||||
fi
|
||||
_debug2 response "$response"
|
||||
return 0
|
||||
}
|
Loading…
Reference in New Issue