acmesh-official / acme.sh

A pure Unix shell script implementing ACME client protocol
https://acme.sh
GNU General Public License v3.0
39.3k stars 4.97k forks source link

Report bug to Slack notify #2271

Open honzahommer opened 5 years ago

honzahommer commented 5 years ago

This is the place to report bugs in the Slack notify.

If you experience a bug, please report it in this issue.

Thanks!

anatanna commented 5 years ago

Hello,

Wiki to notify says that when installing --notify-level 1, the notification will come only in case of errors. However, it comes with every cron task, even if the certificates do not require updating (Skipped certs section of report).

account.conf:

SAVED_SLACK_WEBHOOK_URL='https://hooks.slack.com/services/.................a'
SAVED_SLACK_CHANNEL='#letsencrypt'
SAVED_SLACK_USERNAME='cert_net'
NOTIFY_LEVEL='1'
NOTIFY_HOOK='slack'

report in slack channel:

cert_net APP [01:42]
*Renew Skipped*
Error certs:

Success certs:

Skipped certs:
   anstalldacctest2......net
   anstalldviolet1......net
   ...

How can i set notify to generate full report (error/success/skipped) only if error occurred? Should i set some parameter to cron task?

Thank you.

Neilpang commented 5 years ago

@anatanna please upgrade to the latest version. it's fixed.

acme.sh  --upgrade

acem.sh --cron
anatanna commented 5 years ago

@Neilpang Thank you for your great acme.sh! That worked!

mreiden commented 5 years ago

This probably isn't just a bug with slack notifications, but rather a bug with single quotes in account.conf in general.

I set up slack notifications using export SLACK_USERNAME="Let's Encrypt" which worked and I got the "Hello, this is notification from acme.sh: If you receive this message, your notification works." test confirmation.

This ends up breaking the installation due to the single quote and causes the following error on future runs: unexpected EOF while looking for matching `'' do to SAVED_SLACK_USERNAME='Let's Encrypt' being saved in account.conf.

I changed account.conf to use double quotes SAVED_SLACK_USERNAME="Let's Encrypt" and this worked one time, but ends up being rewritten using single quotes after the next run.

I know the simple answer is to remove the single quote, but this should be rejected when the test notification is sent or not cause future runs to fail by encoding the single quote into a compatible format.

honzahommer commented 5 years ago

@mreiden There is possibility to save SLACK_USERNAME value as base64 encoded string.

diff notify/slack.sh
@@ -27,7 +27,7 @@ slack_send() {

   SLACK_USERNAME="${SLACK_USERNAME:-$(_readaccountconf_mutable SLACK_USERNAME)}"
   if [ -n "$SLACK_USERNAME" ]; then
-    _saveaccountconf_mutable SLACK_USERNAME "$SLACK_USERNAME"
+    _saveaccountconf_mutable SLACK_USERNAME "$SLACK_USERNAME" 1
   fi

   export _H1="Content-Type: application/json"

- or without changing the source -

SLACK_USERNAME="$(printf "__ACME_BASE64__START_%s__ACME_BASE64__END_" $(echo "Let's Encrypt" | tr -d '\r\n' | openssl base64 -A))" SAVED_SLACK_WEBHOOK_URL="..." acme.sh  --set-notify  --notify-hook slack

// cc @Neilpang

mreiden commented 5 years ago

@honzahommer I ended up trying that same code change (adding a 1 to base64 encode the username) myself after reviewing the code, but that ended up sending the notification with no username (i.e. no icon and no "Let's Encrypt ".

Creating a basic script with a few copied functions outputs the saved username correctly, but slack does NOT show the username if it is base64 encoded. However, it does if you edit the config file and use double quotes like SAVED_SLACK_USERNAME="Let's Encrypt".

I'm not sure what the difference is between the double-quoted version and the base64 decoded version, but only the double-quoted version works for me.


B64CONF_END="__ACME_BASE64__END_"

ACCOUNT_CONF_PATH="./test.conf"

_startswith() {
  _str="$1"
  _sub="$2"
  echo "$_str" | grep "^$_sub" >/dev/null 2>&1
}

_endswith() {
  _str="$1"
  _sub="$2"
  echo "$_str" | grep -- "$_sub\$" >/dev/null 2>&1
}

#key
_readaccountconf() {
  _read_conf "$ACCOUNT_CONF_PATH" "$1"
}

#key
_readaccountconf_mutable() {
  _rac_key="$1"
  _readaccountconf "SAVED_$_rac_key"
}

#_read_conf file  key
_read_conf() {
  _r_c_f="$1"
  _sdkey="$2"
  if [ -f "$_r_c_f" ]; then
    _sdv="$(
      eval "$(grep "^$_sdkey *=" "$_r_c_f")"
      eval "printf \"%s\" \"\$$_sdkey\""
    )"
    if _startswith "$_sdv" "${B64CONF_START}" && _endswith "$_sdv" "${B64CONF_END}"; then
      _sdv="$(echo "$_sdv" | sed "s/${B64CONF_START}//" | sed "s/${B64CONF_END}//" | _dbase64)"
    fi
    printf "%s" "$_sdv"
  else
    _debug "config file is empty, can not read $_sdkey"
  fi
}

#Usage: multiline
_base64() {
  [ "" ] #urgly
  if [ "$1" ]; then
    _debug3 "base64 multiline:'$1'"
    ${ACME_OPENSSL_BIN:-openssl} base64 -e
  else
    _debug3 "base64 single line."
    ${ACME_OPENSSL_BIN:-openssl} base64 -e | tr -d '\r\n'
  fi
}

#Usage: multiline
_dbase64() {
  if [ "$1" ]; then
    ${ACME_OPENSSL_BIN:-openssl} base64 -d -A
  else
    ${ACME_OPENSSL_BIN:-openssl} base64 -d
  fi
}

SLACK_USERNAME="${SLACK_USERNAME:-$(_readaccountconf_mutable SLACK_USERNAME)}"
echo $SLACK_USERNAME```