From 3d9608faa086890321ba8d9d630c5b659f89ed46 Mon Sep 17 00:00:00 2001 From: dkerr64 Date: Sat, 22 Feb 2020 20:09:24 -0500 Subject: [PATCH 01/29] Move -T parameter into default ssh command variable --- deploy/ssh.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/deploy/ssh.sh b/deploy/ssh.sh index 9cb0af9..783e6f7 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -12,7 +12,7 @@ # Only a username is required. All others are optional. # # The following examples are for QNAP NAS running QTS 4.2 -# export DEPLOY_SSH_CMD="" # defaults to ssh +# export DEPLOY_SSH_CMD="" # defaults to "ssh -T" # export DEPLOY_SSH_USER="admin" # required # export DEPLOY_SSH_SERVER="qnap" # defaults to domain name # export DEPLOY_SSH_KEYFILE="/etc/stunnel/stunnel.pem" @@ -71,7 +71,7 @@ ssh_deploy() { Le_Deploy_ssh_cmd="$DEPLOY_SSH_CMD" _savedomainconf Le_Deploy_ssh_cmd "$Le_Deploy_ssh_cmd" elif [ -z "$Le_Deploy_ssh_cmd" ]; then - Le_Deploy_ssh_cmd="ssh" + Le_Deploy_ssh_cmd="ssh -T" fi # BACKUP is optional. If not provided then default to yes @@ -194,7 +194,7 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d _info "Submitting sequence of commands to remote server by ssh" # quotations in bash cmd below intended. Squash travis spellcheck error # shellcheck disable=SC2029 - $Le_Deploy_ssh_cmd -T "$Le_Deploy_ssh_user@$Le_Deploy_ssh_server" sh -c "'$_cmdstr'" + $Le_Deploy_ssh_cmd "$Le_Deploy_ssh_user@$Le_Deploy_ssh_server" sh -c "'$_cmdstr'" _ret="$?" if [ "$_ret" != "0" ]; then From 04771e5a4ae243cdc757b7d3159cef92fce40605 Mon Sep 17 00:00:00 2001 From: dkerr64 Date: Sat, 22 Feb 2020 20:16:36 -0500 Subject: [PATCH 02/29] Move call to remote system into separate function --- deploy/ssh.sh | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/deploy/ssh.sh b/deploy/ssh.sh index 783e6f7..8c83f0b 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -31,6 +31,7 @@ ssh_deploy() { _ccert="$3" _cca="$4" _cfullchain="$5" + _err_code=0 _cmdstr="" _homedir='~' _backupprefix="$_homedir/.acme_ssh_deploy/$_cdomain-backup" @@ -190,16 +191,25 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d _info "Backup directories erased after 180 days." fi - _secure_debug "Remote commands to execute: " "$_cmdstr" - _info "Submitting sequence of commands to remote server by ssh" + if ! _ssh_remote_cmd "$_cmdstr"; then + return $_err_code + fi + + return 0 +} + +#cmd +_ssh_remote_cmd() { + _secure_debug "Remote commands to execute: $_cmd" + _info "Submitting sequence of commands to remote server by $Le_Deploy_ssh_cmd" # quotations in bash cmd below intended. Squash travis spellcheck error # shellcheck disable=SC2029 - $Le_Deploy_ssh_cmd "$Le_Deploy_ssh_user@$Le_Deploy_ssh_server" sh -c "'$_cmdstr'" - _ret="$?" + $Le_Deploy_ssh_cmd "$Le_Deploy_ssh_user@$Le_Deploy_ssh_server" sh -c "'$_cmd'" + _err_code="$?" - if [ "$_ret" != "0" ]; then - _err "Error code $_ret returned from $Le_Deploy_ssh_cmd" + if [ "$_err_code" != "0" ]; then + _err "Error code $_err_code returned from $Le_Deploy_ssh_cmd" fi - return $_ret + return $_err_code } From 6420d1239fda00fb5d40299bfbf1b22c4af4762f Mon Sep 17 00:00:00 2001 From: dkerr64 Date: Sat, 22 Feb 2020 20:31:52 -0500 Subject: [PATCH 03/29] Move call to remote system into separate function --- deploy/ssh.sh | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/deploy/ssh.sh b/deploy/ssh.sh index 783e6f7..00d9d21 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -31,6 +31,7 @@ ssh_deploy() { _ccert="$3" _cca="$4" _cfullchain="$5" + _err_code=0 _cmdstr="" _homedir='~' _backupprefix="$_homedir/.acme_ssh_deploy/$_cdomain-backup" @@ -190,16 +191,26 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d _info "Backup directories erased after 180 days." fi - _secure_debug "Remote commands to execute: " "$_cmdstr" - _info "Submitting sequence of commands to remote server by ssh" + if ! _ssh_remote_cmd "$_cmdstr"; then + return $_err_code + fi + + return 0 +} + +#cmd +_ssh_remote_cmd() { + _cmd="$1" + _secure_debug "Remote commands to execute: $_cmd" + _info "Submitting sequence of commands to remote server by $Le_Deploy_ssh_cmd" # quotations in bash cmd below intended. Squash travis spellcheck error # shellcheck disable=SC2029 - $Le_Deploy_ssh_cmd "$Le_Deploy_ssh_user@$Le_Deploy_ssh_server" sh -c "'$_cmdstr'" - _ret="$?" + $Le_Deploy_ssh_cmd "$Le_Deploy_ssh_user@$Le_Deploy_ssh_server" sh -c "'$_cmd'" + _err_code="$?" - if [ "$_ret" != "0" ]; then - _err "Error code $_ret returned from $Le_Deploy_ssh_cmd" + if [ "$_err_code" != "0" ]; then + _err "Error code $_err_code returned from $Le_Deploy_ssh_cmd" fi - return $_ret + return $_err_code } From 283b04df739dff70ed22ee20ffac6a1c576db842 Mon Sep 17 00:00:00 2001 From: dkerr64 Date: Sat, 22 Feb 2020 20:43:28 -0500 Subject: [PATCH 04/29] Move cleanup of backup directory to first step in the function. --- deploy/ssh.sh | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/deploy/ssh.sh b/deploy/ssh.sh index 00d9d21..39a0a21 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -85,6 +85,19 @@ ssh_deploy() { _info "Deploy certificates to remote server $Le_Deploy_ssh_user@$Le_Deploy_ssh_server" + if [ "$Le_Deploy_ssh_backup" = "yes" ]; then + # run cleanup on the backup directory, erase all older + # than 180 days (15552000 seconds). + _cmdstr="{ now=\"\$(date -u +%s)\"; for fn in $_backupprefix*; \ +do if [ -d \"\$fn\" ] && [ \"\$(expr \$now - \$(date -ur \$fn +%s) )\" -ge \"15552000\" ]; \ +then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; done; }; $_cmdstr" + # Alternate version of above... _cmdstr="find $_backupprefix* -type d -mtime +180 2>/dev/null | xargs rm -rf; $_cmdstr" + # Create our backup directory for overwritten cert files. + _cmdstr="mkdir -p $_backupdir; $_cmdstr" + _info "Backup of old certificate files will be placed in remote directory $_backupdir" + _info "Backup directories erased after 180 days." + fi + # KEYFILE is optional. # If provided then private key will be copied to provided filename. if [ -n "$DEPLOY_SSH_KEYFILE" ]; then @@ -178,17 +191,6 @@ ssh_deploy() { if [ -z "$_cmdstr" ]; then _err "No remote commands to excute. Failed to deploy certificates to remote server" return 1 - elif [ "$Le_Deploy_ssh_backup" = "yes" ]; then - # run cleanup on the backup directory, erase all older - # than 180 days (15552000 seconds). - _cmdstr="{ now=\"\$(date -u +%s)\"; for fn in $_backupprefix*; \ -do if [ -d \"\$fn\" ] && [ \"\$(expr \$now - \$(date -ur \$fn +%s) )\" -ge \"15552000\" ]; \ -then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; done; }; $_cmdstr" - # Alternate version of above... _cmdstr="find $_backupprefix* -type d -mtime +180 2>/dev/null | xargs rm -rf; $_cmdstr" - # Create our backup directory for overwritten cert files. - _cmdstr="mkdir -p $_backupdir; $_cmdstr" - _info "Backup of old certificate files will be placed in remote directory $_backupdir" - _info "Backup directories erased after 180 days." fi if ! _ssh_remote_cmd "$_cmdstr"; then From cc820e97c6e7cea1d5de0165bd5b7b5d84249843 Mon Sep 17 00:00:00 2001 From: dkerr64 Date: Sat, 22 Feb 2020 21:10:42 -0500 Subject: [PATCH 05/29] Add support for DEPLOY_SSH_BATCH_MODE with default of yes. Before this update all remote commands were bunched together and sent to the remote host in a single SSH command. This could result in a very long sequence of commands that might be rejected by a remote host (example is VMware ESXi that uses busybox sh). With this update you can set DEPLOY_SSH_BATCH_MODE="no" and each remote command is sent as a separate SSH call so now we do not have big long sequence of commands. Defaults to same behaviour as before this update. --- deploy/ssh.sh | 63 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 55 insertions(+), 8 deletions(-) diff --git a/deploy/ssh.sh b/deploy/ssh.sh index 39a0a21..92aa43d 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -21,6 +21,7 @@ # export DEPLOY_SSH_FULLCHAIN="" # export DEPLOY_SSH_REMOTE_CMD="/etc/init.d/stunnel.sh restart" # export DEPLOY_SSH_BACKUP="" # yes or no, default to yes +# export DEPLOY_SSH_BATCH_MODE="yes" # yes or no, default to yes # ######## Public functions ##################### @@ -83,7 +84,20 @@ ssh_deploy() { fi _savedomainconf Le_Deploy_ssh_backup "$Le_Deploy_ssh_backup" + # BATCH_MODE is optional. If not provided then default to yes + if [ "$DEPLOY_SSH_BATCH_MODE" = "no" ]; then + Le_Deploy_ssh_batch_mode="no" + elif [ -z "$Le_Deploy_ssh_batch_mode" ]; then + Le_Deploy_ssh_batch_mode="yes" + fi + _savedomainconf Le_Deploy_ssh_batch_mode "$Le_Deploy_ssh_batch_mode" + _info "Deploy certificates to remote server $Le_Deploy_ssh_user@$Le_Deploy_ssh_server" + if [ "$Le_Deploy_ssh_batch_mode" = "yes" ]; then + _info "Using BATCH MODE... Multiple commands sent in single call to remote host" + else + _info "Commands sent individually in multiple calls to remote host" + fi if [ "$Le_Deploy_ssh_backup" = "yes" ]; then # run cleanup on the backup directory, erase all older @@ -96,6 +110,12 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d _cmdstr="mkdir -p $_backupdir; $_cmdstr" _info "Backup of old certificate files will be placed in remote directory $_backupdir" _info "Backup directories erased after 180 days." + if [ "$Le_Deploy_ssh_batch_mode" = "no" ]; then + if ! _ssh_remote_cmd "$_cmdstr"; then + return $_err_code + fi + _cmdstr="" + fi fi # KEYFILE is optional. @@ -112,6 +132,12 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d # copy new certificate into file. _cmdstr="$_cmdstr echo \"$(cat "$_ckey")\" > $Le_Deploy_ssh_keyfile;" _info "will copy private key to remote file $Le_Deploy_ssh_keyfile" + if [ "$Le_Deploy_ssh_batch_mode" = "no" ]; then + if ! _ssh_remote_cmd "$_cmdstr"; then + return $_err_code + fi + _cmdstr="" + fi fi # CERTFILE is optional. @@ -132,6 +158,12 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d # copy new certificate into file. _cmdstr="$_cmdstr echo \"$(cat "$_ccert")\" $_pipe $Le_Deploy_ssh_certfile;" _info "will copy certificate to remote file $Le_Deploy_ssh_certfile" + if [ "$Le_Deploy_ssh_batch_mode" = "no" ]; then + if ! _ssh_remote_cmd "$_cmdstr"; then + return $_err_code + fi + _cmdstr="" + fi fi # CAFILE is optional. @@ -153,6 +185,12 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d # copy new certificate into file. _cmdstr="$_cmdstr echo \"$(cat "$_cca")\" $_pipe $Le_Deploy_ssh_cafile;" _info "will copy CA file to remote file $Le_Deploy_ssh_cafile" + if [ "$Le_Deploy_ssh_batch_mode" = "no" ]; then + if ! _ssh_remote_cmd "$_cmdstr"; then + return $_err_code + fi + _cmdstr="" + fi fi # FULLCHAIN is optional. @@ -175,6 +213,12 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d # copy new certificate into file. _cmdstr="$_cmdstr echo \"$(cat "$_cfullchain")\" $_pipe $Le_Deploy_ssh_fullchain;" _info "will copy fullchain to remote file $Le_Deploy_ssh_fullchain" + if [ "$Le_Deploy_ssh_batch_mode" = "no" ]; then + if ! _ssh_remote_cmd "$_cmdstr"; then + return $_err_code + fi + _cmdstr="" + fi fi # REMOTE_CMD is optional. @@ -186,17 +230,20 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d if [ -n "$Le_Deploy_ssh_remote_cmd" ]; then _cmdstr="$_cmdstr $Le_Deploy_ssh_remote_cmd;" _info "Will execute remote command $Le_Deploy_ssh_remote_cmd" + if [ "$Le_Deploy_ssh_batch_mode" = "no" ]; then + if ! _ssh_remote_cmd "$_cmdstr"; then + return $_err_code + fi + _cmdstr="" + fi fi - if [ -z "$_cmdstr" ]; then - _err "No remote commands to excute. Failed to deploy certificates to remote server" - return 1 - fi - - if ! _ssh_remote_cmd "$_cmdstr"; then - return $_err_code + # if running as batch mode then all commands sent in a single SSH call now... + if [ -n "$_cmdstr" ]; then + if ! _ssh_remote_cmd "$_cmdstr"; then + return $_err_code + fi fi - return 0 } From 806b746fc0522bed79a1b51f3c0137a0fa721dc5 Mon Sep 17 00:00:00 2001 From: dkerr64 Date: Sat, 22 Feb 2020 21:23:59 -0500 Subject: [PATCH 06/29] Fix bug where backup and batch_mode yes/no values could not be changed. Once set to "no" then they could never be set back to "yes" --- deploy/ssh.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/ssh.sh b/deploy/ssh.sh index 92aa43d..113ae23 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -79,7 +79,7 @@ ssh_deploy() { # BACKUP is optional. If not provided then default to yes if [ "$DEPLOY_SSH_BACKUP" = "no" ]; then Le_Deploy_ssh_backup="no" - elif [ -z "$Le_Deploy_ssh_backup" ]; then + elif [ -z "$Le_Deploy_ssh_backup" ] || [ "$DEPLOY_SSH_BACKUP" = "yes" ]; then Le_Deploy_ssh_backup="yes" fi _savedomainconf Le_Deploy_ssh_backup "$Le_Deploy_ssh_backup" @@ -87,7 +87,7 @@ ssh_deploy() { # BATCH_MODE is optional. If not provided then default to yes if [ "$DEPLOY_SSH_BATCH_MODE" = "no" ]; then Le_Deploy_ssh_batch_mode="no" - elif [ -z "$Le_Deploy_ssh_batch_mode" ]; then + elif [ -z "$Le_Deploy_ssh_batch_mode" ] || [ "$DEPLOY_SSH_BATCH_MODE" = "yes" ]; then Le_Deploy_ssh_batch_mode="yes" fi _savedomainconf Le_Deploy_ssh_batch_mode "$Le_Deploy_ssh_batch_mode" From 46ee74ed1687bcc5dbb7732bf7483e6c793ec253 Mon Sep 17 00:00:00 2001 From: dkerr64 Date: Sat, 22 Feb 2020 22:05:06 -0500 Subject: [PATCH 07/29] Remove variable from info/error printout that could potentially expose login credentials. --- deploy/ssh.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/ssh.sh b/deploy/ssh.sh index 113ae23..b68dad7 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -251,14 +251,14 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d _ssh_remote_cmd() { _cmd="$1" _secure_debug "Remote commands to execute: $_cmd" - _info "Submitting sequence of commands to remote server by $Le_Deploy_ssh_cmd" + _info "Submitting sequence of commands to remote server by ssh" # quotations in bash cmd below intended. Squash travis spellcheck error # shellcheck disable=SC2029 $Le_Deploy_ssh_cmd "$Le_Deploy_ssh_user@$Le_Deploy_ssh_server" sh -c "'$_cmd'" _err_code="$?" if [ "$_err_code" != "0" ]; then - _err "Error code $_err_code returned from $Le_Deploy_ssh_cmd" + _err "Error code $_err_code returned from ssh" fi return $_err_code From f73a49440790018aacff9e1d540c937f481cfc20 Mon Sep 17 00:00:00 2001 From: dkerr64 Date: Sat, 22 Feb 2020 22:09:28 -0500 Subject: [PATCH 08/29] Remove spaces on blank line to fix travis error --- deploy/ssh.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/ssh.sh b/deploy/ssh.sh index b68dad7..b3e040b 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -91,7 +91,7 @@ ssh_deploy() { Le_Deploy_ssh_batch_mode="yes" fi _savedomainconf Le_Deploy_ssh_batch_mode "$Le_Deploy_ssh_batch_mode" - + _info "Deploy certificates to remote server $Le_Deploy_ssh_user@$Le_Deploy_ssh_server" if [ "$Le_Deploy_ssh_batch_mode" = "yes" ]; then _info "Using BATCH MODE... Multiple commands sent in single call to remote host" From 8ba573d1967e13dcdc03631308f5dbdd3acf565c Mon Sep 17 00:00:00 2001 From: dkerr64 Date: Tue, 3 Mar 2020 13:40:33 -0500 Subject: [PATCH 09/29] Change variable name to MULTI_CALL so default can be "no" --- deploy/ssh.sh | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/deploy/ssh.sh b/deploy/ssh.sh index b3e040b..7eed8a3 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -21,7 +21,7 @@ # export DEPLOY_SSH_FULLCHAIN="" # export DEPLOY_SSH_REMOTE_CMD="/etc/init.d/stunnel.sh restart" # export DEPLOY_SSH_BACKUP="" # yes or no, default to yes -# export DEPLOY_SSH_BATCH_MODE="yes" # yes or no, default to yes +# export DEPLOY_SSH_MULTI_CALL="" # yes or no, default to no # ######## Public functions ##################### @@ -84,19 +84,19 @@ ssh_deploy() { fi _savedomainconf Le_Deploy_ssh_backup "$Le_Deploy_ssh_backup" - # BATCH_MODE is optional. If not provided then default to yes - if [ "$DEPLOY_SSH_BATCH_MODE" = "no" ]; then - Le_Deploy_ssh_batch_mode="no" - elif [ -z "$Le_Deploy_ssh_batch_mode" ] || [ "$DEPLOY_SSH_BATCH_MODE" = "yes" ]; then - Le_Deploy_ssh_batch_mode="yes" + # MULTI_CALL is optional. If not provided then default to no + if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then + Le_Deploy_ssh_multi_call="yes" + elif [ -z "$Le_Deploy_ssh_multi_call" ] || [ "$DEPLOY_SSH_MULTI_CALL" = "no" ]; then + Le_Deploy_ssh_multi_call="no" fi - _savedomainconf Le_Deploy_ssh_batch_mode "$Le_Deploy_ssh_batch_mode" + _savedomainconf Le_Deploy_ssh_multi_call "$Le_Deploy_ssh_multi_call" _info "Deploy certificates to remote server $Le_Deploy_ssh_user@$Le_Deploy_ssh_server" - if [ "$Le_Deploy_ssh_batch_mode" = "yes" ]; then - _info "Using BATCH MODE... Multiple commands sent in single call to remote host" + if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then + _info "Using MULTI_CALL mode... Required commands sent in multiple calls to remote host" else - _info "Commands sent individually in multiple calls to remote host" + _info "Required commands batched and sent in single call to remote host" fi if [ "$Le_Deploy_ssh_backup" = "yes" ]; then @@ -110,7 +110,7 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d _cmdstr="mkdir -p $_backupdir; $_cmdstr" _info "Backup of old certificate files will be placed in remote directory $_backupdir" _info "Backup directories erased after 180 days." - if [ "$Le_Deploy_ssh_batch_mode" = "no" ]; then + if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then if ! _ssh_remote_cmd "$_cmdstr"; then return $_err_code fi @@ -132,7 +132,7 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d # copy new certificate into file. _cmdstr="$_cmdstr echo \"$(cat "$_ckey")\" > $Le_Deploy_ssh_keyfile;" _info "will copy private key to remote file $Le_Deploy_ssh_keyfile" - if [ "$Le_Deploy_ssh_batch_mode" = "no" ]; then + if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then if ! _ssh_remote_cmd "$_cmdstr"; then return $_err_code fi @@ -158,7 +158,7 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d # copy new certificate into file. _cmdstr="$_cmdstr echo \"$(cat "$_ccert")\" $_pipe $Le_Deploy_ssh_certfile;" _info "will copy certificate to remote file $Le_Deploy_ssh_certfile" - if [ "$Le_Deploy_ssh_batch_mode" = "no" ]; then + if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then if ! _ssh_remote_cmd "$_cmdstr"; then return $_err_code fi @@ -185,7 +185,7 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d # copy new certificate into file. _cmdstr="$_cmdstr echo \"$(cat "$_cca")\" $_pipe $Le_Deploy_ssh_cafile;" _info "will copy CA file to remote file $Le_Deploy_ssh_cafile" - if [ "$Le_Deploy_ssh_batch_mode" = "no" ]; then + if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then if ! _ssh_remote_cmd "$_cmdstr"; then return $_err_code fi @@ -213,7 +213,7 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d # copy new certificate into file. _cmdstr="$_cmdstr echo \"$(cat "$_cfullchain")\" $_pipe $Le_Deploy_ssh_fullchain;" _info "will copy fullchain to remote file $Le_Deploy_ssh_fullchain" - if [ "$Le_Deploy_ssh_batch_mode" = "no" ]; then + if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then if ! _ssh_remote_cmd "$_cmdstr"; then return $_err_code fi @@ -230,7 +230,7 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d if [ -n "$Le_Deploy_ssh_remote_cmd" ]; then _cmdstr="$_cmdstr $Le_Deploy_ssh_remote_cmd;" _info "Will execute remote command $Le_Deploy_ssh_remote_cmd" - if [ "$Le_Deploy_ssh_batch_mode" = "no" ]; then + if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then if ! _ssh_remote_cmd "$_cmdstr"; then return $_err_code fi @@ -238,7 +238,7 @@ then rm -rf \"\$fn\"; echo \"Backup \$fn deleted as older than 180 days\"; fi; d fi fi - # if running as batch mode then all commands sent in a single SSH call now... + # if commands not all sent in multiple calls then all commands sent in a single SSH call now... if [ -n "$_cmdstr" ]; then if ! _ssh_remote_cmd "$_cmdstr"; then return $_err_code From 15b841da06e0f2babf639103e7d0d5615a8d9f7b Mon Sep 17 00:00:00 2001 From: Honza Hommer Date: Sun, 8 Mar 2020 04:47:55 +0100 Subject: [PATCH 10/29] Feat: simplify conditions for bin and command --- notify/mail.sh | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/notify/mail.sh b/notify/mail.sh index ec9aa0d..f992cd4 100644 --- a/notify/mail.sh +++ b/notify/mail.sh @@ -76,17 +76,16 @@ mail_send() { } _mail_bin() { - if [ -n "$MAIL_BIN" ]; then - _MAIL_BIN="$MAIL_BIN" - elif _exists "sendmail"; then - _MAIL_BIN="sendmail" - elif _exists "ssmtp"; then - _MAIL_BIN="ssmtp" - elif _exists "mutt"; then - _MAIL_BIN="mutt" - elif _exists "mail"; then - _MAIL_BIN="mail" - else + _MAIL_BIN="" + + for b in "$MAIL_BIN" sendmail ssmtp mutt mail; do + if _exists "$b"; then + _MAIL_BIN="$b" + break + fi + done + + if [ -z "$_MAIL_BIN" ]; then _err "Please install sendmail, ssmtp, mutt or mail first." return 1 fi @@ -95,25 +94,22 @@ _mail_bin() { } _mail_cmnd() { + _MAIL_ARGS="" + case $(basename "$_MAIL_BIN") in sendmail) if [ -n "$MAIL_FROM" ]; then - echo "'$_MAIL_BIN' -f '$MAIL_FROM' '$MAIL_TO'" - else - echo "'$_MAIL_BIN' '$MAIL_TO'" + _MAIL_ARGS="-f '$MAIL_FROM'" fi ;; - ssmtp) - echo "'$_MAIL_BIN' '$MAIL_TO'" - ;; mutt | mail) - echo "'$_MAIL_BIN' -s '$_subject' '$MAIL_TO'" + _MAIL_ARGS="-s '$_subject'" ;; *) - _err "Command $MAIL_BIN is not supported, use sendmail, ssmtp, mutt or mail." - return 1 ;; esac + + echo "'$_MAIL_BIN' $_MAIL_ARGS '$MAIL_TO'" } _mail_body() { From 554e083f3d387baacbc151b98463efc697091706 Mon Sep 17 00:00:00 2001 From: dkerr64 Date: Wed, 11 Mar 2020 10:58:36 -0400 Subject: [PATCH 11/29] For MULTI_CALL default to undefined, deleting entry in config file if set to "no" --- deploy/ssh.sh | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/deploy/ssh.sh b/deploy/ssh.sh index 7eed8a3..5d1ee80 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -20,8 +20,8 @@ # export DEPLOY_SSH_CAFILE="/etc/stunnel/uca.pem" # export DEPLOY_SSH_FULLCHAIN="" # export DEPLOY_SSH_REMOTE_CMD="/etc/init.d/stunnel.sh restart" -# export DEPLOY_SSH_BACKUP="" # yes or no, default to yes -# export DEPLOY_SSH_MULTI_CALL="" # yes or no, default to no +# export DEPLOY_SSH_BACKUP="" # yes or no, default to yes or previously saved value +# export DEPLOY_SSH_MULTI_CALL="" # yes or no, default to no or previously saved value # ######## Public functions ##################### @@ -76,7 +76,7 @@ ssh_deploy() { Le_Deploy_ssh_cmd="ssh -T" fi - # BACKUP is optional. If not provided then default to yes + # BACKUP is optional. If not provided then default to previously saved value or yes. if [ "$DEPLOY_SSH_BACKUP" = "no" ]; then Le_Deploy_ssh_backup="no" elif [ -z "$Le_Deploy_ssh_backup" ] || [ "$DEPLOY_SSH_BACKUP" = "yes" ]; then @@ -84,13 +84,15 @@ ssh_deploy() { fi _savedomainconf Le_Deploy_ssh_backup "$Le_Deploy_ssh_backup" - # MULTI_CALL is optional. If not provided then default to no + # MULTI_CALL is optional. If not provided then default to previously saved + # value (which may be undefined... equivalent to "no"). if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then Le_Deploy_ssh_multi_call="yes" - elif [ -z "$Le_Deploy_ssh_multi_call" ] || [ "$DEPLOY_SSH_MULTI_CALL" = "no" ]; then - Le_Deploy_ssh_multi_call="no" + _savedomainconf Le_Deploy_ssh_multi_call "$Le_Deploy_ssh_multi_call" + elif [ "$DEPLOY_SSH_MULTI_CALL" = "no" ]; then + Le_Deploy_ssh_multi_call="" + _cleardomainconf Le_Deploy_ssh_multi_call fi - _savedomainconf Le_Deploy_ssh_multi_call "$Le_Deploy_ssh_multi_call" _info "Deploy certificates to remote server $Le_Deploy_ssh_user@$Le_Deploy_ssh_server" if [ "$Le_Deploy_ssh_multi_call" = "yes" ]; then From 2a8746f6b0702238b28a69a79e8fe4d05ffcaddc Mon Sep 17 00:00:00 2001 From: Honza Hommer Date: Sun, 8 Mar 2020 04:51:39 +0100 Subject: [PATCH 12/29] Feat: add msmtp command --- notify/mail.sh | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/notify/mail.sh b/notify/mail.sh index f992cd4..54b2a6d 100644 --- a/notify/mail.sh +++ b/notify/mail.sh @@ -6,6 +6,7 @@ #MAIL_FROM="yyyy@gmail.com" #MAIL_TO="yyyy@gmail.com" #MAIL_NOVALIDATE="" +#MAIL_MSMTP_ACCOUNT="" mail_send() { _subject="$1" @@ -78,7 +79,7 @@ mail_send() { _mail_bin() { _MAIL_BIN="" - for b in "$MAIL_BIN" sendmail ssmtp mutt mail; do + for b in "$MAIL_BIN" sendmail ssmtp mutt mail msmtp; do if _exists "$b"; then _MAIL_BIN="$b" break @@ -86,7 +87,7 @@ _mail_bin() { done if [ -z "$_MAIL_BIN" ]; then - _err "Please install sendmail, ssmtp, mutt or mail first." + _err "Please install sendmail, ssmtp, mutt, mail or msmtp first." return 1 fi @@ -105,8 +106,16 @@ _mail_cmnd() { mutt | mail) _MAIL_ARGS="-s '$_subject'" ;; - *) + msmtp) + if [ -n "$MAIL_FROM" ]; then + _MAIL_ARGS="-f '$MAIL_FROM'" + fi + + if [ -n "$MAIL_MSMTP_ACCOUNT" ]; then + _MAIL_ARGS="$_MAIL_ARGS -a '$MAIL_MSMTP_ACCOUNT'" + fi ;; + *) ;; esac echo "'$_MAIL_BIN' $_MAIL_ARGS '$MAIL_TO'" @@ -114,7 +123,7 @@ _mail_cmnd() { _mail_body() { case $(basename "$_MAIL_BIN") in - sendmail | ssmtp) + sendmail | ssmtp | msmtp) if [ -n "$MAIL_FROM" ]; then echo "From: $MAIL_FROM" fi From f38df4df1151822d50628be22f27ab3eb20429f4 Mon Sep 17 00:00:00 2001 From: dkerr64 Date: Sat, 14 Mar 2020 21:51:21 -0400 Subject: [PATCH 13/29] Make remote backup directory path user configurable. --- deploy/ssh.sh | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/deploy/ssh.sh b/deploy/ssh.sh index 5d1ee80..d71637a 100644 --- a/deploy/ssh.sh +++ b/deploy/ssh.sh @@ -21,6 +21,7 @@ # export DEPLOY_SSH_FULLCHAIN="" # export DEPLOY_SSH_REMOTE_CMD="/etc/init.d/stunnel.sh restart" # export DEPLOY_SSH_BACKUP="" # yes or no, default to yes or previously saved value +# export DEPLOY_SSH_BACKUP_PATH=".acme_ssh_deploy" # path on remote system. Defaults to .acme_ssh_deploy # export DEPLOY_SSH_MULTI_CALL="" # yes or no, default to no or previously saved value # ######## Public functions ##################### @@ -34,9 +35,8 @@ ssh_deploy() { _cfullchain="$5" _err_code=0 _cmdstr="" - _homedir='~' - _backupprefix="$_homedir/.acme_ssh_deploy/$_cdomain-backup" - _backupdir="$_backupprefix-$(_utc_date | tr ' ' '-')" + _backupprefix="" + _backupdir="" if [ -f "$DOMAIN_CONF" ]; then # shellcheck disable=SC1090 @@ -84,6 +84,14 @@ ssh_deploy() { fi _savedomainconf Le_Deploy_ssh_backup "$Le_Deploy_ssh_backup" + # BACKUP_PATH is optional. If not provided then default to previously saved value or .acme_ssh_deploy + if [ -n "$DEPLOY_SSH_BACKUP_PATH" ]; then + Le_Deploy_ssh_backup_path="$DEPLOY_SSH_BACKUP_PATH" + elif [ -z "$Le_Deploy_ssh_backup_path" ]; then + Le_Deploy_ssh_backup_path=".acme_ssh_deploy" + fi + _savedomainconf Le_Deploy_ssh_backup_path "$Le_Deploy_ssh_backup_path" + # MULTI_CALL is optional. If not provided then default to previously saved # value (which may be undefined... equivalent to "no"). if [ "$DEPLOY_SSH_MULTI_CALL" = "yes" ]; then @@ -102,6 +110,8 @@ ssh_deploy() { fi if [ "$Le_Deploy_ssh_backup" = "yes" ]; then + _backupprefix="$Le_Deploy_ssh_backup_path/$_cdomain-backup" + _backupdir="$_backupprefix-$(_utc_date | tr ' ' '-')" # run cleanup on the backup directory, erase all older # than 180 days (15552000 seconds). _cmdstr="{ now=\"\$(date -u +%s)\"; for fn in $_backupprefix*; \ From 4fa59ea04ec8e31777ce4fcd7c4456094518dee4 Mon Sep 17 00:00:00 2001 From: Ehsan Aliakbar Date: Tue, 24 Mar 2020 17:56:50 +0430 Subject: [PATCH 14/29] Adding Arvan Dns Api --- dnsapi/dns_arvan.sh | 163 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 dnsapi/dns_arvan.sh diff --git a/dnsapi/dns_arvan.sh b/dnsapi/dns_arvan.sh new file mode 100644 index 0000000..af9de46 --- /dev/null +++ b/dnsapi/dns_arvan.sh @@ -0,0 +1,163 @@ +#!/usr/bin/env sh + +#Arvan_Token="xxxx" + +ARVAN_API_URL="https://napi.arvancloud.com/cdn/4.0/domains" + +#Author: Ehsan Aliakbar +#Report Bugs here: https://github.com/Neilpang/acme.sh +# +######## Public functions ##################### + +#Usage: dns_arvan_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" +dns_arvan_add() { + fulldomain=$1 + txtvalue=$2 + _info "Using Arvan" + + Arvan_Token="${Arvan_Token:-$(_readaccountconf_mutable Arvan_Token)}" + + if [ -z "$Arvan_Token" ]; then + _err "You didn't specify \"Arvan_Token\" token yet." + _err "You can get yours from here https://npanel.arvancloud.com/profile/api-keys" + return 1 + fi + #save the api token to the account conf file. + _saveaccountconf_mutable Arvan_Token "$Arvan_Token" + + _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" + + _info "Adding record" + if _arvan_rest POST "$_domain/dns-records" "{\"type\":\"TXT\",\"name\":\"$_sub_domain\",\"value\":{\"text\":\"$txtvalue\"},\"ttl\":120}"; then + if _contains "$response" "$txtvalue"; then + _info "Added, OK" + return 0 + elif _contains "$response" "Record Data is Duplicated"; then + _info "Already exists, 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_arvan_rm() { + fulldomain=$1 + txtvalue=$2 + _info "Using Arvan" + _debug fulldomain "$fulldomain" + _debug txtvalue "$txtvalue" + + Arvan_Token="${Arvan_Token:-$(_readaccountconf_mutable Arvan_Token)}" + + _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" + shorted_txtvalue=$(printf "%s" "$txtvalue" | cut -d "-" -d "_" -f1) + _arvan_rest GET "${_domain}/dns-records?search=$shorted_txtvalue" + + if ! printf "%s" "$response" | grep \"current_page\":1 >/dev/null; then + _err "Error on Arvan Api" + -err "Please create a github issue with debbug log" + return 1 + fi + + count=$(printf "%s\n" "$response" | _egrep_o "\"total\":[^,]*" | cut -d : -f 2) + _debug count "$count" + if [ "$count" = "0" ]; then + _info "Don't need to remove." + else + record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | head -n 1) + _debug "record_id" "$record_id" + if [ -z "$record_id" ]; then + _err "Can not get record id to remove." + return 1 + fi + if ! _arvan_rest "DELETE" "${_domain}/dns-records/$record_id"; then + _err "Delete record error." + return 1 + fi + _debug "$response" + _contains "$response" 'dns record deleted' + 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=1 + 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 ! _arvan_rest GET "?search=$h"; then + return 1 + fi + + if _contains "$response" "\"domain\":\"$h\"" || _contains "$response" '"total":1'; then + _domain_id=$(echo "$response" | _egrep_o "\[.\"id\":\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \") + if [ "$_domain_id" ]; then + _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) + _domain=$h + return 0 + fi + return 1 + fi + p=$i + i=$(_math "$i" + 1) + done + return 1 +} + +_arvan_rest() { + mtd="$1" + ep="$2" + data="$3" + + token_trimmed=$(echo "$Arvan_Token" | tr -d '"') + + export _H1="Authorization: $token_trimmed" + + if [ "$mtd" == "DELETE" ]; then + # DELETE Request shouldn't have Content-Type + _debug data "$data" + response="$(_post "$data" "$ARVAN_API_URL/$ep" "" "$mtd")" + elif [ "$mtd" == "POST" ]; then + export _H2="Content-Type: application/json" + _debug data "$data" + response="$(_post "$data" "$ARVAN_API_URL/$ep" "" "$mtd")" + else + response="$(_get "$ARVAN_API_URL/$ep$data")" + fi +} \ No newline at end of file From 200cd5972aac175a11536218cb2b21c0026a6172 Mon Sep 17 00:00:00 2001 From: Ehsan Aliakbar Date: Sat, 28 Mar 2020 21:50:58 +0430 Subject: [PATCH 15/29] fix shellcheck errors in Arvan Dns Api --- dnsapi/dns_arvan.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_arvan.sh b/dnsapi/dns_arvan.sh index af9de46..341c8c1 100644 --- a/dnsapi/dns_arvan.sh +++ b/dnsapi/dns_arvan.sh @@ -78,7 +78,7 @@ dns_arvan_rm() { if ! printf "%s" "$response" | grep \"current_page\":1 >/dev/null; then _err "Error on Arvan Api" - -err "Please create a github issue with debbug log" + _err "Please create a github issue with debbug log" return 1 fi @@ -149,11 +149,11 @@ _arvan_rest() { export _H1="Authorization: $token_trimmed" - if [ "$mtd" == "DELETE" ]; then + if [ "$mtd" = "DELETE" ]; then # DELETE Request shouldn't have Content-Type _debug data "$data" response="$(_post "$data" "$ARVAN_API_URL/$ep" "" "$mtd")" - elif [ "$mtd" == "POST" ]; then + elif [ "$mtd" = "POST" ]; then export _H2="Content-Type: application/json" _debug data "$data" response="$(_post "$data" "$ARVAN_API_URL/$ep" "" "$mtd")" From 5fac282ee098394ee3cd6eff1975e699bc5ce9b2 Mon Sep 17 00:00:00 2001 From: der-berni Date: Tue, 7 Apr 2020 19:25:39 +0200 Subject: [PATCH 16/29] Update to work with new one.com procedure Since some Months, its no longer possible to add TXT Records with the Name "_acme-challenge" to the base domain. To override the fallback value, you must use a CNAME and proxy it. For example. CNAME _acme-challenge.yourdomain.com => proxy_acme-challenge.yourdomain.com The TXT Records have to be created on proxy_acme-challenge.yourdomain.com Since the default CNAME TTL is 3600 seconds, it is recommended to leave the CNAME record. But if you would like to use the build-in SSL (for your web-site etc.) from one.com, you have to delete the record. A new variable "ONECOM_KeepCnameProxy" you can set in the account.conf is used to keep the CNAME record. By default the CNAME record will be removed. For ex.: SAVED_ONECOM_KeepCnameProxy='1' to keep the CNAME Record and speedup the process. --- dnsapi/dns_one.sh | 189 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 143 insertions(+), 46 deletions(-) diff --git a/dnsapi/dns_one.sh b/dnsapi/dns_one.sh index 0fdc3d5..4cc159d 100644 --- a/dnsapi/dns_one.sh +++ b/dnsapi/dns_one.sh @@ -5,7 +5,7 @@ # Author: github: @diseq # Created: 2019-02-17 # Fixed by: @der-berni -# Modified: 2019-05-31 +# Modified: 2020-04-07 # # export ONECOM_User="username" # export ONECOM_Password="password" @@ -29,33 +29,46 @@ dns_one_add() { _err "root domain not found" return 1 fi - - mysubdomain=$_sub_domain - mydomain=$_domain - _debug mysubdomain "$mysubdomain" - _debug mydomain "$mydomain" - - # get entries - response="$(_get "https://www.one.com/admin/api/domains/$mydomain/dns/custom_records")" - _debug response "$response" - - # Update the IP address for domain entry - postdata="{\"type\":\"dns_custom_records\",\"attributes\":{\"priority\":0,\"ttl\":600,\"type\":\"TXT\",\"prefix\":\"$mysubdomain\",\"content\":\"$txtvalue\"}}" - _debug postdata "$postdata" - response="$(_post "$postdata" "https://www.one.com/admin/api/domains/$mydomain/dns/custom_records" "" "POST" "application/json")" - response="$(echo "$response" | _normalizeJson)" - _debug response "$response" - - id=$(echo "$response" | sed -n "s/{\"result\":{\"data\":{\"type\":\"dns_custom_records\",\"id\":\"\([^\"]*\)\",\"attributes\":{\"prefix\":\"$mysubdomain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"priority\":0,\"ttl\":600}}},\"metadata\":null}/\1/p") - + + subdomain="${_sub_domain}" + maindomain=${_domain} + + useProxy=0 + if [ "${_sub_domain}" = "_acme-challenge" ]; then + subdomain="proxy${_sub_domain}" + useProxy=1 + fi + + _debug subdomain "$subdomain" + _debug maindomain "$maindomain" + + if [ $useProxy -eq 1 ]; then + #Check if the CNAME exists + _dns_one_getrecord "CNAME" "$_sub_domain" "$subdomain.$maindomain" + if [ -z "$id" ]; then + _info "$(__red "Add CNAME Proxy record: '$(__green "\"$_sub_domain\" => \"$subdomain.$maindomain\"")'")" + _dns_one_addrecord "CNAME" "$_sub_domain" "$subdomain.$maindomain" + + _info "Not valid yet, let's wait 1 hour to take effect." + _sleep 3600 + fi + fi + + #Check if the TXT exists + _dns_one_getrecord "TXT" "$subdomain" "$txtvalue" + if [ ! -z "$id" ]; then + _info "$(__green "Txt record with the same value found. Skip adding.")" + return 0 + fi + + _dns_one_addrecord "TXT" "$subdomain" "$txtvalue" if [ -z "$id" ]; then - _err "Add txt record error." + _err "Add CNAME record error." return 1 else - _info "Added, OK ($id)" + _info "$(__green "Added, OK ($id)")" return 0 fi - } dns_one_rm() { @@ -73,36 +86,46 @@ dns_one_rm() { return 1 fi - mysubdomain=$_sub_domain - mydomain=$_domain - _debug mysubdomain "$mysubdomain" - _debug mydomain "$mydomain" - - # get entries - response="$(_get "https://www.one.com/admin/api/domains/$mydomain/dns/custom_records")" - response="$(echo "$response" | _normalizeJson)" - _debug response "$response" - - id=$(printf -- "%s" "$response" | sed -n "s/.*{\"type\":\"dns_custom_records\",\"id\":\"\([^\"]*\)\",\"attributes\":{\"prefix\":\"$mysubdomain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"priority\":0,\"ttl\":600}.*/\1/p") - + subdomain="${_sub_domain}" + maindomain=${_domain} + + useProxy=0 + if [ "${_sub_domain}" = "_acme-challenge" ]; then + subdomain="proxy${_sub_domain}" + useProxy=1 + fi + + _debug subdomain "$subdomain" + _debug maindomain "$maindomain" + if [ $useProxy -eq 1 ]; then + if [ "$ONECOM_KeepCnameProxy" = "1" ]; then + _info "$(__red "Keeping CNAME Proxy record: '$(__green "\"$_sub_domain\" => \"$subdomain.$maindomain\"")'")" + else + #Check if the CNAME exists + _dns_one_getrecord "CNAME" "$_sub_domain" "$subdomain.$maindomain" + if [ ! -z "$id" ]; then + _info "$(__red "Removing CNAME Proxy record: '$(__green "\"$_sub_domain\" => \"$subdomain.$maindomain\"")'")" + _dns_one_delrecord "$id" + fi + fi + fi + + #Check if the TXT exists + _dns_one_getrecord "TXT" "$subdomain" "$txtvalue" if [ -z "$id" ]; then _err "Txt record not found." return 1 fi - + # delete entry - response="$(_post "$postdata" "https://www.one.com/admin/api/domains/$mydomain/dns/custom_records/$id" "" "DELETE" "application/json")" - response="$(echo "$response" | _normalizeJson)" - _debug response "$response" - - if [ "$response" = '{"result":null,"metadata":null}' ]; then - _info "Removed, OK" - return 0 + + if _dns_one_delrecord "$id"; then + _info "$(__green Removed, OK)" + return 0 else - _err "Removing txt record error." - return 1 + _err "Removing txt record error." + return 1 fi - } #_acme-challenge.www.domain.com @@ -138,6 +161,7 @@ _get_root() { _dns_one_login() { # get credentials + ONECOM_KeepCnameProxy="${ONECOM_KeepCnameProxy:-$(_readaccountconf_mutable ONECOM_KeepCnameProxy)}" ONECOM_User="${ONECOM_User:-$(_readaccountconf_mutable ONECOM_User)}" ONECOM_Password="${ONECOM_Password:-$(_readaccountconf_mutable ONECOM_Password)}" if [ -z "$ONECOM_User" ] || [ -z "$ONECOM_Password" ]; then @@ -177,3 +201,76 @@ _dns_one_login() { return 0 } + +_dns_one_getrecord() { + type="$1" + name="$2" + value="$3" + if [ -z "$type" ]; then + type="TXT" + fi + if [ -z "$name" ]; then + _err "Record name is empty." + return 1 + fi + + response="$(_get "https://www.one.com/admin/api/domains/$maindomain/dns/custom_records")" + response="$(echo "$response" | _normalizeJson)" + _debug response "$response" + + if [ -z "${value}" ]; then + id=$(printf -- "%s" "$response" | sed -n "s/.*{\"type\":\"dns_custom_records\",\"id\":\"\([^\"]*\)\",\"attributes\":{\"prefix\":\"${name}\",\"type\":\"${type}\",\"content\":\"[^\"]*\",\"priority\":0,\"ttl\":600}.*/\1/p") + response=$(printf -- "%s" "$response" | sed -n "s/.*{\"type\":\"dns_custom_records\",\"id\":\"[^\"]*\",\"attributes\":{\"prefix\":\"${name}\",\"type\":\"${type}\",\"content\":\"\([^\"]*\)\",\"priority\":0,\"ttl\":600}.*/\1/p") + else + id=$(printf -- "%s" "$response" | sed -n "s/.*{\"type\":\"dns_custom_records\",\"id\":\"\([^\"]*\)\",\"attributes\":{\"prefix\":\"${name}\",\"type\":\"${type}\",\"content\":\"${value}\",\"priority\":0,\"ttl\":600}.*/\1/p") + fi + if [ -z "$id" ]; then + _err "Record not found." + return 1 + fi + return 0 +} + +_dns_one_addrecord() { + type="$1" + name="$2" + value="$3" + if [ -z "$type" ]; then + type="TXT" + fi + if [ -z "$name" ]; then + _err "Record name is empty." + return 1 + fi + + postdata="{\"type\":\"dns_custom_records\",\"attributes\":{\"priority\":0,\"ttl\":600,\"type\":\"${type}\",\"prefix\":\"${name}\",\"content\":\"${value}\"}}" + _debug postdata "$postdata" + response="$(_post "$postdata" "https://www.one.com/admin/api/domains/$maindomain/dns/custom_records" "" "POST" "application/json")" + response="$(echo "$response" | _normalizeJson)" + _debug response "$response" + + id=$(echo "$response" | sed -n "s/{\"result\":{\"data\":{\"type\":\"dns_custom_records\",\"id\":\"\([^\"]*\)\",\"attributes\":{\"prefix\":\"$subdomain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"priority\":0,\"ttl\":600}}},\"metadata\":null}/\1/p") + + if [ -z "$id" ]; then + return 1 + else + return 0 + fi +} + +_dns_one_delrecord() { + id="$1" + if [ -z "$id" ]; then + return 1 + fi + + response="$(_post "" "https://www.one.com/admin/api/domains/$maindomain/dns/custom_records/$id" "" "DELETE" "application/json")" + response="$(echo "$response" | _normalizeJson)" + _debug response "$response" + + if [ "$response" = '{"result":null,"metadata":null}' ]; then + return 0 + else + return 1 + fi +} From da7b1fb014ceb1791bff30f65967c3aa1af491e4 Mon Sep 17 00:00:00 2001 From: der-berni Date: Thu, 9 Apr 2020 12:17:08 +0200 Subject: [PATCH 17/29] cleanup according to styleguide / ShellCheck --- dnsapi/dns_one.sh | 87 ++++++++++++++++++++++++----------------------- 1 file changed, 45 insertions(+), 42 deletions(-) diff --git a/dnsapi/dns_one.sh b/dnsapi/dns_one.sh index 4cc159d..96ef596 100644 --- a/dnsapi/dns_one.sh +++ b/dnsapi/dns_one.sh @@ -6,7 +6,10 @@ # Created: 2019-02-17 # Fixed by: @der-berni # Modified: 2020-04-07 -# +# +# Use ONECOM_KeepCnameProxy to keep the CNAME DNS record +# export ONECOM_KeepCnameProxy="1" +# # export ONECOM_User="username" # export ONECOM_Password="password" # @@ -29,41 +32,41 @@ dns_one_add() { _err "root domain not found" return 1 fi - + subdomain="${_sub_domain}" maindomain=${_domain} - + useProxy=0 if [ "${_sub_domain}" = "_acme-challenge" ]; then subdomain="proxy${_sub_domain}" useProxy=1 fi - + _debug subdomain "$subdomain" _debug maindomain "$maindomain" - + if [ $useProxy -eq 1 ]; then #Check if the CNAME exists _dns_one_getrecord "CNAME" "$_sub_domain" "$subdomain.$maindomain" if [ -z "$id" ]; then _info "$(__red "Add CNAME Proxy record: '$(__green "\"$_sub_domain\" => \"$subdomain.$maindomain\"")'")" _dns_one_addrecord "CNAME" "$_sub_domain" "$subdomain.$maindomain" - + _info "Not valid yet, let's wait 1 hour to take effect." _sleep 3600 fi fi - + #Check if the TXT exists _dns_one_getrecord "TXT" "$subdomain" "$txtvalue" - if [ ! -z "$id" ]; then + if [ -n "$id" ]; then _info "$(__green "Txt record with the same value found. Skip adding.")" return 0 fi - + _dns_one_addrecord "TXT" "$subdomain" "$txtvalue" if [ -z "$id" ]; then - _err "Add CNAME record error." + _err "Add TXT record error." return 1 else _info "$(__green "Added, OK ($id)")" @@ -88,43 +91,42 @@ dns_one_rm() { subdomain="${_sub_domain}" maindomain=${_domain} - + useProxy=0 if [ "${_sub_domain}" = "_acme-challenge" ]; then subdomain="proxy${_sub_domain}" useProxy=1 fi - + _debug subdomain "$subdomain" _debug maindomain "$maindomain" if [ $useProxy -eq 1 ]; then - if [ "$ONECOM_KeepCnameProxy" = "1" ]; then - _info "$(__red "Keeping CNAME Proxy record: '$(__green "\"$_sub_domain\" => \"$subdomain.$maindomain\"")'")" - else - #Check if the CNAME exists - _dns_one_getrecord "CNAME" "$_sub_domain" "$subdomain.$maindomain" - if [ ! -z "$id" ]; then - _info "$(__red "Removing CNAME Proxy record: '$(__green "\"$_sub_domain\" => \"$subdomain.$maindomain\"")'")" - _dns_one_delrecord "$id" - fi + if [ "$ONECOM_KeepCnameProxy" = "1" ]; then + _info "$(__red "Keeping CNAME Proxy record: '$(__green "\"$_sub_domain\" => \"$subdomain.$maindomain\"")'")" + else + #Check if the CNAME exists + _dns_one_getrecord "CNAME" "$_sub_domain" "$subdomain.$maindomain" + if [ -n "$id" ]; then + _info "$(__red "Removing CNAME Proxy record: '$(__green "\"$_sub_domain\" => \"$subdomain.$maindomain\"")'")" + _dns_one_delrecord "$id" fi + fi fi - + #Check if the TXT exists _dns_one_getrecord "TXT" "$subdomain" "$txtvalue" if [ -z "$id" ]; then _err "Txt record not found." return 1 fi - + # delete entry - if _dns_one_delrecord "$id"; then - _info "$(__green Removed, OK)" - return 0 + _info "$(__green Removed, OK)" + return 0 else - _err "Removing txt record error." - return 1 + _err "Removing txt record error." + return 1 fi } @@ -162,6 +164,7 @@ _dns_one_login() { # get credentials ONECOM_KeepCnameProxy="${ONECOM_KeepCnameProxy:-$(_readaccountconf_mutable ONECOM_KeepCnameProxy)}" + ONECOM_KeepCnameProxy="${ONECOM_KeepCnameProxy:-0}" ONECOM_User="${ONECOM_User:-$(_readaccountconf_mutable ONECOM_User)}" ONECOM_Password="${ONECOM_Password:-$(_readaccountconf_mutable ONECOM_Password)}" if [ -z "$ONECOM_User" ] || [ -z "$ONECOM_Password" ]; then @@ -173,6 +176,7 @@ _dns_one_login() { fi #save the api key and email to the account conf file. + _saveaccountconf_mutable ONECOM_KeepCnameProxy "$ONECOM_KeepCnameProxy" _saveaccountconf_mutable ONECOM_User "$ONECOM_User" _saveaccountconf_mutable ONECOM_Password "$ONECOM_Password" @@ -207,17 +211,17 @@ _dns_one_getrecord() { name="$2" value="$3" if [ -z "$type" ]; then - type="TXT" + type="TXT" fi if [ -z "$name" ]; then - _err "Record name is empty." - return 1 + _err "Record name is empty." + return 1 fi - + response="$(_get "https://www.one.com/admin/api/domains/$maindomain/dns/custom_records")" response="$(echo "$response" | _normalizeJson)" _debug response "$response" - + if [ -z "${value}" ]; then id=$(printf -- "%s" "$response" | sed -n "s/.*{\"type\":\"dns_custom_records\",\"id\":\"\([^\"]*\)\",\"attributes\":{\"prefix\":\"${name}\",\"type\":\"${type}\",\"content\":\"[^\"]*\",\"priority\":0,\"ttl\":600}.*/\1/p") response=$(printf -- "%s" "$response" | sed -n "s/.*{\"type\":\"dns_custom_records\",\"id\":\"[^\"]*\",\"attributes\":{\"prefix\":\"${name}\",\"type\":\"${type}\",\"content\":\"\([^\"]*\)\",\"priority\":0,\"ttl\":600}.*/\1/p") @@ -225,7 +229,6 @@ _dns_one_getrecord() { id=$(printf -- "%s" "$response" | sed -n "s/.*{\"type\":\"dns_custom_records\",\"id\":\"\([^\"]*\)\",\"attributes\":{\"prefix\":\"${name}\",\"type\":\"${type}\",\"content\":\"${value}\",\"priority\":0,\"ttl\":600}.*/\1/p") fi if [ -z "$id" ]; then - _err "Record not found." return 1 fi return 0 @@ -236,13 +239,13 @@ _dns_one_addrecord() { name="$2" value="$3" if [ -z "$type" ]; then - type="TXT" + type="TXT" fi if [ -z "$name" ]; then - _err "Record name is empty." - return 1 + _err "Record name is empty." + return 1 fi - + postdata="{\"type\":\"dns_custom_records\",\"attributes\":{\"priority\":0,\"ttl\":600,\"type\":\"${type}\",\"prefix\":\"${name}\",\"content\":\"${value}\"}}" _debug postdata "$postdata" response="$(_post "$postdata" "https://www.one.com/admin/api/domains/$maindomain/dns/custom_records" "" "POST" "application/json")" @@ -261,16 +264,16 @@ _dns_one_addrecord() { _dns_one_delrecord() { id="$1" if [ -z "$id" ]; then - return 1 + return 1 fi - + response="$(_post "" "https://www.one.com/admin/api/domains/$maindomain/dns/custom_records/$id" "" "DELETE" "application/json")" response="$(echo "$response" | _normalizeJson)" _debug response "$response" if [ "$response" = '{"result":null,"metadata":null}' ]; then - return 0 + return 0 else - return 1 + return 1 fi } From 4dfdfa0b7db773cc46d12c1ff107ee50fef2fb4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=96=B5=E5=96=B5=E5=96=B5=E5=96=B5=E5=9B=9B?= Date: Sun, 12 Apr 2020 12:28:07 +0800 Subject: [PATCH 18/29] Fix typo on line 27 --- dnsapi/dns_he.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_he.sh b/dnsapi/dns_he.sh index caa4d2c..5829e00 100755 --- a/dnsapi/dns_he.sh +++ b/dnsapi/dns_he.sh @@ -24,7 +24,7 @@ dns_he_add() { if [ -z "$HE_Username" ] || [ -z "$HE_Password" ]; then HE_Username= HE_Password= - _err "No auth details provided. Please set user credentials using the \$HE_Username and \$HE_Password envoronment variables." + _err "No auth details provided. Please set user credentials using the \$HE_Username and \$HE_Password environment variables." return 1 fi _saveaccountconf_mutable HE_Username "$HE_Username" From 2c971a25985049c928597da57e636b5487d19abf Mon Sep 17 00:00:00 2001 From: mod242 <40213799+mod242@users.noreply.github.com> Date: Thu, 16 Apr 2020 20:03:34 +0200 Subject: [PATCH 19/29] Filter out blank lines Response from the provider has changed so that there are blank lines at the end, which leads to the result can not be parsed correctly --- dnsapi/dns_ddnss.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_ddnss.sh b/dnsapi/dns_ddnss.sh index 53781d0..ecc4f17 100644 --- a/dnsapi/dns_ddnss.sh +++ b/dnsapi/dns_ddnss.sh @@ -119,7 +119,7 @@ _ddnss_rest() { # DDNSS uses GET to update domain info if [ "$method" = "GET" ]; then - response="$(_get "$url" | sed 's/<[a-zA-Z\/][^>]*>//g' | _tail_n 1)" + response="$(_get "$url" | sed 's/<[a-zA-Z\/][^>]*>//g' | tr -s "\n" | _tail_n 1)" else _err "Unsupported method" return 1 From 2febdfc3636614a226e00fe27a419baa8ffe9d6c Mon Sep 17 00:00:00 2001 From: Simon Wydooghe Date: Fri, 17 Apr 2020 15:53:15 +0200 Subject: [PATCH 20/29] Fix: allow removal of email address as contact It seems the current code doesn't allow for removing the email address from the contact field. This fixes that. This only removes the email address if an explicit empty email address is specified on the command line or in the account.conf file. If it is left unspecified on the command line it still just uses whatever was configured in the account.conf. --- acme.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/acme.sh b/acme.sh index f672710..763d8a1 100755 --- a/acme.sh +++ b/acme.sh @@ -3512,6 +3512,8 @@ updateaccount() { if [ "$ACME_VERSION" = "2" ]; then if [ "$ACCOUNT_EMAIL" ]; then updjson='{"contact": ["mailto:'$ACCOUNT_EMAIL'"]}' + else + updjson='{"contact": []}' fi else # ACMEv1: Updates happen the same way a registration is done. From d842ccb287588de346c40bcc26c531e0b183e4bb Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 18 Apr 2020 18:51:08 +0800 Subject: [PATCH 21/29] fix format error --- dnsapi/dns_arvan.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_arvan.sh b/dnsapi/dns_arvan.sh index 341c8c1..edeb56c 100644 --- a/dnsapi/dns_arvan.sh +++ b/dnsapi/dns_arvan.sh @@ -8,7 +8,7 @@ ARVAN_API_URL="https://napi.arvancloud.com/cdn/4.0/domains" #Report Bugs here: https://github.com/Neilpang/acme.sh # ######## Public functions ##################### - + #Usage: dns_arvan_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" dns_arvan_add() { fulldomain=$1 @@ -22,7 +22,7 @@ dns_arvan_add() { _err "You can get yours from here https://npanel.arvancloud.com/profile/api-keys" return 1 fi - #save the api token to the account conf file. + #save the api token to the account conf file. _saveaccountconf_mutable Arvan_Token "$Arvan_Token" _debug "First detect the root zone" @@ -150,7 +150,7 @@ _arvan_rest() { export _H1="Authorization: $token_trimmed" if [ "$mtd" = "DELETE" ]; then - # DELETE Request shouldn't have Content-Type + #DELETE Request shouldn't have Content-Type _debug data "$data" response="$(_post "$data" "$ARVAN_API_URL/$ep" "" "$mtd")" elif [ "$mtd" = "POST" ]; then @@ -160,4 +160,4 @@ _arvan_rest() { else response="$(_get "$ARVAN_API_URL/$ep$data")" fi -} \ No newline at end of file +} From ed7a945261c96d8b721a53c10fd9eaf00ce54182 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 18 Apr 2020 18:59:33 +0800 Subject: [PATCH 22/29] add comment message. --- .github/auto-comment.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/auto-comment.yml b/.github/auto-comment.yml index 1e7b389..1c3b746 100644 --- a/.github/auto-comment.yml +++ b/.github/auto-comment.yml @@ -10,8 +10,14 @@ issuesOpened: > please also provide the log with `--debug 2`. + 同时请提供调试输出 `--debug 2` + see: https://github.com/acmesh-official/acme.sh/wiki/How-to-debug-acme.sh - + + Without `--debug 2` log, your issue will NEVER get replied. + + 没有调试输出, 你的 issue 不会得到任何解答. + pullRequestOpened: > First, never send a PR to `master` branch, it will never be accepted. Please send to the `dev` branch instead. From 1564742b76d2e3d20d7c55411d008aaa4cbef402 Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 18 Apr 2020 19:38:38 +0800 Subject: [PATCH 23/29] add comments --- .github/auto-comment.yml | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/.github/auto-comment.yml b/.github/auto-comment.yml index 1c3b746..520b3ce 100644 --- a/.github/auto-comment.yml +++ b/.github/auto-comment.yml @@ -4,7 +4,7 @@ issuesOpened: > 如果有 bug, 请先更新到最新版试试: - ```sh + ``` acme.sh --upgrade ``` @@ -17,10 +17,10 @@ issuesOpened: > Without `--debug 2` log, your issue will NEVER get replied. 没有调试输出, 你的 issue 不会得到任何解答. - + pullRequestOpened: > - First, never send a PR to `master` branch, it will never be accepted. Please send to the `dev` branch instead. + First, NEVER send a PR to `master` branch, it will NEVER be accepted. Please send to the `dev` branch instead. If this is a PR to support new DNS API or new notification API, please read this guide first: https://github.com/acmesh-official/acme.sh/wiki/DNS-API-Dev-Guide @@ -29,6 +29,12 @@ pullRequestOpened: > Then add your usage here: https://github.com/acmesh-official/acme.sh/wiki/dnsapi - + + Or some other wiki pages: + + https://github.com/acmesh-official/acme.sh/wiki/deployhooks + + https://github.com/acmesh-official/acme.sh/wiki/notify + From 1041c9f9fc50eb6aa29de5b882dc7244e9f4024d Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 18 Apr 2020 20:03:48 +0800 Subject: [PATCH 24/29] support revoke reason. https://github.com/acmesh-official/acme.sh/issues/2856 --- acme.sh | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/acme.sh b/acme.sh index 763d8a1..18c8e00 100755 --- a/acme.sh +++ b/acme.sh @@ -138,6 +138,8 @@ _NOTIFY_WIKI="https://github.com/acmesh-official/acme.sh/wiki/notify" _SUDO_WIKI="https://github.com/acmesh-official/acme.sh/wiki/sudo" +_REVOKE_WIKI="https://github.com/acmesh-official/acme.sh/wiki/revokecert" + _DNS_MANUAL_ERR="The dns manual mode can not renew automatically, you must issue it again manually. You'd better use the other modes instead." _DNS_MANUAL_WARN="It seems that you are using dns manual mode. please take care: $_DNS_MANUAL_ERR" @@ -5456,6 +5458,7 @@ uninstallcronjob() { } +#domain isECC revokeReason revoke() { Le_Domain="$1" if [ -z "$Le_Domain" ]; then @@ -5464,7 +5467,10 @@ revoke() { fi _isEcc="$2" - + _reason="$3" + if [ -z "$_reason" ]; then + _reason="0" + fi _initpath "$Le_Domain" "$_isEcc" if [ ! -f "$DOMAIN_CONF" ]; then _err "$Le_Domain is not a issued domain, skip." @@ -5486,7 +5492,7 @@ revoke() { _initAPI if [ "$ACME_VERSION" = "2" ]; then - data="{\"certificate\": \"$cert\"}" + data="{\"certificate\": \"$cert\",\"reason\":$_reason}" else data="{\"resource\": \"revoke-cert\", \"certificate\": \"$cert\"}" fi @@ -6295,6 +6301,7 @@ Parameters: 0: Bulk mode. Send all the domain's notifications in one message(mail). 1: Cert mode. Send a message for every single cert. --notify-hook [hookname] Set the notify hook + --revoke-reason [0-10] The reason for '--revoke' command. See: $_REVOKE_WIKI " } @@ -6470,6 +6477,7 @@ _process() { _notify_hook="" _notify_level="" _notify_mode="" + _revoke_reason="" while [ ${#} -gt 0 ]; do case "${1}" in @@ -6941,6 +6949,14 @@ _process() { fi _notify_mode="$_nmode" shift + ;; + --revoke-reason) + _revoke_reason="$2" + if _startswith "$_revoke_reason" "-"; then + _err "'$_revoke_reason' is not a integer for '$1'" + return 1 + fi + shift ;; *) _err "Unknown parameter : $1" @@ -7029,7 +7045,7 @@ _process() { renewAll "$_stopRenewOnError" ;; revoke) - revoke "$_domain" "$_ecc" + revoke "$_domain" "$_ecc" "$_revoke_reason" ;; remove) remove "$_domain" "$_ecc" From a995333081876b7f9a06e2c824ed1127d784ebaf Mon Sep 17 00:00:00 2001 From: neil Date: Sat, 18 Apr 2020 22:34:32 +0800 Subject: [PATCH 25/29] fix format --- acme.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acme.sh b/acme.sh index 18c8e00..57f4590 100755 --- a/acme.sh +++ b/acme.sh @@ -6950,7 +6950,7 @@ _process() { _notify_mode="$_nmode" shift ;; - --revoke-reason) + --revoke-reason) _revoke_reason="$2" if _startswith "$_revoke_reason" "-"; then _err "'$_revoke_reason' is not a integer for '$1'" From 08cc7587ab8042caf4ddab9e4d6910a62797c2ea Mon Sep 17 00:00:00 2001 From: Wolfram Webers Date: Sat, 18 Apr 2020 18:11:24 +0200 Subject: [PATCH 26/29] - Adding fix for latest "os-bind" plugin --- dnsapi/dns_opnsense.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsapi/dns_opnsense.sh b/dnsapi/dns_opnsense.sh index b2a3746..ec7d227 100755 --- a/dnsapi/dns_opnsense.sh +++ b/dnsapi/dns_opnsense.sh @@ -150,7 +150,7 @@ _get_root() { return 1 fi _debug h "$h" - id=$(echo "$_domain_response" | _egrep_o "\"[^\"]*\":{\"enabled\":\"1\",\"type\":{\"master\":{\"value\":\"master\",\"selected\":1},\"slave\":{\"value\":\"slave\",\"selected\":0}},\"masterip\":\"[^\"]*\",\"domainname\":\"${h}\"" | cut -d ':' -f 1 | cut -d '"' -f 2) + id=$(echo "$_domain_response" | _egrep_o "\"[^\"]*\":{\"enabled\":\"1\",\"type\":{\"master\":{\"value\":\"master\",\"selected\":1},\"slave\":{\"value\":\"slave\",\"selected\":0}},\"masterip\":\"[^\"]*\",\"allownotifyslave\":{\"\":{[^}]*}},\"domainname\":\"${h}\"" | cut -d ':' -f 1 | cut -d '"' -f 2) if [ -n "$id" ]; then _debug id "$id" From 3bad815982841302a9d55d073fff9d69937cf1ab Mon Sep 17 00:00:00 2001 From: Nils Sandmann Date: Sat, 18 Apr 2020 18:52:08 +0200 Subject: [PATCH 27/29] Better error handling on login, return correct return code --- dnsapi/dns_inwx.sh | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/dnsapi/dns_inwx.sh b/dnsapi/dns_inwx.sh index 7c08d72..4995ca1 100755 --- a/dnsapi/dns_inwx.sh +++ b/dnsapi/dns_inwx.sh @@ -148,17 +148,21 @@ _inwx_login() { - ' $INWX_User $INWX_Password) + ' "$INWX_User" "$INWX_Password") response="$(_post "$xml_content" "$INWX_Api" "" "POST")" _H1=$(printf "Cookie: %s" "$(grep "domrobot=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o 'domrobot=[^;]*;' | tr -d ';')") export _H1 + if ! _contains "$response" "code1000"; then + _err "INWX API: Authentication error (username/password correct?)" + return 1 + fi + #https://github.com/inwx/php-client/blob/master/INWX/Domrobot.php#L71 - if _contains "$response" "code1000" \ - && _contains "$response" "tfaGOOGLE-AUTH"; then + if _contains "$response" "tfaGOOGLE-AUTH"; then if [ -z "$INWX_Shared_Secret" ]; then - _err "Mobile TAN detected." + _err "INWX API: Mobile TAN detected." _err "Please define a shared secret." return 1 fi @@ -191,6 +195,11 @@ _inwx_login() { ' "$tan") response="$(_post "$xml_content" "$INWX_Api" "" "POST")" + + if ! _contains "$response" "code1000"; then + _err "INWX API: Mobile TAN not correct." + return 1 + fi fi } From 5d00edc896dfbd09d961ea6f76843cf7c18b6083 Mon Sep 17 00:00:00 2001 From: Nils Sandmann Date: Sat, 18 Apr 2020 18:54:43 +0200 Subject: [PATCH 28/29] Fix multiple domains with 2FA, reuse session cookie --- dnsapi/dns_inwx.sh | 50 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_inwx.sh b/dnsapi/dns_inwx.sh index 4995ca1..50b4b10 100755 --- a/dnsapi/dns_inwx.sh +++ b/dnsapi/dns_inwx.sh @@ -34,6 +34,10 @@ dns_inwx_add() { _saveaccountconf_mutable INWX_Password "$INWX_Password" _saveaccountconf_mutable INWX_Shared_Secret "$INWX_Shared_Secret" + if ! _inwx_login; then + return 1 + fi + _debug "First detect the root zone" if ! _get_root "$fulldomain"; then _err "invalid domain" @@ -64,6 +68,10 @@ dns_inwx_rm() { return 1 fi + if ! _inwx_login; then + return 1 + fi + _debug "First detect the root zone" if ! _get_root "$fulldomain"; then _err "invalid domain" @@ -123,8 +131,42 @@ dns_inwx_rm() { #################### Private functions below ################################## +_inwx_check_cookie() { + INWX_Cookie="${INWX_Cookie:-$(_readaccountconf_mutable INWX_Cookie)}" + if [ -z "$INWX_Cookie" ]; then + _debug "No cached cookie found" + return 1 + fi + _H1="$INWX_Cookie" + export _H1 + + xml_content=$(printf ' + + account.info + ') + + response="$(_post "$xml_content" "$INWX_Api" "" "POST")" + + if _contains "$response" "code1000"; then + _debug "Cached cookie still valid" + return 0 + fi + + _debug "Cached cookie no longer valid" + _H1="" + export _H1 + INWX_Cookie="" + _saveaccountconf_mutable INWX_Cookie "$INWX_Cookie" + return 1 +} + _inwx_login() { + if _inwx_check_cookie; then + _debug "Already logged in" + return 0 + fi + xml_content=$(printf ' account.login @@ -151,8 +193,12 @@ _inwx_login() { ' "$INWX_User" "$INWX_Password") response="$(_post "$xml_content" "$INWX_Api" "" "POST")" - _H1=$(printf "Cookie: %s" "$(grep "domrobot=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o 'domrobot=[^;]*;' | tr -d ';')") + + INWX_Cookie=$(printf "Cookie: %s" "$(grep "domrobot=" "$HTTP_HEADER" | grep "^Set-Cookie:" | _tail_n 1 | _egrep_o 'domrobot=[^;]*;' | tr -d ';')") + _H1=$INWX_Cookie export _H1 + export INWX_Cookie + _saveaccountconf_mutable INWX_Cookie "$INWX_Cookie" if ! _contains "$response" "code1000"; then _err "INWX API: Authentication error (username/password correct?)" @@ -212,8 +258,6 @@ _get_root() { i=2 p=1 - _inwx_login - xml_content=' nameserver.list From 9bad11ec79e23cf617b9b07c91537a3f7962c4d4 Mon Sep 17 00:00:00 2001 From: wurzelpanzer <32928046+wurzelpanzer@users.noreply.github.com> Date: Mon, 20 Apr 2020 08:49:08 +0200 Subject: [PATCH 29/29] easyDNS API out of beta Added new links to API docs and API access signup --- dnsapi/dns_easydns.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dnsapi/dns_easydns.sh b/dnsapi/dns_easydns.sh index ca8faab..f466f1e 100644 --- a/dnsapi/dns_easydns.sh +++ b/dnsapi/dns_easydns.sh @@ -4,8 +4,7 @@ # # easyDNS REST API for acme.sh by Neilpang based on dns_cf.sh # -# Please note: # API is currently beta and subject to constant change -# http://sandbox.rest.easydns.net:3000/ +# API Documentation: https://sandbox.rest.easydns.net:3001/ # # Author: wurzelpanzer [wurzelpanzer@maximolider.net] # Report Bugs here: https://github.com/acmesh-official/acme.sh/issues/2647 @@ -25,7 +24,7 @@ dns_easydns_add() { EASYDNS_Key="${EASYDNS_Key:-$(_readaccountconf_mutable EASYDNS_Key)}" if [ -z "$EASYDNS_Token" ] || [ -z "$EASYDNS_Key" ]; then - _err "You didn't specify an easydns.net token or api key. Please sign up at http://docs.sandbox.rest.easydns.net/beta_signup.php" + _err "You didn't specify an easydns.net token or api key. Signup at https://cp.easydns.com/manage/security/api/signup.php" return 1 else _saveaccountconf_mutable EASYDNS_Token "$EASYDNS_Token"