mirror of
https://github.com/plantroon/acme.sh.git
synced 2024-12-22 13:11:41 +00:00
commit
15c68c9594
12
README.md
12
README.md
@ -20,18 +20,18 @@
|
|||||||
|
|
||||||
- An ACME protocol client written purely in Shell (Unix shell) language.
|
- An ACME protocol client written purely in Shell (Unix shell) language.
|
||||||
- Full ACME protocol implementation.
|
- Full ACME protocol implementation.
|
||||||
- Support ACME v1 and ACME v2
|
- Support ECDSA certs
|
||||||
- Support ACME v2 wildcard certs
|
- Support SAN and wildcard certs
|
||||||
- Simple, powerful and very easy to use. You only need 3 minutes to learn it.
|
- Simple, powerful and very easy to use. You only need 3 minutes to learn it.
|
||||||
- Bash, dash and sh compatible.
|
- Bash, dash and sh compatible.
|
||||||
- Purely written in Shell with no dependencies on python or the official Let's Encrypt client.
|
- Purely written in Shell with no dependencies on python.
|
||||||
- Just one script to issue, renew and install your certificates automatically.
|
- Just one script to issue, renew and install your certificates automatically.
|
||||||
- DOES NOT require `root/sudoer` access.
|
- DOES NOT require `root/sudoer` access.
|
||||||
- Docker friendly
|
- Docker ready
|
||||||
- IPv6 support
|
- IPv6 ready
|
||||||
- Cron job notifications for renewal or error etc.
|
- Cron job notifications for renewal or error etc.
|
||||||
|
|
||||||
It's probably the `easiest & smartest` shell script to automatically issue & renew the free certificates from Let's Encrypt.
|
It's probably the `easiest & smartest` shell script to automatically issue & renew the free certificates.
|
||||||
|
|
||||||
Wiki: https://github.com/acmesh-official/acme.sh/wiki
|
Wiki: https://github.com/acmesh-official/acme.sh/wiki
|
||||||
|
|
||||||
|
107
acme.sh
107
acme.sh
@ -1768,7 +1768,7 @@ _inithttp() {
|
|||||||
if [ -z "$ACME_HTTP_NO_REDIRECTS" ]; then
|
if [ -z "$ACME_HTTP_NO_REDIRECTS" ]; then
|
||||||
_ACME_CURL="$_ACME_CURL -L "
|
_ACME_CURL="$_ACME_CURL -L "
|
||||||
fi
|
fi
|
||||||
if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then
|
if [ "$DEBUG" ] && [ "$DEBUG" -ge 2 ]; then
|
||||||
_CURL_DUMP="$(_mktemp)"
|
_CURL_DUMP="$(_mktemp)"
|
||||||
_ACME_CURL="$_ACME_CURL --trace-ascii $_CURL_DUMP "
|
_ACME_CURL="$_ACME_CURL --trace-ascii $_CURL_DUMP "
|
||||||
fi
|
fi
|
||||||
@ -1808,6 +1808,8 @@ _inithttp() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_HTTP_MAX_RETRY=8
|
||||||
|
|
||||||
# body url [needbase64] [POST|PUT|DELETE] [ContentType]
|
# body url [needbase64] [POST|PUT|DELETE] [ContentType]
|
||||||
_post() {
|
_post() {
|
||||||
body="$1"
|
body="$1"
|
||||||
@ -1815,6 +1817,33 @@ _post() {
|
|||||||
needbase64="$3"
|
needbase64="$3"
|
||||||
httpmethod="$4"
|
httpmethod="$4"
|
||||||
_postContentType="$5"
|
_postContentType="$5"
|
||||||
|
_sleep_retry_sec=1
|
||||||
|
_http_retry_times=0
|
||||||
|
_hcode=0
|
||||||
|
while [ "${_http_retry_times}" -le "$_HTTP_MAX_RETRY" ]; do
|
||||||
|
[ "$_http_retry_times" = "$_HTTP_MAX_RETRY" ]
|
||||||
|
_lastHCode="$?"
|
||||||
|
_debug "Retrying post"
|
||||||
|
_post_impl "$body" "$_post_url" "$needbase64" "$httpmethod" "$_postContentType" "$_lastHCode"
|
||||||
|
_hcode="$?"
|
||||||
|
_debug _hcode "$_hcode"
|
||||||
|
if [ "$_hcode" = "0" ]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
_http_retry_times=$(_math $_http_retry_times + 1)
|
||||||
|
_sleep $_sleep_retry_sec
|
||||||
|
done
|
||||||
|
return $_hcode
|
||||||
|
}
|
||||||
|
|
||||||
|
# body url [needbase64] [POST|PUT|DELETE] [ContentType] [displayError]
|
||||||
|
_post_impl() {
|
||||||
|
body="$1"
|
||||||
|
_post_url="$2"
|
||||||
|
needbase64="$3"
|
||||||
|
httpmethod="$4"
|
||||||
|
_postContentType="$5"
|
||||||
|
displayError="$6"
|
||||||
|
|
||||||
if [ -z "$httpmethod" ]; then
|
if [ -z "$httpmethod" ]; then
|
||||||
httpmethod="POST"
|
httpmethod="POST"
|
||||||
@ -1866,7 +1895,9 @@ _post() {
|
|||||||
fi
|
fi
|
||||||
_ret="$?"
|
_ret="$?"
|
||||||
if [ "$_ret" != "0" ]; then
|
if [ "$_ret" != "0" ]; then
|
||||||
_err "Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: $_ret"
|
if [ -z "$displayError" ] || [ "$displayError" = "0" ]; then
|
||||||
|
_err "Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: $_ret"
|
||||||
|
fi
|
||||||
if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then
|
if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then
|
||||||
_err "Here is the curl dump log:"
|
_err "Here is the curl dump log:"
|
||||||
_err "$(cat "$_CURL_DUMP")"
|
_err "$(cat "$_CURL_DUMP")"
|
||||||
@ -1922,7 +1953,9 @@ _post() {
|
|||||||
_debug "wget returns 8, the server returns a 'Bad request' response, lets process the response later."
|
_debug "wget returns 8, the server returns a 'Bad request' response, lets process the response later."
|
||||||
fi
|
fi
|
||||||
if [ "$_ret" != "0" ]; then
|
if [ "$_ret" != "0" ]; then
|
||||||
_err "Please refer to https://www.gnu.org/software/wget/manual/html_node/Exit-Status.html for error code: $_ret"
|
if [ -z "$displayError" ] || [ "$displayError" = "0" ]; then
|
||||||
|
_err "Please refer to https://www.gnu.org/software/wget/manual/html_node/Exit-Status.html for error code: $_ret"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
_sed_i "s/^ *//g" "$HTTP_HEADER"
|
_sed_i "s/^ *//g" "$HTTP_HEADER"
|
||||||
else
|
else
|
||||||
@ -1936,13 +1969,38 @@ _post() {
|
|||||||
|
|
||||||
# url getheader timeout
|
# url getheader timeout
|
||||||
_get() {
|
_get() {
|
||||||
|
url="$1"
|
||||||
|
onlyheader="$2"
|
||||||
|
t="$3"
|
||||||
|
_sleep_retry_sec=1
|
||||||
|
_http_retry_times=0
|
||||||
|
_hcode=0
|
||||||
|
while [ "${_http_retry_times}" -le "$_HTTP_MAX_RETRY" ]; do
|
||||||
|
[ "$_http_retry_times" = "$_HTTP_MAX_RETRY" ]
|
||||||
|
_lastHCode="$?"
|
||||||
|
_debug "Retrying GET"
|
||||||
|
_get_impl "$url" "$onlyheader" "$t" "$_lastHCode"
|
||||||
|
_hcode="$?"
|
||||||
|
_debug _hcode "$_hcode"
|
||||||
|
if [ "$_hcode" = "0" ]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
_http_retry_times=$(_math $_http_retry_times + 1)
|
||||||
|
_sleep $_sleep_retry_sec
|
||||||
|
done
|
||||||
|
return $_hcode
|
||||||
|
}
|
||||||
|
|
||||||
|
# url getheader timeout displayError
|
||||||
|
_get_impl() {
|
||||||
_debug GET
|
_debug GET
|
||||||
url="$1"
|
url="$1"
|
||||||
onlyheader="$2"
|
onlyheader="$2"
|
||||||
t="$3"
|
t="$3"
|
||||||
|
displayError="$4"
|
||||||
_debug url "$url"
|
_debug url "$url"
|
||||||
_debug "timeout=$t"
|
_debug "timeout=$t"
|
||||||
|
_debug "displayError" "$displayError"
|
||||||
_inithttp
|
_inithttp
|
||||||
|
|
||||||
if [ "$_ACME_CURL" ] && [ "${ACME_USE_WGET:-0}" = "0" ]; then
|
if [ "$_ACME_CURL" ] && [ "${ACME_USE_WGET:-0}" = "0" ]; then
|
||||||
@ -1961,7 +2019,9 @@ _get() {
|
|||||||
fi
|
fi
|
||||||
ret=$?
|
ret=$?
|
||||||
if [ "$ret" != "0" ]; then
|
if [ "$ret" != "0" ]; then
|
||||||
_err "Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: $ret"
|
if [ -z "$displayError" ] || [ "$displayError" = "0" ]; then
|
||||||
|
_err "Please refer to https://curl.haxx.se/libcurl/c/libcurl-errors.html for error code: $ret"
|
||||||
|
fi
|
||||||
if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then
|
if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then
|
||||||
_err "Here is the curl dump log:"
|
_err "Here is the curl dump log:"
|
||||||
_err "$(cat "$_CURL_DUMP")"
|
_err "$(cat "$_CURL_DUMP")"
|
||||||
@ -1987,7 +2047,9 @@ _get() {
|
|||||||
_debug "wget returns 8, the server returns a 'Bad request' response, lets process the response later."
|
_debug "wget returns 8, the server returns a 'Bad request' response, lets process the response later."
|
||||||
fi
|
fi
|
||||||
if [ "$ret" != "0" ]; then
|
if [ "$ret" != "0" ]; then
|
||||||
_err "Please refer to https://www.gnu.org/software/wget/manual/html_node/Exit-Status.html for error code: $ret"
|
if [ -z "$displayError" ] || [ "$displayError" = "0" ]; then
|
||||||
|
_err "Please refer to https://www.gnu.org/software/wget/manual/html_node/Exit-Status.html for error code: $ret"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
ret=$?
|
ret=$?
|
||||||
@ -3925,7 +3987,7 @@ _ns_lookup_ali() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_ns_is_available_dp() {
|
_ns_is_available_dp() {
|
||||||
if _get "https://dns.alidns.com" "" 1 >/dev/null 2>&1; then
|
if _get "https://doh.pub" "" 1 >/dev/null 2>&1; then
|
||||||
return 0
|
return 0
|
||||||
else
|
else
|
||||||
return 1
|
return 1
|
||||||
@ -4712,26 +4774,13 @@ $_authorizations_map"
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
_debug "sleep 2 secs to verify"
|
|
||||||
sleep 2
|
|
||||||
_debug "checking"
|
|
||||||
|
|
||||||
_send_signed_request "$uri"
|
|
||||||
|
|
||||||
if [ "$?" != "0" ]; then
|
|
||||||
_err "$d:Verify error:$response"
|
|
||||||
_clearupwebbroot "$_currentRoot" "$removelevel" "$token"
|
|
||||||
_clearup
|
|
||||||
_on_issue_err "$_post_hook" "$vlist"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
_debug2 original "$response"
|
_debug2 original "$response"
|
||||||
|
|
||||||
response="$(echo "$response" | _normalizeJson)"
|
response="$(echo "$response" | _normalizeJson)"
|
||||||
_debug2 response "$response"
|
_debug2 response "$response"
|
||||||
|
|
||||||
status=$(echo "$response" | _egrep_o '"status":"[^"]*' | cut -d : -f 2 | tr -d '"')
|
status=$(echo "$response" | _egrep_o '"status":"[^"]*' | cut -d : -f 2 | tr -d '"')
|
||||||
|
_debug2 status "$status"
|
||||||
if _contains "$status" "invalid"; then
|
if _contains "$status" "invalid"; then
|
||||||
error="$(echo "$response" | _egrep_o '"error":\{[^\}]*')"
|
error="$(echo "$response" | _egrep_o '"error":\{[^\}]*')"
|
||||||
_debug2 error "$error"
|
_debug2 error "$error"
|
||||||
@ -4763,9 +4812,9 @@ $_authorizations_map"
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$status" = "pending" ]; then
|
if [ "$status" = "pending" ]; then
|
||||||
_info "Pending"
|
_info "Pending, The CA is processing your order, please just wait. ($waittimes/$MAX_RETRY_TIMES)"
|
||||||
elif [ "$status" = "processing" ]; then
|
elif [ "$status" = "processing" ]; then
|
||||||
_info "Processing"
|
_info "Processing, The CA is processing your order, please just wait. ($waittimes/$MAX_RETRY_TIMES)"
|
||||||
else
|
else
|
||||||
_err "$d:Verify error:$response"
|
_err "$d:Verify error:$response"
|
||||||
_clearupwebbroot "$_currentRoot" "$removelevel" "$token"
|
_clearupwebbroot "$_currentRoot" "$removelevel" "$token"
|
||||||
@ -4773,7 +4822,19 @@ $_authorizations_map"
|
|||||||
_on_issue_err "$_post_hook" "$vlist"
|
_on_issue_err "$_post_hook" "$vlist"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
_debug "sleep 2 secs to verify again"
|
||||||
|
sleep 2
|
||||||
|
_debug "checking"
|
||||||
|
|
||||||
|
_send_signed_request "$uri"
|
||||||
|
|
||||||
|
if [ "$?" != "0" ]; then
|
||||||
|
_err "$d:Verify error:$response"
|
||||||
|
_clearupwebbroot "$_currentRoot" "$removelevel" "$token"
|
||||||
|
_clearup
|
||||||
|
_on_issue_err "$_post_hook" "$vlist"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
done
|
done
|
||||||
|
@ -261,7 +261,9 @@ _get_root() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! _contains "$response" "This service does not exist" >/dev/null && ! _contains "$response" "NOT_GRANTED_CALL" >/dev/null; then
|
if ! _contains "$response" "This service does not exist" >/dev/null &&
|
||||||
|
! _contains "$response" "This call has not been granted" >/dev/null &&
|
||||||
|
! _contains "$response" "NOT_GRANTED_CALL" >/dev/null; then
|
||||||
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
|
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
|
||||||
_domain="$h"
|
_domain="$h"
|
||||||
return 0
|
return 0
|
||||||
|
@ -37,11 +37,19 @@ sendgrid_send() {
|
|||||||
fi
|
fi
|
||||||
_saveaccountconf_mutable SENDGRID_FROM "$SENDGRID_FROM"
|
_saveaccountconf_mutable SENDGRID_FROM "$SENDGRID_FROM"
|
||||||
|
|
||||||
|
SENDGRID_FROM_NAME="${SENDGRID_FROM_NAME:-$(_readaccountconf_mutable SENDGRID_FROM_NAME)}"
|
||||||
|
_saveaccountconf_mutable SENDGRID_FROM_NAME "$SENDGRID_FROM_NAME"
|
||||||
|
|
||||||
export _H1="Authorization: Bearer $SENDGRID_API_KEY"
|
export _H1="Authorization: Bearer $SENDGRID_API_KEY"
|
||||||
export _H2="Content-Type: application/json"
|
export _H2="Content-Type: application/json"
|
||||||
|
|
||||||
_content="$(echo "$_content" | _json_encode)"
|
_content="$(echo "$_content" | _json_encode)"
|
||||||
_data="{\"personalizations\": [{\"to\": [{\"email\": \"$SENDGRID_TO\"}]}],\"from\": {\"email\": \"$SENDGRID_FROM\"},\"subject\": \"$_subject\",\"content\": [{\"type\": \"text/plain\", \"value\": \"$_content\"}]}"
|
|
||||||
|
if [ -z "$SENDGRID_FROM_NAME" ]; then
|
||||||
|
_data="{\"personalizations\": [{\"to\": [{\"email\": \"$SENDGRID_TO\"}]}],\"from\": {\"email\": \"$SENDGRID_FROM\"},\"subject\": \"$_subject\",\"content\": [{\"type\": \"text/plain\", \"value\": \"$_content\"}]}"
|
||||||
|
else
|
||||||
|
_data="{\"personalizations\": [{\"to\": [{\"email\": \"$SENDGRID_TO\"}]}],\"from\": {\"email\": \"$SENDGRID_FROM\", \"name\": \"$SENDGRID_FROM_NAME\"},\"subject\": \"$_subject\",\"content\": [{\"type\": \"text/plain\", \"value\": \"$_content\"}]}"
|
||||||
|
fi
|
||||||
response="$(_post "$_data" "https://api.sendgrid.com/v3/mail/send")"
|
response="$(_post "$_data" "https://api.sendgrid.com/v3/mail/send")"
|
||||||
|
|
||||||
if [ "$?" = "0" ] && [ -z "$response" ]; then
|
if [ "$?" = "0" ] && [ -z "$response" ]; then
|
||||||
|
Loading…
Reference in New Issue
Block a user