#!/usr/bin/env sh
-VER=2.8.7
+VER=2.8.9
PROJECT_NAME="acme.sh"
DEFAULT_STAGING_CA=$CA_LETSENCRYPT_V2_TEST
CA_NAMES="
-Letsencrypt.org,letsencrypt
-Letsencrypt.org_test,letsencrypt_test,letsencrypttest
+LetsEncrypt.org,letsencrypt
+LetsEncrypt.org_test,letsencrypt_test,letsencrypttest
BuyPass.com,buypass
BuyPass.com_test,buypass_test,buypasstest
ZeroSSL.com,zerossl
DEFAULT_OPENSSL_BIN="openssl"
-_OLD_CA_HOST="https://acme-v01.api.letsencrypt.org"
-_OLD_STAGE_CA_HOST="https://acme-staging.api.letsencrypt.org"
-
VTYPE_HTTP="http-01"
VTYPE_DNS="dns-01"
VTYPE_ALPN="tls-alpn-01"
_DNS_MANUAL_WIKI="https://github.com/acmesh-official/acme.sh/wiki/dns-manual-mode"
+_DNS_API_WIKI="https://github.com/acmesh-official/acme.sh/wiki/dnsapi"
+
_NOTIFY_WIKI="https://github.com/acmesh-official/acme.sh/wiki/notify"
_SUDO_WIKI="https://github.com/acmesh-official/acme.sh/wiki/sudo"
_SERVER_WIKI="https://github.com/acmesh-official/acme.sh/wiki/Server"
+_PREFERRED_CHAIN_WIKI="https://github.com/acmesh-official/acme.sh/wiki/Preferred-Chain"
+
+_DNSCHECK_WIKI="https://github.com/acmesh-official/acme.sh/wiki/dnscheck"
+
_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"
_h_char_2_dec() {
_ch=$1
case "${_ch}" in
- a | A)
- printf "10"
- ;;
- b | B)
- printf "11"
- ;;
- c | C)
- printf "12"
- ;;
- d | D)
- printf "13"
- ;;
- e | E)
- printf "14"
- ;;
- f | F)
- printf "15"
- ;;
- *)
- printf "%s" "$_ch"
- ;;
+ a | A)
+ printf "10"
+ ;;
+ b | B)
+ printf "11"
+ ;;
+ c | C)
+ printf "12"
+ ;;
+ d | D)
+ printf "13"
+ ;;
+ e | E)
+ printf "14"
+ ;;
+ f | F)
+ printf "15"
+ ;;
+ *)
+ printf "%s" "$_ch"
+ ;;
esac
}
for _hex_code in $_hex_str; do
#upper case
case "${_hex_code}" in
- "41")
- printf "%s" "A"
- ;;
- "42")
- printf "%s" "B"
- ;;
- "43")
- printf "%s" "C"
- ;;
- "44")
- printf "%s" "D"
- ;;
- "45")
- printf "%s" "E"
- ;;
- "46")
- printf "%s" "F"
- ;;
- "47")
- printf "%s" "G"
- ;;
- "48")
- printf "%s" "H"
- ;;
- "49")
- printf "%s" "I"
- ;;
- "4a")
- printf "%s" "J"
- ;;
- "4b")
- printf "%s" "K"
- ;;
- "4c")
- printf "%s" "L"
- ;;
- "4d")
- printf "%s" "M"
- ;;
- "4e")
- printf "%s" "N"
- ;;
- "4f")
- printf "%s" "O"
- ;;
- "50")
- printf "%s" "P"
- ;;
- "51")
- printf "%s" "Q"
- ;;
- "52")
- printf "%s" "R"
- ;;
- "53")
- printf "%s" "S"
- ;;
- "54")
- printf "%s" "T"
- ;;
- "55")
- printf "%s" "U"
- ;;
- "56")
- printf "%s" "V"
- ;;
- "57")
- printf "%s" "W"
- ;;
- "58")
- printf "%s" "X"
- ;;
- "59")
- printf "%s" "Y"
- ;;
- "5a")
- printf "%s" "Z"
- ;;
+ "41")
+ printf "%s" "A"
+ ;;
+ "42")
+ printf "%s" "B"
+ ;;
+ "43")
+ printf "%s" "C"
+ ;;
+ "44")
+ printf "%s" "D"
+ ;;
+ "45")
+ printf "%s" "E"
+ ;;
+ "46")
+ printf "%s" "F"
+ ;;
+ "47")
+ printf "%s" "G"
+ ;;
+ "48")
+ printf "%s" "H"
+ ;;
+ "49")
+ printf "%s" "I"
+ ;;
+ "4a")
+ printf "%s" "J"
+ ;;
+ "4b")
+ printf "%s" "K"
+ ;;
+ "4c")
+ printf "%s" "L"
+ ;;
+ "4d")
+ printf "%s" "M"
+ ;;
+ "4e")
+ printf "%s" "N"
+ ;;
+ "4f")
+ printf "%s" "O"
+ ;;
+ "50")
+ printf "%s" "P"
+ ;;
+ "51")
+ printf "%s" "Q"
+ ;;
+ "52")
+ printf "%s" "R"
+ ;;
+ "53")
+ printf "%s" "S"
+ ;;
+ "54")
+ printf "%s" "T"
+ ;;
+ "55")
+ printf "%s" "U"
+ ;;
+ "56")
+ printf "%s" "V"
+ ;;
+ "57")
+ printf "%s" "W"
+ ;;
+ "58")
+ printf "%s" "X"
+ ;;
+ "59")
+ printf "%s" "Y"
+ ;;
+ "5a")
+ printf "%s" "Z"
+ ;;
#lower case
- "61")
- printf "%s" "a"
- ;;
- "62")
- printf "%s" "b"
- ;;
- "63")
- printf "%s" "c"
- ;;
- "64")
- printf "%s" "d"
- ;;
- "65")
- printf "%s" "e"
- ;;
- "66")
- printf "%s" "f"
- ;;
- "67")
- printf "%s" "g"
- ;;
- "68")
- printf "%s" "h"
- ;;
- "69")
- printf "%s" "i"
- ;;
- "6a")
- printf "%s" "j"
- ;;
- "6b")
- printf "%s" "k"
- ;;
- "6c")
- printf "%s" "l"
- ;;
- "6d")
- printf "%s" "m"
- ;;
- "6e")
- printf "%s" "n"
- ;;
- "6f")
- printf "%s" "o"
- ;;
- "70")
- printf "%s" "p"
- ;;
- "71")
- printf "%s" "q"
- ;;
- "72")
- printf "%s" "r"
- ;;
- "73")
- printf "%s" "s"
- ;;
- "74")
- printf "%s" "t"
- ;;
- "75")
- printf "%s" "u"
- ;;
- "76")
- printf "%s" "v"
- ;;
- "77")
- printf "%s" "w"
- ;;
- "78")
- printf "%s" "x"
- ;;
- "79")
- printf "%s" "y"
- ;;
- "7a")
- printf "%s" "z"
- ;;
+ "61")
+ printf "%s" "a"
+ ;;
+ "62")
+ printf "%s" "b"
+ ;;
+ "63")
+ printf "%s" "c"
+ ;;
+ "64")
+ printf "%s" "d"
+ ;;
+ "65")
+ printf "%s" "e"
+ ;;
+ "66")
+ printf "%s" "f"
+ ;;
+ "67")
+ printf "%s" "g"
+ ;;
+ "68")
+ printf "%s" "h"
+ ;;
+ "69")
+ printf "%s" "i"
+ ;;
+ "6a")
+ printf "%s" "j"
+ ;;
+ "6b")
+ printf "%s" "k"
+ ;;
+ "6c")
+ printf "%s" "l"
+ ;;
+ "6d")
+ printf "%s" "m"
+ ;;
+ "6e")
+ printf "%s" "n"
+ ;;
+ "6f")
+ printf "%s" "o"
+ ;;
+ "70")
+ printf "%s" "p"
+ ;;
+ "71")
+ printf "%s" "q"
+ ;;
+ "72")
+ printf "%s" "r"
+ ;;
+ "73")
+ printf "%s" "s"
+ ;;
+ "74")
+ printf "%s" "t"
+ ;;
+ "75")
+ printf "%s" "u"
+ ;;
+ "76")
+ printf "%s" "v"
+ ;;
+ "77")
+ printf "%s" "w"
+ ;;
+ "78")
+ printf "%s" "x"
+ ;;
+ "79")
+ printf "%s" "y"
+ ;;
+ "7a")
+ printf "%s" "z"
+ ;;
#numbers
- "30")
- printf "%s" "0"
- ;;
- "31")
- printf "%s" "1"
- ;;
- "32")
- printf "%s" "2"
- ;;
- "33")
- printf "%s" "3"
- ;;
- "34")
- printf "%s" "4"
- ;;
- "35")
- printf "%s" "5"
- ;;
- "36")
- printf "%s" "6"
- ;;
- "37")
- printf "%s" "7"
- ;;
- "38")
- printf "%s" "8"
- ;;
- "39")
- printf "%s" "9"
- ;;
- "2d")
- printf "%s" "-"
- ;;
- "5f")
- printf "%s" "_"
- ;;
- "2e")
- printf "%s" "."
- ;;
- "7e")
- printf "%s" "~"
- ;;
- #other hex
- *)
- printf '%%%s' "$_hex_code"
- ;;
+ "30")
+ printf "%s" "0"
+ ;;
+ "31")
+ printf "%s" "1"
+ ;;
+ "32")
+ printf "%s" "2"
+ ;;
+ "33")
+ printf "%s" "3"
+ ;;
+ "34")
+ printf "%s" "4"
+ ;;
+ "35")
+ printf "%s" "5"
+ ;;
+ "36")
+ printf "%s" "6"
+ ;;
+ "37")
+ printf "%s" "7"
+ ;;
+ "38")
+ printf "%s" "8"
+ ;;
+ "39")
+ printf "%s" "9"
+ ;;
+ "2d")
+ printf "%s" "-"
+ ;;
+ "5f")
+ printf "%s" "_"
+ ;;
+ "2e")
+ printf "%s" "."
+ ;;
+ "7e")
+ printf "%s" "~"
+ ;;
+ #other hex
+ *)
+ printf '%%%s' "$_hex_code"
+ ;;
esac
done
}
_checkcert() {
_cf="$1"
if [ "$DEBUG" ]; then
- openssl x509 -noout -text -in "$_cf"
+ ${ACME_OPENSSL_BIN:-openssl} x509 -noout -text -in "$_cf"
else
- openssl x509 -noout -text -in "$_cf" >/dev/null 2>&1
+ ${ACME_OPENSSL_BIN:-openssl} x509 -noout -text -in "$_cf" >/dev/null 2>&1
fi
}
return 1
fi
- [ "$_length" != "1024" ] \
- && [ "$_length" != "2048" ] \
- && [ "$_length" != "3072" ] \
- && [ "$_length" != "4096" ] \
- && [ "$_length" != "8192" ]
+ [ "$_length" != "1024" ] &&
+ [ "$_length" != "2048" ] &&
+ [ "$_length" != "3072" ] &&
+ [ "$_length" != "4096" ] &&
+ [ "$_length" != "8192" ]
}
# _createkey 2048|ec-256 file
domain="$1"
pfxPassword="$2"
if [ -z "$domain" ]; then
- _usage "Usage: $PROJECT_ENTRY --toPkcs -d domain [--password pfx-password]"
+ _usage "Usage: $PROJECT_ENTRY --to-pkcs12 --domain <domain.tld> [--password <password>] [--ecc]"
return 1
fi
domain="$1"
if [ -z "$domain" ]; then
- _usage "Usage: $PROJECT_ENTRY --toPkcs8 -d domain [--ecc]"
+ _usage "Usage: $PROJECT_ENTRY --to-pkcs8 --domain <domain.tld> [--ecc]"
return 1
fi
createAccountKey() {
_info "Creating account key"
if [ -z "$1" ]; then
- _usage "Usage: $PROJECT_ENTRY --createAccountKey --accountkeylength 2048"
+ _usage "Usage: $PROJECT_ENTRY --create-account-key [--accountkeylength <bits>]"
return
fi
createDomainKey() {
_info "Creating domain key"
if [ -z "$1" ]; then
- _usage "Usage: $PROJECT_ENTRY --createDomainKey -d domain.com [ --keylength 2048 ]"
+ _usage "Usage: $PROJECT_ENTRY --create-domain-key --domain <domain.tld> [--keylength <bits>]"
return
fi
_initpath "$domain" "$_cdl"
- if [ ! -f "$CERT_KEY_PATH" ] || [ ! -s "$CERT_KEY_PATH" ] || ([ "$FORCE" ] && ! [ "$IS_RENEW" ]) || [ "$Le_ForceNewDomainKey" = "1" ]; then
+ if [ ! -f "$CERT_KEY_PATH" ] || [ ! -s "$CERT_KEY_PATH" ] || ([ "$FORCE" ] && ! [ "$_ACME_IS_RENEW" ]) || [ "$Le_ForceNewDomainKey" = "1" ]; then
if _createkey "$_cdl" "$CERT_KEY_PATH"; then
_savedomainconf Le_Keylength "$_cdl"
_info "The domain key is here: $(__green $CERT_KEY_PATH)"
return 1
fi
else
- if [ "$IS_RENEW" ]; then
+ if [ "$_ACME_IS_RENEW" ]; then
_info "Domain key exists, skip"
return 0
else
createCSR() {
_info "Creating csr"
if [ -z "$1" ]; then
- _usage "Usage: $PROJECT_ENTRY --createCSR -d domain1.com [-d domain2.com -d domain3.com ... ]"
+ _usage "Usage: $PROJECT_ENTRY --create-csr --domain <domain.tld> [--domain <domain2.tld> ...]"
return
fi
_initpath "$domain" "$_isEcc"
- if [ -f "$CSR_PATH" ] && [ "$IS_RENEW" ] && [ -z "$FORCE" ]; then
+ if [ -f "$CSR_PATH" ] && [ "$_ACME_IS_RENEW" ] && [ -z "$FORCE" ]; then
_info "CSR exists, skip"
return
fi
crv_oid="$(${ACME_OPENSSL_BIN:-openssl} ec -in "$keyfile" -noout -text 2>/dev/null | grep "^ASN1 OID:" | cut -d ":" -f 2 | tr -d " \r\n")"
_debug3 crv_oid "$crv_oid"
case "${crv_oid}" in
- "prime256v1")
- crv="P-256"
- __ECC_KEY_LEN=256
- ;;
- "secp384r1")
- crv="P-384"
- __ECC_KEY_LEN=384
- ;;
- "secp521r1")
- crv="P-521"
- __ECC_KEY_LEN=512
- ;;
- *)
- _err "ECC oid : $crv_oid"
- return 1
- ;;
+ "prime256v1")
+ crv="P-256"
+ __ECC_KEY_LEN=256
+ ;;
+ "secp384r1")
+ crv="P-384"
+ __ECC_KEY_LEN=384
+ ;;
+ "secp521r1")
+ crv="P-521"
+ __ECC_KEY_LEN=512
+ ;;
+ *)
+ _err "ECC oid : $crv_oid"
+ return 1
+ ;;
esac
_debug3 crv "$crv"
fi
_err "Can not create temp file."
}
+#clear all the https envs to cause _inithttp() to run next time.
+_resethttp() {
+ __HTTP_INITIALIZED=""
+ _ACME_CURL=""
+ _ACME_WGET=""
+ ACME_HTTP_NO_REDIRECTS=""
+}
+
_inithttp() {
if [ -z "$HTTP_HEADER" ] || ! touch "$HTTP_HEADER"; then
fi
if [ -z "$_ACME_CURL" ] && _exists "curl"; then
- _ACME_CURL="curl -L --silent --dump-header $HTTP_HEADER "
+ _ACME_CURL="curl --silent --dump-header $HTTP_HEADER "
+ if [ -z "$ACME_HTTP_NO_REDIRECTS" ]; then
+ _ACME_CURL="$_ACME_CURL -L "
+ fi
if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then
_CURL_DUMP="$(_mktemp)"
_ACME_CURL="$_ACME_CURL --trace-ascii $_CURL_DUMP "
if [ -z "$_ACME_WGET" ] && _exists "wget"; then
_ACME_WGET="wget -q"
+ if [ "$ACME_HTTP_NO_REDIRECTS" ]; then
+ _ACME_WGET="$_ACME_WGET --max-redirect 0 "
+ fi
if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then
_ACME_WGET="$_ACME_WGET -d "
fi
_debug2 original "$response"
if echo "$responseHeaders" | grep -i "Content-Type: *application/json" >/dev/null 2>&1; then
- response="$(echo "$response" | _normalizeJson)"
+ response="$(echo "$response" | _json_decode | _normalizeJson)"
fi
_debug2 response "$response"
_err "Can not init api."
return 1
fi
+ response=$(echo "$response" | _json_decode)
_debug2 "response" "$response"
ACME_KEY_CHANGE=$(echo "$response" | _egrep_o 'key-change" *: *"[^"]*"' | cut -d '"' -f 3)
. "$ACCOUNT_CONF_PATH"
fi
- if [ "$ACME_IN_CRON" ]; then
+ if [ "$_ACME_IN_CRON" ]; then
if [ ! "$_USER_PATH_EXPORTED" ]; then
_USER_PATH_EXPORTED=1
export PATH="$USER_PATH:$PATH"
CA_HOME="$DEFAULT_CA_HOME"
fi
- if [ "$ACME_VERSION" = "2" ]; then
- DEFAULT_CA="$CA_LETSENCRYPT_V2"
- DEFAULT_STAGING_CA="$CA_LETSENCRYPT_V2_TEST"
- fi
-
if [ -z "$ACME_DIRECTORY" ]; then
- default_acme_server=$(_readaccountconf "DEFAULT_ACME_SERVER")
- _debug default_acme_server "$default_acme_server"
- if [ "$default_acme_server" ]; then
- ACME_DIRECTORY="$default_acme_server"
+ if [ "$STAGE" ]; then
+ ACME_DIRECTORY="$DEFAULT_STAGING_CA"
+ _info "Using ACME_DIRECTORY: $ACME_DIRECTORY"
else
- if [ -z "$STAGE" ]; then
- ACME_DIRECTORY="$DEFAULT_CA"
+ default_acme_server=$(_readaccountconf "DEFAULT_ACME_SERVER")
+ _debug default_acme_server "$default_acme_server"
+ if [ "$default_acme_server" ]; then
+ ACME_DIRECTORY="$default_acme_server"
else
- ACME_DIRECTORY="$DEFAULT_STAGING_CA"
- _info "Using stage ACME_DIRECTORY: $ACME_DIRECTORY"
+ ACME_DIRECTORY="$DEFAULT_CA"
fi
fi
fi
if _restoreApache; then
_err "The apache config file is restored."
else
- _err "Sorry, The apache config file can not be restored, please report bug."
+ _err "Sorry, the apache config file can not be restored, please report bug."
fi
return 1
fi
)
fi
- if [ "$IS_RENEW" = "1" ] && _hasfield "$Le_Webroot" "$W_DNS"; then
+ if [ "$_ACME_IS_RENEW" = "1" ] && _hasfield "$Le_Webroot" "$W_DNS"; then
_err "$_DNS_MANUAL_ERR"
fi
fi
#run renew hook
- if [ "$IS_RENEW" ] && [ "$_chk_renew_hook" ]; then
+ if [ "$_ACME_IS_RENEW" ] && [ "$_chk_renew_hook" ]; then
_info "Run renew hook:'$_chk_renew_hook'"
if ! (
export CERT_PATH
_end_time="$(_math "$_end_time" + 1200)" #let's check no more than 20 minutes.
while [ "$(_time)" -le "$_end_time" ]; do
+ _info "You can use '--dnssleep' to disable public dns checks."
+ _info "See: $_DNSCHECK_WIKI"
_left=""
for entry in $dns_entries; do
d=$(_getfield "$entry" 1)
}
+#file
+_get_cert_issuers() {
+ _cfile="$1"
+ if _contains "$(${ACME_OPENSSL_BIN:-openssl} help crl2pkcs7 2>&1)" "Usage: crl2pkcs7" || _contains "$(${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 help 2>&1)" "unknown option help"; then
+ ${ACME_OPENSSL_BIN:-openssl} crl2pkcs7 -nocrl -certfile $_cfile | ${ACME_OPENSSL_BIN:-openssl} pkcs7 -print_certs -text -noout | grep 'Issuer:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2
+ else
+ ${ACME_OPENSSL_BIN:-openssl} x509 -in $_cfile -text -noout | grep 'Issuer:' | _egrep_o "CN *=[^,]*" | cut -d = -f 2
+ fi
+}
+
+#cert issuer
+_match_issuer() {
+ _cfile="$1"
+ _missuer="$2"
+ _fissuers="$(_get_cert_issuers $_cfile)"
+ _debug2 _fissuers "$_fissuers"
+ if _contains "$_fissuers" "$_missuer"; then
+ return 0
+ fi
+ _fissuers="$(echo "$_fissuers" | _lower_case)"
+ _missuer="$(echo "$_missuer" | _lower_case)"
+ _contains "$_fissuers" "$_missuer"
+}
+
#webroot, domain domainlist keylength
issue() {
if [ -z "$2" ]; then
- _usage "Usage: $PROJECT_ENTRY --issue -d a.com -w /path/to/webroot/a.com/ "
+ _usage "Usage: $PROJECT_ENTRY --issue --domain <domain.tld> --webroot <directory>"
return 1
fi
if [ -z "$1" ]; then
_renew_hook="${12}"
_local_addr="${13}"
_challenge_alias="${14}"
- #remove these later.
- if [ "$_web_roots" = "dns-cf" ]; then
- _web_roots="dns_cf"
- fi
- if [ "$_web_roots" = "dns-dp" ]; then
- _web_roots="dns_dp"
- fi
- if [ "$_web_roots" = "dns-cx" ]; then
- _web_roots="dns_cx"
- fi
+ _preferred_chain="${15}"
- if [ ! "$IS_RENEW" ]; then
+ if [ -z "$_ACME_IS_RENEW" ]; then
_initpath "$_main_domain" "$_key_length"
mkdir -p "$DOMAIN_PATH"
fi
else
_cleardomainconf "Le_ChallengeAlias"
fi
-
- if [ "$ACME_DIRECTORY" != "$DEFAULT_CA" ]; then
- Le_API="$ACME_DIRECTORY"
- _savedomainconf "Le_API" "$Le_API"
+ if [ "$_preferred_chain" ]; then
+ _savedomainconf "Le_Preferred_Chain" "$_preferred_chain" "base64"
else
- _cleardomainconf Le_API
+ _cleardomainconf "Le_Preferred_Chain"
fi
+
+ Le_API="$ACME_DIRECTORY"
+ _savedomainconf "Le_API" "$Le_API"
+
_info "Using CA: $ACME_DIRECTORY"
if [ "$_alt_domains" = "$NO_VALUE" ]; then
_alt_domains=""
der="$(_getfile "${CSR_PATH}" "${BEGIN_CSR}" "${END_CSR}" | tr -d "\r\n" | _url_replace)"
if [ "$ACME_VERSION" = "2" ]; then
- _info "Lets finalize the order, Le_OrderFinalize: $Le_OrderFinalize"
+ _info "Lets finalize the order."
+ _info "Le_OrderFinalize" "$Le_OrderFinalize"
if ! _send_signed_request "${Le_OrderFinalize}" "{\"csr\": \"$der\"}"; then
_err "Sign failed."
_on_issue_err "$_post_hook"
return 1
fi
if [ -z "$Le_LinkOrder" ]; then
- Le_LinkOrder="$(echo "$responseHeaders" | grep -i '^Location.*$' | _tail_n 1 | tr -d "\r\n" | cut -d ":" -f 2-)"
+ Le_LinkOrder="$(echo "$responseHeaders" | grep -i '^Location.*$' | _tail_n 1 | tr -d "\r\n \t" | cut -d ":" -f 2-)"
fi
_savedomainconf "Le_LinkOrder" "$Le_LinkOrder"
_on_issue_err "$_post_hook"
return 1
fi
- _info "Download cert, Le_LinkCert: $Le_LinkCert"
+ _info "Downloading cert."
+ _info "Le_LinkCert" "$Le_LinkCert"
if ! _send_signed_request "$Le_LinkCert"; then
_err "Sign failed, can not download cert:$Le_LinkCert."
_err "$response"
fi
echo "$response" >"$CERT_PATH"
-
- if [ "$(grep -- "$BEGIN_CERT" "$CERT_PATH" | wc -l)" -gt "1" ]; then
- _debug "Found cert chain"
- cat "$CERT_PATH" >"$CERT_FULLCHAIN_PATH"
- _end_n="$(grep -n -- "$END_CERT" "$CERT_FULLCHAIN_PATH" | _head_n 1 | cut -d : -f 1)"
- _debug _end_n "$_end_n"
- sed -n "1,${_end_n}p" "$CERT_FULLCHAIN_PATH" >"$CERT_PATH"
- _end_n="$(_math $_end_n + 1)"
- sed -n "${_end_n},9999p" "$CERT_FULLCHAIN_PATH" >"$CA_CERT_PATH"
+ _split_cert_chain "$CERT_PATH" "$CERT_FULLCHAIN_PATH" "$CA_CERT_PATH"
+
+ if [ "$_preferred_chain" ] && [ -f "$CERT_FULLCHAIN_PATH" ]; then
+ if ! _match_issuer "$CERT_FULLCHAIN_PATH" "$_preferred_chain"; then
+ rels="$(echo "$responseHeaders" | tr -d ' <>' | grep -i "^link:" | grep -i 'rel="alternate"' | cut -d : -f 2- | cut -d ';' -f 1)"
+ _debug2 "rels" "$rels"
+ for rel in $rels; do
+ _info "Try rel: $rel"
+ if ! _send_signed_request "$rel"; then
+ _err "Sign failed, can not download cert:$rel"
+ _err "$response"
+ continue
+ fi
+ _relcert="$CERT_PATH.alt"
+ _relfullchain="$CERT_FULLCHAIN_PATH.alt"
+ _relca="$CA_CERT_PATH.alt"
+ echo "$response" >"$_relcert"
+ _split_cert_chain "$_relcert" "$_relfullchain" "$_relca"
+ if _match_issuer "$_relfullchain" "$_preferred_chain"; then
+ _info "Matched issuer in: $rel"
+ cat $_relcert >"$CERT_PATH"
+ cat $_relfullchain >"$CERT_FULLCHAIN_PATH"
+ cat $_relca >"$CA_CERT_PATH"
+ break
+ fi
+ done
+ fi
fi
-
else
if ! _send_signed_request "${ACME_NEW_ORDER}" "{\"resource\": \"$ACME_NEW_ORDER_RES\", \"csr\": \"$der\"}" "needbase64"; then
_err "Sign failed. $response"
_info "Your cert key is in $(__green " $CERT_KEY_PATH ")"
fi
- if [ ! "$USER_PATH" ] || [ ! "$ACME_IN_CRON" ]; then
+ if [ ! "$USER_PATH" ] || [ ! "$_ACME_IN_CRON" ]; then
USER_PATH="$PATH"
_saveaccountconf "USER_PATH" "$USER_PATH"
fi
fi
}
+#in_out_cert out_fullchain out_ca
+_split_cert_chain() {
+ _certf="$1"
+ _fullchainf="$2"
+ _caf="$3"
+ if [ "$(grep -- "$BEGIN_CERT" "$_certf" | wc -l)" -gt "1" ]; then
+ _debug "Found cert chain"
+ cat "$_certf" >"$_fullchainf"
+ _end_n="$(grep -n -- "$END_CERT" "$_fullchainf" | _head_n 1 | cut -d : -f 1)"
+ _debug _end_n "$_end_n"
+ sed -n "1,${_end_n}p" "$_fullchainf" >"$_certf"
+ _end_n="$(_math $_end_n + 1)"
+ sed -n "${_end_n},9999p" "$_fullchainf" >"$_caf"
+ fi
+}
+
#domain [isEcc]
renew() {
Le_Domain="$1"
if [ -z "$Le_Domain" ]; then
- _usage "Usage: $PROJECT_ENTRY --renew -d domain.com [--ecc]"
+ _usage "Usage: $PROJECT_ENTRY --renew --domain <domain.tld> [--ecc]"
return 1
fi
_info "$(__green "Renew: '$Le_Domain'")"
if [ ! -f "$DOMAIN_CONF" ]; then
- _info "'$Le_Domain' is not a issued domain, skip."
+ _info "'$Le_Domain' is not an issued domain, skip."
return $RENEW_SKIP
fi
fi
if [ "$Le_API" ]; then
- if [ "$_OLD_CA_HOST" = "$Le_API" ]; then
- export Le_API="$DEFAULT_CA"
- _savedomainconf Le_API "$Le_API"
- fi
- if [ "$_OLD_STAGE_CA_HOST" = "$Le_API" ]; then
- export Le_API="$DEFAULT_STAGING_CA"
- _savedomainconf Le_API "$Le_API"
- fi
export ACME_DIRECTORY="$Le_API"
#reload ca configs
ACCOUNT_KEY_PATH=""
return "$RENEW_SKIP"
fi
- if [ "$ACME_IN_CRON" = "1" ] && [ -z "$Le_CertCreateTime" ]; then
+ if [ "$_ACME_IN_CRON" = "1" ] && [ -z "$Le_CertCreateTime" ]; then
_info "Skip invalid cert for: $Le_Domain"
return $RENEW_SKIP
fi
- IS_RENEW="1"
+ _ACME_IS_RENEW="1"
Le_ReloadCmd="$(_readdomainconf Le_ReloadCmd)"
Le_PreHook="$(_readdomainconf Le_PreHook)"
Le_PostHook="$(_readdomainconf Le_PostHook)"
Le_RenewHook="$(_readdomainconf Le_RenewHook)"
- issue "$Le_Webroot" "$Le_Domain" "$Le_Alt" "$Le_Keylength" "$Le_RealCertPath" "$Le_RealKeyPath" "$Le_RealCACertPath" "$Le_ReloadCmd" "$Le_RealFullChainPath" "$Le_PreHook" "$Le_PostHook" "$Le_RenewHook" "$Le_LocalAddress" "$Le_ChallengeAlias"
+ Le_Preferred_Chain="$(_readdomainconf Le_Preferred_Chain)"
+ issue "$Le_Webroot" "$Le_Domain" "$Le_Alt" "$Le_Keylength" "$Le_RealCertPath" "$Le_RealKeyPath" "$Le_RealCACertPath" "$Le_ReloadCmd" "$Le_RealFullChainPath" "$Le_PreHook" "$Le_PostHook" "$Le_RenewHook" "$Le_LocalAddress" "$Le_ChallengeAlias" "$Le_Preferred_Chain"
res="$?"
if [ "$res" != "0" ]; then
return "$res"
res="$?"
fi
- IS_RENEW=""
+ _ACME_IS_RENEW=""
return "$res"
}
for di in "${CERT_HOME}"/*.*/; do
_debug di "$di"
if ! [ -d "$di" ]; then
- _debug "Not directory, skip: $di"
+ _debug "Not a directory, skip: $di"
continue
fi
d=$(basename "$di")
_error_level="$NOTIFY_LEVEL_RENEW"
_notify_code=0
fi
- if [ "$ACME_IN_CRON" ]; then
+ if [ "$_ACME_IN_CRON" ]; then
if [ $_set_level -ge $NOTIFY_LEVEL_RENEW ]; then
if [ "$NOTIFY_MODE" = "$NOTIFY_MODE_CERT" ]; then
_send_notify "Renew $d success" "Good, the cert is renewed." "$NOTIFY_HOOK" 0
_error_level="$NOTIFY_LEVEL_SKIP"
_notify_code=$RENEW_SKIP
fi
- if [ "$ACME_IN_CRON" ]; then
+ if [ "$_ACME_IN_CRON" ]; then
if [ $_set_level -ge $NOTIFY_LEVEL_SKIP ]; then
if [ "$NOTIFY_MODE" = "$NOTIFY_MODE_CERT" ]; then
_send_notify "Renew $d skipped" "Good, the cert is skipped." "$NOTIFY_HOOK" "$RENEW_SKIP"
_error_level="$NOTIFY_LEVEL_ERROR"
_notify_code=1
fi
- if [ "$ACME_IN_CRON" ]; then
+ if [ "$_ACME_IN_CRON" ]; then
if [ $_set_level -ge $NOTIFY_LEVEL_ERROR ]; then
if [ "$NOTIFY_MODE" = "$NOTIFY_MODE_CERT" ]; then
_send_notify "Renew $d error" "There is an error." "$NOTIFY_HOOK" 1
done
_debug _error_level "$_error_level"
_debug _set_level "$_set_level"
- if [ "$ACME_IN_CRON" ] && [ $_error_level -le $_set_level ]; then
+ if [ "$_ACME_IN_CRON" ] && [ $_error_level -le $_set_level ]; then
if [ -z "$NOTIFY_MODE" ] || [ "$NOTIFY_MODE" = "$NOTIFY_MODE_BULK" ]; then
_msg_subject="Renew"
if [ "$_error_msg" ]; then
_csrfile="$1"
_csrW="$2"
if [ -z "$_csrfile" ] || [ -z "$_csrW" ]; then
- _usage "Usage: $PROJECT_ENTRY --signcsr --csr mycsr.csr -w /path/to/webroot/a.com/ "
+ _usage "Usage: $PROJECT_ENTRY --sign-csr --csr <csr-file> --webroot <directory>"
return 1
fi
_csrfile="$1"
_csrd="$2"
if [ -z "$_csrfile" ] && [ -z "$_csrd" ]; then
- _usage "Usage: $PROJECT_ENTRY --showcsr --csr mycsr.csr"
+ _usage "Usage: $PROJECT_ENTRY --show-csr --csr <csr-file>"
return 1
fi
_info "KeyLength=$_csrkeylength"
}
+#listraw domain
list() {
_raw="$1"
+ _domain="$2"
_initpath
_sep="|"
if [ "$_raw" ]; then
- printf "%s\n" "Main_Domain${_sep}KeyLength${_sep}SAN_Domains${_sep}CA${_sep}Created${_sep}Renew"
+ if [ -z "$_domain" ]; then
+ printf "%s\n" "Main_Domain${_sep}KeyLength${_sep}SAN_Domains${_sep}CA${_sep}Created${_sep}Renew"
+ fi
for di in "${CERT_HOME}"/*.*/; do
d=$(basename "$di")
_debug d "$d"
if [ -f "$DOMAIN_CONF" ]; then
. "$DOMAIN_CONF"
_ca="$(_getCAShortName "$Le_API")"
- printf "%s\n" "$Le_Domain${_sep}\"$Le_Keylength\"${_sep}$Le_Alt${_sep}$_ca${_sep}$Le_CertCreateTimeStr${_sep}$Le_NextRenewTimeStr"
+ if [ -z "$_domain" ]; then
+ printf "%s\n" "$Le_Domain${_sep}\"$Le_Keylength\"${_sep}$Le_Alt${_sep}$_ca${_sep}$Le_CertCreateTimeStr${_sep}$Le_NextRenewTimeStr"
+ else
+ if [ "$_domain" = "$d" ]; then
+ cat "$DOMAIN_CONF"
+ fi
+ fi
fi
)
done
else
if _exists column; then
- list "raw" | column -t -s "$_sep"
+ list "raw" "$_domain" | column -t -s "$_sep"
else
- list "raw" | tr "$_sep" '\t'
+ list "raw" "$_domain" | tr "$_sep" '\t'
fi
fi
_hooks="$2"
_isEcc="$3"
if [ -z "$_hooks" ]; then
- _usage "Usage: $PROJECT_ENTRY --deploy -d domain.com --deploy-hook cpanel [--ecc] "
+ _usage "Usage: $PROJECT_ENTRY --deploy --domain <domain.tld> --deploy-hook <hookname> [--ecc] "
return 1
fi
installcert() {
_main_domain="$1"
if [ -z "$_main_domain" ]; then
- _usage "Usage: $PROJECT_ENTRY --installcert -d domain.com [--ecc] [--cert-file cert-file-path] [--key-file key-file-path] [--ca-file ca-cert-file-path] [ --reloadCmd reloadCmd] [--fullchain-file fullchain-path]"
+ _usage "Usage: $PROJECT_ENTRY --install-cert --domain <domain.tld> [--ecc] [--cert-file <file>] [--key-file <file>] [--ca-file <file>] [ --reloadcmd <command>] [--fullchain-file <file>]"
return 1
fi
if [ "$_real_cert" ]; then
_info "Installing cert to:$_real_cert"
- if [ -f "$_real_cert" ] && [ ! "$IS_RENEW" ]; then
+ if [ -f "$_real_cert" ] && [ ! "$_ACME_IS_RENEW" ]; then
cp "$_real_cert" "$_backup_path/cert.bak"
fi
cat "$CERT_PATH" >"$_real_cert" || return 1
echo "" >>"$_real_ca"
cat "$CA_CERT_PATH" >>"$_real_ca" || return 1
else
- if [ -f "$_real_ca" ] && [ ! "$IS_RENEW" ]; then
+ if [ -f "$_real_ca" ] && [ ! "$_ACME_IS_RENEW" ]; then
cp "$_real_ca" "$_backup_path/ca.bak"
fi
cat "$CA_CERT_PATH" >"$_real_ca" || return 1
if [ "$_real_key" ]; then
_info "Installing key to:$_real_key"
- if [ -f "$_real_key" ] && [ ! "$IS_RENEW" ]; then
+ if [ -f "$_real_key" ] && [ ! "$_ACME_IS_RENEW" ]; then
cp "$_real_key" "$_backup_path/key.bak"
fi
if [ -f "$_real_key" ]; then
if [ "$_real_fullchain" ]; then
_info "Installing full chain to:$_real_fullchain"
- if [ -f "$_real_fullchain" ] && [ ! "$IS_RENEW" ]; then
+ if [ -f "$_real_fullchain" ] && [ ! "$_ACME_IS_RENEW" ]; then
cp "$_real_fullchain" "$_backup_path/fullchain.bak"
fi
cat "$CERT_FULLCHAIN_PATH" >"$_real_fullchain" || return 1
revoke() {
Le_Domain="$1"
if [ -z "$Le_Domain" ]; then
- _usage "Usage: $PROJECT_ENTRY --revoke -d domain.com [--ecc]"
+ _usage "Usage: $PROJECT_ENTRY --revoke --domain <domain.tld> [--ecc]"
return 1
fi
remove() {
Le_Domain="$1"
if [ -z "$Le_Domain" ]; then
- _usage "Usage: $PROJECT_ENTRY --remove -d domain.com [--ecc]"
+ _usage "Usage: $PROJECT_ENTRY --remove --domain <domain.tld> [--ecc]"
return 1
fi
_URL_NAME="uri"
fi
- entries="$(echo "$response" | _egrep_o "[^{]*\"type\":\"[^\"]*\", *\"status\": *\"valid\", *\"$_URL_NAME\"[^}]*")"
+ entries="$(echo "$response" | tr '][' '==' | _egrep_o "challenges\": *=[^=]*=" | tr '}{' '\n' | grep "\"status\": *\"valid\"")"
if [ -z "$entries" ]; then
_info "No valid entries found."
if [ -z "$thumbprint" ]; then
_debug _vtype "$_vtype"
_info "Found $_vtype"
- uri="$(echo "$entry" | _egrep_o "\"$_URL_NAME\":\"[^\"]*" | cut -d : -f 2,3 | tr -d '"')"
+ uri="$(echo "$entry" | _egrep_o "\"$_URL_NAME\":\"[^\"]*\"" | tr -d '" ' | cut -d : -f 2-)"
_debug uri "$uri"
if [ "$_d_type" ] && [ "$_d_type" != "$_vtype" ]; then
_initAPI
_debug _d_domain_list "$_d_domain_list"
if [ -z "$(echo $_d_domain_list | cut -d , -f 1)" ]; then
- _usage "Usage: $PROJECT_ENTRY --deactivate -d domain.com [-d domain.com]"
+ _usage "Usage: $PROJECT_ENTRY --deactivate --domain <domain.tld> [--domain <domain2.tld> ...]"
return 1
fi
for _d_dm in $(echo "$_d_domain_list" | tr ',' ' '); do
}
-# nocron confighome noprofile
+# nocron confighome noprofile accountemail
install() {
if [ -z "$LE_WORKING_DIR" ]; then
_nocron="$1"
_c_home="$2"
_noprofile="$3"
+ _accountemail="$4"
+
if ! _initpath; then
_err "Install failed."
return 1
_debug "Skip install cron job"
fi
- if [ "$ACME_IN_CRON" != "1" ]; then
+ if [ "$_ACME_IN_CRON" != "1" ]; then
if ! _precheck "$_nocron"; then
_err "Pre-check failed, can not install."
return 1
_info "Installed to $LE_WORKING_DIR/$PROJECT_ENTRY"
- if [ "$ACME_IN_CRON" != "1" ] && [ -z "$_noprofile" ]; then
+ if [ "$_ACME_IN_CRON" != "1" ] && [ -z "$_noprofile" ]; then
_installalias "$_c_home"
fi
fi
fi
+ if [ "$_accountemail" ]; then
+ _saveaccountconf "ACCOUNT_EMAIL" "$_accountemail"
+ fi
+
_info OK
}
}
cron() {
- export ACME_IN_CRON=1
+ export _ACME_IN_CRON=1
_initpath
_info "$(__green "===Starting cron===")"
if [ "$AUTO_UPGRADE" = "1" ]; then
fi
renewAll
_ret="$?"
- ACME_IN_CRON=""
+ _ACME_IN_CRON=""
_info "$(__green "===End cron===")"
exit $_ret
}
_initpath
if [ -z "$_nhook$_nlevel$_nmode" ]; then
- _usage "Usage: $PROJECT_ENTRY --set-notify [--notify-hook mailgun] [--notify-level $NOTIFY_LEVEL_DEFAULT] [--notify-mode $NOTIFY_MODE_DEFAULT]"
+ _usage "Usage: $PROJECT_ENTRY --set-notify [--notify-hook <hookname>] [--notify-level <0|1|2|3>] [--notify-mode <0|1>]"
_usage "$_NOTIFY_WIKI"
return 1
fi
showhelp() {
_initpath
version
- echo "Usage: $PROJECT_ENTRY command ...[parameters]....
+ echo "Usage: $PROJECT_ENTRY <command> ... [parameters ...]
Commands:
- --help, -h Show this help message.
- --version, -v Show version info.
+ -h, --help Show this help message.
+ -v, --version Show version info.
--install Install $PROJECT_NAME to your system.
--uninstall Uninstall $PROJECT_NAME, and uninstall the cron job.
--upgrade Upgrade $PROJECT_NAME to the latest code from $PROJECT.
--issue Issue a cert.
- --signcsr Issue a cert from an existing csr.
--deploy Deploy the cert to your server.
- --install-cert Install the issued cert to apache/nginx or any other server.
- --renew, -r Renew a cert.
+ -i, --install-cert Install the issued cert to apache/nginx or any other server.
+ -r, --renew Renew a cert.
--renew-all Renew all the certs.
--revoke Revoke a cert.
--remove Remove the cert from list of certs known to $PROJECT_NAME.
--list List all the certs.
- --showcsr Show the content of a csr.
- --install-cronjob Install the cron job to renew certs, you don't need to call this. The 'install' command can automatically install the cron job.
- --uninstall-cronjob Uninstall the cron job. The 'uninstall' command can do this automatically.
- --cron Run cron job to renew all the certs.
- --toPkcs Export the certificate and key to a pfx file.
- --toPkcs8 Convert to pkcs8 format.
+ --to-pkcs12 Export the certificate and key to a pfx file.
+ --to-pkcs8 Convert to pkcs8 format.
+ --sign-csr Issue a cert from an existing csr.
+ --show-csr Show the content of a csr.
+ -ccr, --create-csr Create CSR, professional use.
+ --create-domain-key Create an domain private key, professional use.
--update-account Update account info.
--register-account Register account key.
--deactivate-account Deactivate the account.
--create-account-key Create an account private key, professional use.
- --create-domain-key Create an domain private key, professional use.
- --createCSR, -ccsr Create CSR , professional use.
- --deactivate Deactivate the domain authz, professional use.
+ --install-cronjob Install the cron job to renew certs, you don't need to call this. The 'install' command can automatically install the cron job.
+ --uninstall-cronjob Uninstall the cron job. The 'uninstall' command can do this automatically.
+ --cron Run cron job to renew all the certs.
--set-notify Set the cron notification hook, level or mode.
- --set-default-ca Used with '--server' , to set the default CA to use to use.
+ --deactivate Deactivate the domain authz, professional use.
+ --set-default-ca Used with '--server', Set the default CA to use.
+ See: $_SERVER_WIKI
Parameters:
- --domain, -d domain.tld Specifies a domain, used to issue, renew or revoke etc.
- --challenge-alias domain.tld The challenge domain alias for DNS alias mode: $_DNS_ALIAS_WIKI
- --domain-alias domain.tld The domain alias for DNS alias mode: $_DNS_ALIAS_WIKI
- --force, -f Used to force to install or force to renew a cert immediately.
- --staging, --test Use staging server, just for test.
- --debug Output debug info.
- --output-insecure Output all the sensitive messages. By default all the credentials/sensitive messages are hidden from the output/debug/log for security.
- --webroot, -w /path/to/webroot Specifies the web root folder for web root mode.
+ -d, --domain <domain.tld> Specifies a domain, used to issue, renew or revoke etc.
+ --challenge-alias <domain.tld> The challenge domain alias for DNS alias mode.
+ See: $_DNS_ALIAS_WIKI
+
+ --domain-alias <domain.tld> The domain alias for DNS alias mode.
+ See: $_DNS_ALIAS_WIKI
+
+ --preferred-chain <chain> If the CA offers multiple certificate chains, prefer the chain with an issuer matching this Subject Common Name.
+ If no match, the default offered chain will be used. (default: empty)
+ See: $_PREFERRED_CHAIN_WIKI
+
+ -f, --force Force install, force cert renewal or override sudo restrictions.
+ --staging, --test Use staging server, for testing.
+ --debug [0|1|2|3] Output debug info. Defaults to 1 if argument is omitted.
+ --output-insecure Output all the sensitive messages.
+ By default all the credentials/sensitive messages are hidden from the output/debug/log for security.
+ -w, --webroot <directory> Specifies the web root folder for web root mode.
--standalone Use standalone mode.
--alpn Use standalone alpn mode.
- --stateless Use stateless mode, see: $_STATELESS_WIKI
+ --stateless Use stateless mode.
+ See: $_STATELESS_WIKI
+
--apache Use apache mode.
- --dns [dns_cf|dns_dp|dns_cx|/path/to/api/file] Use dns mode or dns api.
- --dnssleep 300 The time in seconds to wait for all the txt records to take effect in dns api mode. It's not necessary to use this by default, $PROJECT_NAME polls dns status automatically.
-
- --keylength, -k [2048] Specifies the domain key length: 2048, 3072, 4096, 8192 or ec-256, ec-384, ec-521.
- --accountkeylength, -ak [2048] Specifies the account key length: 2048, 3072, 4096
- --log [/path/to/logfile] Specifies the log file. The default is: \"$DEFAULT_LOG_FILE\" if you don't give a file path here.
- --log-level 1|2 Specifies the log level, default is 1.
- --syslog [0|3|6|7] Syslog level, 0: disable syslog, 3: error, 6: info, 7: debug.
-
- --eab-kid EAB_KID Key Identifier for External Account Binding.
- --eab-hmac-key EAB_HMAC_KEY HMAC key for External Account Binding.
-
-
+ --dns [dns_hook] Use dns manual mode or dns api. Defaults to manual mode when argument is omitted.
+ See: $_DNS_API_WIKI
+
+ --dnssleep <seconds> The time in seconds to wait for all the txt records to propagate in dns api mode.
+ It's not necessary to use this by default, $PROJECT_NAME polls dns status by DOH automatically.
+ -k, --keylength <bits> Specifies the domain key length: 2048, 3072, 4096, 8192 or ec-256, ec-384, ec-521.
+ -ak, --accountkeylength <bits> Specifies the account key length: 2048, 3072, 4096
+ --log [file] Specifies the log file. Defaults to \"$DEFAULT_LOG_FILE\" if argument is omitted.
+ --log-level <1|2> Specifies the log level, default is 1.
+ --syslog <0|3|6|7> Syslog level, 0: disable syslog, 3: error, 6: info, 7: debug.
+ --eab-kid <eab_key_id> Key Identifier for External Account Binding.
+ --eab-hmac-key <eab_hmac_key> HMAC key for External Account Binding.
+
+
These parameters are to install the cert to nginx/apache or any other server after issue/renew a cert:
- --cert-file After issue/renew, the cert will be copied to this path.
- --key-file After issue/renew, the key will be copied to this path.
- --ca-file After issue/renew, the intermediate cert will be copied to this path.
- --fullchain-file After issue/renew, the fullchain cert will be copied to this path.
-
- --reloadcmd \"service nginx reload\" After issue/renew, it's used to reload the server.
-
- --server SERVER ACME Directory Resource URI. See: $_SERVER_WIKI (default: $DEFAULT_CA)
- --accountconf Specifies a customized account config file.
- --home Specifies the home dir for $PROJECT_NAME.
- --cert-home Specifies the home dir to save all the certs, only valid for '--install' command.
- --config-home Specifies the home dir to save all the configurations.
- --useragent Specifies the user agent string. it will be saved for future use too.
- --accountemail, -m Specifies the account email, only valid for the '--install' and '--update-account' command.
- --accountkey Specifies the account key path, only valid for the '--install' command.
- --days Specifies the days to renew the cert when using '--issue' command. The default value is $DEFAULT_RENEW days.
- --httpport Specifies the standalone listening port. Only valid if the server is behind a reverse proxy or load balancer.
- --tlsport Specifies the standalone tls listening port. Only valid if the server is behind a reverse proxy or load balancer.
- --local-address Specifies the standalone/tls server listening address, in case you have multiple ip addresses.
+ --cert-file <file> Path to copy the cert file to after issue/renew..
+ --key-file <file> Path to copy the key file to after issue/renew.
+ --ca-file <file> Path to copy the intermediate cert file to after issue/renew.
+ --fullchain-file <file> Path to copy the fullchain cert file to after issue/renew.
+ --reloadcmd <command> Command to execute after issue/renew to reload the server.
+
+ --server <server_uri> ACME Directory Resource URI. (default: $DEFAULT_CA)
+ See: $_SERVER_WIKI
+
+ --accountconf <file> Specifies a customized account config file.
+ --home <directory> Specifies the home dir for $PROJECT_NAME.
+ --cert-home <directory> Specifies the home dir to save all the certs, only valid for '--install' command.
+ --config-home <directory> Specifies the home dir to save all the configurations.
+ --useragent <string> Specifies the user agent string. it will be saved for future use too.
+ -m, --email <email> Specifies the account email, only valid for the '--install' and '--update-account' command.
+ --accountkey <file> Specifies the account key path, only valid for the '--install' command.
+ --days <ndays> Specifies the days to renew the cert when using '--issue' command. The default value is $DEFAULT_RENEW days.
+ --httpport <port> Specifies the standalone listening port. Only valid if the server is behind a reverse proxy or load balancer.
+ --tlsport <port> Specifies the standalone tls listening port. Only valid if the server is behind a reverse proxy or load balancer.
+ --local-address <ip> Specifies the standalone/tls server listening address, in case you have multiple ip addresses.
--listraw Only used for '--list' command, list the certs in raw format.
- --stopRenewOnError, -se Only valid for '--renew-all' command. Stop if one cert has error in renewal.
+ -se, --stop-renew-on-error Only valid for '--renew-all' command. Stop if one cert has error in renewal.
--insecure Do not check the server certificate, in some devices, the api server's certificate may not be trusted.
- --ca-bundle Specifies the path to the CA certificate bundle to verify api server's certificate.
- --ca-path Specifies directory containing CA certificates in PEM format, used by wget or curl.
- --nocron Only valid for '--install' command, which means: do not install the default cron job. In this case, the certs will not be renewed automatically.
- --noprofile Only valid for '--install' command, which means: do not install aliases to user profile.
+ --ca-bundle <file> Specifies the path to the CA certificate bundle to verify api server's certificate.
+ --ca-path <directory> Specifies directory containing CA certificates in PEM format, used by wget or curl.
+ --no-cron Only valid for '--install' command, which means: do not install the default cron job.
+ In this case, the certs will not be renewed automatically.
+ --no-profile Only valid for '--install' command, which means: do not install aliases to user profile.
--no-color Do not output color text.
--force-color Force output of color text. Useful for non-interactive use with the aha tool for HTML E-Mails.
- --ecc Specifies to use the ECC cert. Valid for '--install-cert', '--renew', '--revoke', '--toPkcs' and '--createCSR'
- --csr Specifies the input csr.
- --pre-hook Command to be run before obtaining any certificates.
- --post-hook Command to be run after attempting to obtain/renew certificates. No matter the obtain/renew is success or failed.
- --renew-hook Command to be run once for each successfully renewed certificate.
- --deploy-hook The hook file to deploy cert
- --ocsp-must-staple, --ocsp Generate ocsp must Staple extension.
- --always-force-new-domain-key Generate new domain key when renewal. Otherwise, the domain key is not changed by default.
- --auto-upgrade [0|1] Valid for '--upgrade' command, indicating whether to upgrade automatically in future.
+ --ecc Specifies to use the ECC cert. Valid for '--install-cert', '--renew', '--revoke', '--to-pkcs12' and '--create-csr'
+ --csr <file> Specifies the input csr.
+ --pre-hook <command> Command to be run before obtaining any certificates.
+ --post-hook <command> Command to be run after attempting to obtain/renew certificates. Runs regardless of whether obtain/renew succeeded or failed.
+ --renew-hook <command> Command to be run after each successfully renewed certificate.
+ --deploy-hook <hookname> The hook file to deploy cert
+ --ocsp, --ocsp-must-staple Generate OCSP-Must-Staple extension.
+ --always-force-new-domain-key Generate new domain key on renewal. Otherwise, the domain key is not changed by default.
+ --auto-upgrade [0|1] Valid for '--upgrade' command, indicating whether to upgrade automatically in future. Defaults to 1 if argument is omitted.
--listen-v4 Force standalone/tls server to listen at ipv4.
--listen-v6 Force standalone/tls server to listen at ipv6.
- --openssl-bin Specifies a custom openssl bin location.
+ --openssl-bin <file> Specifies a custom openssl bin location.
--use-wget Force to use wget, if you have both curl and wget installed.
- --yes-I-know-dns-manual-mode-enough-go-ahead-please Force to use dns manual mode: $_DNS_MANUAL_WIKI
- --branch, -b Only valid for '--upgrade' command, specifies the branch name to upgrade to.
-
- --notify-level 0|1|2|3 Set the notification level: Default value is $NOTIFY_LEVEL_DEFAULT.
- 0: disabled, no notification will be sent.
- 1: send notifications only when there is an error.
- 2: send notifications when a cert is successfully renewed, or there is an error.
- 3: send notifications when a cert is skipped, renewed, or error.
- --notify-mode 0|1 Set notification mode. Default value is $NOTIFY_MODE_DEFAULT.
- 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
+ --yes-I-know-dns-manual-mode-enough-go-ahead-please Force use of dns manual mode.
+ See: $_DNS_MANUAL_WIKI
+
+ -b, --branch <branch> Only valid for '--upgrade' command, specifies the branch name to upgrade to.
+ --notify-level <0|1|2|3> Set the notification level: Default value is $NOTIFY_LEVEL_DEFAULT.
+ 0: disabled, no notification will be sent.
+ 1: send notifications only when there is an error.
+ 2: send notifications when a cert is successfully renewed, or there is an error.
+ 3: send notifications when a cert is skipped, renewed, or error.
+ --notify-mode <0|1> Set notification mode. Default value is $NOTIFY_MODE_DEFAULT.
+ 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 revocation, can be used in conjunction with the '--revoke' command.
+ See: $_REVOKE_WIKI
+
+ --password <password> Add a password to exported pfx file. Use with --to-pkcs12.
+
"
}
-# nocron noprofile
-_installOnline() {
+installOnline() {
_info "Installing from online archive."
- _nocron="$1"
- _noprofile="$2"
- if [ ! "$BRANCH" ]; then
- BRANCH="master"
+
+ _branch="$BRANCH"
+ if [ -z "$_branch" ]; then
+ _branch="master"
fi
- target="$PROJECT/archive/$BRANCH.tar.gz"
+ target="$PROJECT/archive/$_branch.tar.gz"
_info "Downloading $target"
- localname="$BRANCH.tar.gz"
+ localname="$_branch.tar.gz"
if ! _get "$target" >$localname; then
_err "Download error."
return 1
exit 1
fi
- cd "$PROJECT_NAME-$BRANCH"
+ cd "$PROJECT_NAME-$_branch"
chmod +x $PROJECT_ENTRY
- if ./$PROJECT_ENTRY install "$_nocron" "" "$_noprofile"; then
+ if ./$PROJECT_ENTRY --install "$@"; then
_info "Install success!"
_initpath
_saveaccountconf "UPGRADE_HASH" "$(_getUpgradeHash)"
cd ..
- rm -rf "$PROJECT_NAME-$BRANCH"
+ rm -rf "$PROJECT_NAME-$_branch"
rm -f "$localname"
)
}
[ -z "$FORCE" ] && [ "$(_getUpgradeHash)" = "$(_readaccountconf "UPGRADE_HASH")" ] && _info "Already uptodate!" && exit 0
export LE_WORKING_DIR
cd "$LE_WORKING_DIR"
- _installOnline "nocron" "noprofile"
+ installOnline "--nocron" "--noprofile"
); then
_info "Upgrade success!"
exit 0
return 0
fi
if [ -n "$SUDO_COMMAND" ]; then
- #it's a normal user doing "sudo su", or `sudo -i` or `sudo -s`
- _endswith "$SUDO_COMMAND" /bin/su || grep "^$SUDO_COMMAND\$" /etc/shells >/dev/null 2>&1
+ #it's a normal user doing "sudo su", or `sudo -i` or `sudo -s`, or `sudo su acmeuser1`
+ _endswith "$SUDO_COMMAND" /bin/su || _contains "$SUDO_COMMAND" "/bin/su " || grep "^$SUDO_COMMAND\$" /etc/shells >/dev/null 2>&1
return $?
fi
#otherwise
#url
_getCAShortName() {
caurl="$1"
+ if [ -z "$caurl" ]; then
+ caurl="$DEFAULT_CA"
+ fi
caurl_lower="$(echo $caurl | _lower_case)"
_sindex=0
for surl in $(echo "$CA_SERVERS" | _lower_case | tr , ' '); do
_revoke_reason=""
_eab_kid=""
_eab_hmac_key=""
+ _preferred_chain=""
while [ ${#} -gt 0 ]; do
case "${1}" in
- --help | -h)
- showhelp
- return
- ;;
- --version | -v)
- version
- return
- ;;
- --install)
- _CMD="install"
- ;;
- --uninstall)
- _CMD="uninstall"
- ;;
- --upgrade)
- _CMD="upgrade"
- ;;
- --issue)
- _CMD="issue"
- ;;
- --deploy)
- _CMD="deploy"
- ;;
- --signcsr)
- _CMD="signcsr"
- ;;
- --showcsr)
- _CMD="showcsr"
- ;;
- --installcert | -i | --install-cert)
- _CMD="installcert"
- ;;
- --renew | -r)
- _CMD="renew"
- ;;
- --renewAll | --renewall | --renew-all)
- _CMD="renewAll"
- ;;
- --revoke)
- _CMD="revoke"
- ;;
- --remove)
- _CMD="remove"
- ;;
- --list)
- _CMD="list"
- ;;
- --installcronjob | --install-cronjob)
- _CMD="installcronjob"
- ;;
- --uninstallcronjob | --uninstall-cronjob)
- _CMD="uninstallcronjob"
- ;;
- --cron)
- _CMD="cron"
- ;;
- --toPkcs)
- _CMD="toPkcs"
- ;;
- --toPkcs8)
- _CMD="toPkcs8"
- ;;
- --createAccountKey | --createaccountkey | -cak | --create-account-key)
- _CMD="createAccountKey"
- ;;
- --createDomainKey | --createdomainkey | -cdk | --create-domain-key)
- _CMD="createDomainKey"
- ;;
- --createCSR | --createcsr | -ccr)
- _CMD="createCSR"
- ;;
- --deactivate)
- _CMD="deactivate"
- ;;
- --updateaccount | --update-account)
- _CMD="updateaccount"
- ;;
- --registeraccount | --register-account)
- _CMD="registeraccount"
- ;;
- --deactivate-account)
- _CMD="deactivateaccount"
- ;;
- --set-notify)
- _CMD="setnotify"
- ;;
- --set-default-ca)
- _CMD="setdefaultca"
- ;;
- --domain | -d)
- _dvalue="$2"
-
- if [ "$_dvalue" ]; then
- if _startswith "$_dvalue" "-"; then
- _err "'$_dvalue' is not a valid domain for parameter '$1'"
- return 1
- fi
- if _is_idn "$_dvalue" && ! _exists idn; then
- _err "It seems that $_dvalue is an IDN( Internationalized Domain Names), please install 'idn' command first."
- return 1
- fi
-
- if _startswith "$_dvalue" "*."; then
- _debug "Wildcard domain"
- export ACME_VERSION=2
- fi
- if [ -z "$_domain" ]; then
- _domain="$_dvalue"
- else
- if [ "$_altdomains" = "$NO_VALUE" ]; then
- _altdomains="$_dvalue"
- else
- _altdomains="$_altdomains,$_dvalue"
- fi
- fi
- fi
-
- shift
- ;;
+ --help | -h)
+ showhelp
+ return
+ ;;
+ --version | -v)
+ version
+ return
+ ;;
+ --install)
+ _CMD="install"
+ ;;
+ --install-online)
+ shift
+ installOnline "$@"
+ return
+ ;;
+ --uninstall)
+ _CMD="uninstall"
+ ;;
+ --upgrade)
+ _CMD="upgrade"
+ ;;
+ --issue)
+ _CMD="issue"
+ ;;
+ --deploy)
+ _CMD="deploy"
+ ;;
+ --sign-csr | --signcsr)
+ _CMD="signcsr"
+ ;;
+ --show-csr | --showcsr)
+ _CMD="showcsr"
+ ;;
+ -i | --install-cert | --installcert)
+ _CMD="installcert"
+ ;;
+ --renew | -r)
+ _CMD="renew"
+ ;;
+ --renew-all | --renewAll | --renewall)
+ _CMD="renewAll"
+ ;;
+ --revoke)
+ _CMD="revoke"
+ ;;
+ --remove)
+ _CMD="remove"
+ ;;
+ --list)
+ _CMD="list"
+ ;;
+ --install-cronjob | --installcronjob)
+ _CMD="installcronjob"
+ ;;
+ --uninstall-cronjob | --uninstallcronjob)
+ _CMD="uninstallcronjob"
+ ;;
+ --cron)
+ _CMD="cron"
+ ;;
+ --to-pkcs12 | --to-pkcs | --toPkcs)
+ _CMD="toPkcs"
+ ;;
+ --to-pkcs8 | --toPkcs8)
+ _CMD="toPkcs8"
+ ;;
+ --create-account-key | --createAccountKey | --createaccountkey | -cak)
+ _CMD="createAccountKey"
+ ;;
+ --create-domain-key | --createDomainKey | --createdomainkey | -cdk)
+ _CMD="createDomainKey"
+ ;;
+ -ccr | --create-csr | --createCSR | --createcsr)
+ _CMD="createCSR"
+ ;;
+ --deactivate)
+ _CMD="deactivate"
+ ;;
+ --update-account | --updateaccount)
+ _CMD="updateaccount"
+ ;;
+ --register-account | --registeraccount)
+ _CMD="registeraccount"
+ ;;
+ --deactivate-account)
+ _CMD="deactivateaccount"
+ ;;
+ --set-notify)
+ _CMD="setnotify"
+ ;;
+ --set-default-ca)
+ _CMD="setdefaultca"
+ ;;
+ -d | --domain)
+ _dvalue="$2"
- --force | -f)
- FORCE="1"
- ;;
- --staging | --test)
- STAGE="1"
- ;;
- --server)
- _server="$2"
- _selectServer "$_server"
- shift
- ;;
- --debug)
- if [ -z "$2" ] || _startswith "$2" "-"; then
- DEBUG="$DEBUG_LEVEL_DEFAULT"
- else
- DEBUG="$2"
- shift
- fi
- ;;
- --output-insecure)
- export OUTPUT_INSECURE=1
- ;;
- --webroot | -w)
- wvalue="$2"
- if [ -z "$_webroot" ]; then
- _webroot="$wvalue"
- else
- _webroot="$_webroot,$wvalue"
- fi
- shift
- ;;
- --challenge-alias)
- cvalue="$2"
- _challenge_alias="$_challenge_alias$cvalue,"
- shift
- ;;
- --domain-alias)
- cvalue="$DNS_ALIAS_PREFIX$2"
- _challenge_alias="$_challenge_alias$cvalue,"
- shift
- ;;
- --standalone)
- wvalue="$NO_VALUE"
- if [ -z "$_webroot" ]; then
- _webroot="$wvalue"
- else
- _webroot="$_webroot,$wvalue"
- fi
- ;;
- --alpn)
- wvalue="$W_ALPN"
- if [ -z "$_webroot" ]; then
- _webroot="$wvalue"
- else
- _webroot="$_webroot,$wvalue"
- fi
- ;;
- --stateless)
- wvalue="$MODE_STATELESS"
- if [ -z "$_webroot" ]; then
- _webroot="$wvalue"
- else
- _webroot="$_webroot,$wvalue"
- fi
- ;;
- --local-address)
- lvalue="$2"
- _local_address="$_local_address$lvalue,"
- shift
- ;;
- --apache)
- wvalue="apache"
- if [ -z "$_webroot" ]; then
- _webroot="$wvalue"
- else
- _webroot="$_webroot,$wvalue"
- fi
- ;;
- --nginx)
- wvalue="$NGINX"
- if [ "$2" ] && ! _startswith "$2" "-"; then
- wvalue="$NGINX$2"
- shift
+ if [ "$_dvalue" ]; then
+ if _startswith "$_dvalue" "-"; then
+ _err "'$_dvalue' is not a valid domain for parameter '$1'"
+ return 1
fi
- if [ -z "$_webroot" ]; then
- _webroot="$wvalue"
- else
- _webroot="$_webroot,$wvalue"
+ if _is_idn "$_dvalue" && ! _exists idn; then
+ _err "It seems that $_dvalue is an IDN( Internationalized Domain Names), please install 'idn' command first."
+ return 1
fi
- ;;
- --dns)
- wvalue="$W_DNS"
- if [ "$2" ] && ! _startswith "$2" "-"; then
- wvalue="$2"
- shift
+
+ if _startswith "$_dvalue" "*."; then
+ _debug "Wildcard domain"
+ export ACME_VERSION=2
fi
- if [ -z "$_webroot" ]; then
- _webroot="$wvalue"
+ if [ -z "$_domain" ]; then
+ _domain="$_dvalue"
else
- _webroot="$_webroot,$wvalue"
+ if [ "$_altdomains" = "$NO_VALUE" ]; then
+ _altdomains="$_dvalue"
+ else
+ _altdomains="$_altdomains,$_dvalue"
+ fi
fi
- ;;
- --dnssleep)
- _dnssleep="$2"
- Le_DNSSleep="$_dnssleep"
- shift
- ;;
+ fi
- --keylength | -k)
- _keylength="$2"
- shift
- ;;
- --accountkeylength | -ak)
- _accountkeylength="$2"
- shift
- ;;
+ shift
+ ;;
- --cert-file | --certpath)
- _cert_file="$2"
- shift
- ;;
- --key-file | --keypath)
- _key_file="$2"
- shift
- ;;
- --ca-file | --capath)
- _ca_file="$2"
- shift
- ;;
- --fullchain-file | --fullchainpath)
- _fullchain_file="$2"
- shift
- ;;
- --reloadcmd | --reloadCmd)
- _reloadcmd="$2"
- shift
- ;;
- --password)
- _password="$2"
- shift
- ;;
- --accountconf)
- _accountconf="$2"
- ACCOUNT_CONF_PATH="$_accountconf"
- shift
- ;;
- --home)
- LE_WORKING_DIR="$2"
- shift
- ;;
- --certhome | --cert-home)
- _certhome="$2"
- CERT_HOME="$_certhome"
- shift
- ;;
- --config-home)
- _confighome="$2"
- LE_CONFIG_HOME="$_confighome"
- shift
- ;;
- --useragent)
- _useragent="$2"
- USER_AGENT="$_useragent"
- shift
- ;;
- --accountemail | -m)
- _accountemail="$2"
- ACCOUNT_EMAIL="$_accountemail"
- shift
- ;;
- --accountkey)
- _accountkey="$2"
- ACCOUNT_KEY_PATH="$_accountkey"
- shift
- ;;
- --days)
- _days="$2"
- Le_RenewalDays="$_days"
- shift
- ;;
- --httpport)
- _httpport="$2"
- Le_HTTPPort="$_httpport"
- shift
- ;;
- --tlsport)
- _tlsport="$2"
- Le_TLSPort="$_tlsport"
- shift
- ;;
- --listraw)
- _listraw="raw"
- ;;
- --stopRenewOnError | --stoprenewonerror | -se)
- _stopRenewOnError="1"
- ;;
- --insecure)
- #_insecure="1"
- HTTPS_INSECURE="1"
- ;;
- --ca-bundle)
- _ca_bundle="$(_readlink "$2")"
- CA_BUNDLE="$_ca_bundle"
- shift
- ;;
- --ca-path)
- _ca_path="$2"
- CA_PATH="$_ca_path"
- shift
- ;;
- --nocron)
- _nocron="1"
- ;;
- --noprofile)
- _noprofile="1"
- ;;
- --no-color)
- export ACME_NO_COLOR=1
- ;;
- --force-color)
- export ACME_FORCE_COLOR=1
- ;;
- --ecc)
- _ecc="isEcc"
- ;;
- --csr)
- _csr="$2"
- shift
- ;;
- --pre-hook)
- _pre_hook="$2"
- shift
- ;;
- --post-hook)
- _post_hook="$2"
- shift
- ;;
- --renew-hook)
- _renew_hook="$2"
- shift
- ;;
- --deploy-hook)
- if [ -z "$2" ] || _startswith "$2" "-"; then
- _usage "Please specify a value for '--deploy-hook'"
- return 1
- fi
- _deploy_hook="$_deploy_hook$2,"
- shift
- ;;
- --ocsp-must-staple | --ocsp)
- Le_OCSP_Staple="1"
- ;;
- --always-force-new-domain-key)
- if [ -z "$2" ] || _startswith "$2" "-"; then
- Le_ForceNewDomainKey=1
- else
- Le_ForceNewDomainKey="$2"
- shift
- fi
- ;;
- --yes-I-know-dns-manual-mode-enough-go-ahead-please)
- export FORCE_DNS_MANUAL=1
- ;;
- --log | --logfile)
- _log="1"
- _logfile="$2"
- if _startswith "$_logfile" '-'; then
- _logfile=""
- else
- shift
- fi
- LOG_FILE="$_logfile"
- if [ -z "$LOG_LEVEL" ]; then
- LOG_LEVEL="$DEFAULT_LOG_LEVEL"
- fi
- ;;
- --log-level)
- _log_level="$2"
- LOG_LEVEL="$_log_level"
- shift
- ;;
- --syslog)
- if ! _startswith "$2" '-'; then
- _syslog="$2"
- shift
- fi
- if [ -z "$_syslog" ]; then
- _syslog="$SYSLOG_LEVEL_DEFAULT"
- fi
- ;;
- --auto-upgrade)
- _auto_upgrade="$2"
- if [ -z "$_auto_upgrade" ] || _startswith "$_auto_upgrade" '-'; then
- _auto_upgrade="1"
- else
- shift
- fi
- AUTO_UPGRADE="$_auto_upgrade"
- ;;
- --listen-v4)
- _listen_v4="1"
- Le_Listen_V4="$_listen_v4"
- ;;
- --listen-v6)
- _listen_v6="1"
- Le_Listen_V6="$_listen_v6"
- ;;
- --openssl-bin)
- _openssl_bin="$2"
- ACME_OPENSSL_BIN="$_openssl_bin"
- shift
- ;;
- --use-wget)
- _use_wget="1"
- ACME_USE_WGET="1"
- ;;
- --branch | -b)
- export BRANCH="$2"
+ -f | --force)
+ FORCE="1"
+ ;;
+ --staging | --test)
+ STAGE="1"
+ ;;
+ --server)
+ _server="$2"
+ _selectServer "$_server"
+ shift
+ ;;
+ --debug)
+ if [ -z "$2" ] || _startswith "$2" "-"; then
+ DEBUG="$DEBUG_LEVEL_DEFAULT"
+ else
+ DEBUG="$2"
shift
- ;;
- --notify-hook)
- _nhook="$2"
- if _startswith "$_nhook" "-"; then
- _err "'$_nhook' is not a hook name for '$1'"
- return 1
- fi
- if [ "$_notify_hook" ]; then
- _notify_hook="$_notify_hook,$_nhook"
- else
- _notify_hook="$_nhook"
- fi
+ fi
+ ;;
+ --output-insecure)
+ export OUTPUT_INSECURE=1
+ ;;
+ -w | --webroot)
+ wvalue="$2"
+ if [ -z "$_webroot" ]; then
+ _webroot="$wvalue"
+ else
+ _webroot="$_webroot,$wvalue"
+ fi
+ shift
+ ;;
+ --challenge-alias)
+ cvalue="$2"
+ _challenge_alias="$_challenge_alias$cvalue,"
+ shift
+ ;;
+ --domain-alias)
+ cvalue="$DNS_ALIAS_PREFIX$2"
+ _challenge_alias="$_challenge_alias$cvalue,"
+ shift
+ ;;
+ --standalone)
+ wvalue="$NO_VALUE"
+ if [ -z "$_webroot" ]; then
+ _webroot="$wvalue"
+ else
+ _webroot="$_webroot,$wvalue"
+ fi
+ ;;
+ --alpn)
+ wvalue="$W_ALPN"
+ if [ -z "$_webroot" ]; then
+ _webroot="$wvalue"
+ else
+ _webroot="$_webroot,$wvalue"
+ fi
+ ;;
+ --stateless)
+ wvalue="$MODE_STATELESS"
+ if [ -z "$_webroot" ]; then
+ _webroot="$wvalue"
+ else
+ _webroot="$_webroot,$wvalue"
+ fi
+ ;;
+ --local-address)
+ lvalue="$2"
+ _local_address="$_local_address$lvalue,"
+ shift
+ ;;
+ --apache)
+ wvalue="apache"
+ if [ -z "$_webroot" ]; then
+ _webroot="$wvalue"
+ else
+ _webroot="$_webroot,$wvalue"
+ fi
+ ;;
+ --nginx)
+ wvalue="$NGINX"
+ if [ "$2" ] && ! _startswith "$2" "-"; then
+ wvalue="$NGINX$2"
shift
- ;;
- --notify-level)
- _nlevel="$2"
- if _startswith "$_nlevel" "-"; then
- _err "'$_nlevel' is not a integer for '$1'"
- return 1
- fi
- _notify_level="$_nlevel"
+ fi
+ if [ -z "$_webroot" ]; then
+ _webroot="$wvalue"
+ else
+ _webroot="$_webroot,$wvalue"
+ fi
+ ;;
+ --dns)
+ wvalue="$W_DNS"
+ if [ "$2" ] && ! _startswith "$2" "-"; then
+ wvalue="$2"
shift
- ;;
- --notify-mode)
- _nmode="$2"
- if _startswith "$_nmode" "-"; then
- _err "'$_nmode' is not a integer for '$1'"
- return 1
- fi
- _notify_mode="$_nmode"
+ fi
+ if [ -z "$_webroot" ]; then
+ _webroot="$wvalue"
+ else
+ _webroot="$_webroot,$wvalue"
+ fi
+ ;;
+ --dnssleep)
+ _dnssleep="$2"
+ Le_DNSSleep="$_dnssleep"
+ shift
+ ;;
+
+ --keylength | -k)
+ _keylength="$2"
+ shift
+ ;;
+ -ak | --accountkeylength)
+ _accountkeylength="$2"
+ shift
+ ;;
+
+ --cert-file | --certpath)
+ _cert_file="$2"
+ shift
+ ;;
+ --key-file | --keypath)
+ _key_file="$2"
+ shift
+ ;;
+ --ca-file | --capath)
+ _ca_file="$2"
+ shift
+ ;;
+ --fullchain-file | --fullchainpath)
+ _fullchain_file="$2"
+ shift
+ ;;
+ --reloadcmd | --reloadCmd)
+ _reloadcmd="$2"
+ shift
+ ;;
+ --password)
+ _password="$2"
+ shift
+ ;;
+ --accountconf)
+ _accountconf="$2"
+ ACCOUNT_CONF_PATH="$_accountconf"
+ shift
+ ;;
+ --home)
+ LE_WORKING_DIR="$2"
+ shift
+ ;;
+ --cert-home | --certhome)
+ _certhome="$2"
+ CERT_HOME="$_certhome"
+ shift
+ ;;
+ --config-home)
+ _confighome="$2"
+ LE_CONFIG_HOME="$_confighome"
+ shift
+ ;;
+ --useragent)
+ _useragent="$2"
+ USER_AGENT="$_useragent"
+ shift
+ ;;
+ -m | --email | --accountemail)
+ _accountemail="$2"
+ export ACCOUNT_EMAIL="$_accountemail"
+ shift
+ ;;
+ --accountkey)
+ _accountkey="$2"
+ ACCOUNT_KEY_PATH="$_accountkey"
+ shift
+ ;;
+ --days)
+ _days="$2"
+ Le_RenewalDays="$_days"
+ shift
+ ;;
+ --httpport)
+ _httpport="$2"
+ Le_HTTPPort="$_httpport"
+ shift
+ ;;
+ --tlsport)
+ _tlsport="$2"
+ Le_TLSPort="$_tlsport"
+ shift
+ ;;
+ --listraw)
+ _listraw="raw"
+ ;;
+ -se | --stop-renew-on-error | --stopRenewOnError | --stoprenewonerror)
+ _stopRenewOnError="1"
+ ;;
+ --insecure)
+ #_insecure="1"
+ HTTPS_INSECURE="1"
+ ;;
+ --ca-bundle)
+ _ca_bundle="$(_readlink "$2")"
+ CA_BUNDLE="$_ca_bundle"
+ shift
+ ;;
+ --ca-path)
+ _ca_path="$2"
+ CA_PATH="$_ca_path"
+ shift
+ ;;
+ --no-cron | --nocron)
+ _nocron="1"
+ ;;
+ --no-profile | --noprofile)
+ _noprofile="1"
+ ;;
+ --no-color)
+ export ACME_NO_COLOR=1
+ ;;
+ --force-color)
+ export ACME_FORCE_COLOR=1
+ ;;
+ --ecc)
+ _ecc="isEcc"
+ ;;
+ --csr)
+ _csr="$2"
+ shift
+ ;;
+ --pre-hook)
+ _pre_hook="$2"
+ shift
+ ;;
+ --post-hook)
+ _post_hook="$2"
+ shift
+ ;;
+ --renew-hook)
+ _renew_hook="$2"
+ shift
+ ;;
+ --deploy-hook)
+ if [ -z "$2" ] || _startswith "$2" "-"; then
+ _usage "Please specify a value for '--deploy-hook'"
+ return 1
+ fi
+ _deploy_hook="$_deploy_hook$2,"
+ shift
+ ;;
+ --ocsp-must-staple | --ocsp)
+ Le_OCSP_Staple="1"
+ ;;
+ --always-force-new-domain-key)
+ if [ -z "$2" ] || _startswith "$2" "-"; then
+ Le_ForceNewDomainKey=1
+ else
+ Le_ForceNewDomainKey="$2"
shift
- ;;
- --revoke-reason)
- _revoke_reason="$2"
- if _startswith "$_revoke_reason" "-"; then
- _err "'$_revoke_reason' is not a integer for '$1'"
- return 1
- fi
+ fi
+ ;;
+ --yes-I-know-dns-manual-mode-enough-go-ahead-please)
+ export FORCE_DNS_MANUAL=1
+ ;;
+ --log | --logfile)
+ _log="1"
+ _logfile="$2"
+ if _startswith "$_logfile" '-'; then
+ _logfile=""
+ else
shift
- ;;
- --eab-kid)
- _eab_kid="$2"
+ fi
+ LOG_FILE="$_logfile"
+ if [ -z "$LOG_LEVEL" ]; then
+ LOG_LEVEL="$DEFAULT_LOG_LEVEL"
+ fi
+ ;;
+ --log-level)
+ _log_level="$2"
+ LOG_LEVEL="$_log_level"
+ shift
+ ;;
+ --syslog)
+ if ! _startswith "$2" '-'; then
+ _syslog="$2"
shift
- ;;
- --eab-hmac-key)
- _eab_hmac_key="$2"
+ fi
+ if [ -z "$_syslog" ]; then
+ _syslog="$SYSLOG_LEVEL_DEFAULT"
+ fi
+ ;;
+ --auto-upgrade)
+ _auto_upgrade="$2"
+ if [ -z "$_auto_upgrade" ] || _startswith "$_auto_upgrade" '-'; then
+ _auto_upgrade="1"
+ else
shift
- ;;
- *)
- _err "Unknown parameter : $1"
+ fi
+ AUTO_UPGRADE="$_auto_upgrade"
+ ;;
+ --listen-v4)
+ _listen_v4="1"
+ Le_Listen_V4="$_listen_v4"
+ ;;
+ --listen-v6)
+ _listen_v6="1"
+ Le_Listen_V6="$_listen_v6"
+ ;;
+ --openssl-bin)
+ _openssl_bin="$2"
+ ACME_OPENSSL_BIN="$_openssl_bin"
+ shift
+ ;;
+ --use-wget)
+ _use_wget="1"
+ ACME_USE_WGET="1"
+ ;;
+ --branch | -b)
+ export BRANCH="$2"
+ shift
+ ;;
+ --notify-hook)
+ _nhook="$2"
+ if _startswith "$_nhook" "-"; then
+ _err "'$_nhook' is not a hook name for '$1'"
return 1
- ;;
+ fi
+ if [ "$_notify_hook" ]; then
+ _notify_hook="$_notify_hook,$_nhook"
+ else
+ _notify_hook="$_nhook"
+ fi
+ shift
+ ;;
+ --notify-level)
+ _nlevel="$2"
+ if _startswith "$_nlevel" "-"; then
+ _err "'$_nlevel' is not a integer for '$1'"
+ return 1
+ fi
+ _notify_level="$_nlevel"
+ shift
+ ;;
+ --notify-mode)
+ _nmode="$2"
+ if _startswith "$_nmode" "-"; then
+ _err "'$_nmode' is not a integer for '$1'"
+ return 1
+ 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
+ ;;
+ --eab-kid)
+ _eab_kid="$2"
+ shift
+ ;;
+ --eab-hmac-key)
+ _eab_hmac_key="$2"
+ shift
+ ;;
+ --preferred-chain)
+ _preferred_chain="$2"
+ shift
+ ;;
+ *)
+ _err "Unknown parameter : $1"
+ return 1
+ ;;
esac
shift 1
fi
_debug "Running cmd: ${_CMD}"
case "${_CMD}" in
- install) install "$_nocron" "$_confighome" "$_noprofile" ;;
- uninstall) uninstall "$_nocron" ;;
- upgrade) upgrade ;;
- issue)
- issue "$_webroot" "$_domain" "$_altdomains" "$_keylength" "$_cert_file" "$_key_file" "$_ca_file" "$_reloadcmd" "$_fullchain_file" "$_pre_hook" "$_post_hook" "$_renew_hook" "$_local_address" "$_challenge_alias"
- ;;
- deploy)
- deploy "$_domain" "$_deploy_hook" "$_ecc"
- ;;
- signcsr)
- signcsr "$_csr" "$_webroot" "$_cert_file" "$_key_file" "$_ca_file" "$_reloadcmd" "$_fullchain_file" "$_pre_hook" "$_post_hook" "$_renew_hook" "$_local_address" "$_challenge_alias"
- ;;
- showcsr)
- showcsr "$_csr" "$_domain"
- ;;
- installcert)
- installcert "$_domain" "$_cert_file" "$_key_file" "$_ca_file" "$_reloadcmd" "$_fullchain_file" "$_ecc"
- ;;
- renew)
- renew "$_domain" "$_ecc"
- ;;
- renewAll)
- renewAll "$_stopRenewOnError"
- ;;
- revoke)
- revoke "$_domain" "$_ecc" "$_revoke_reason"
- ;;
- remove)
- remove "$_domain" "$_ecc"
- ;;
- deactivate)
- deactivate "$_domain,$_altdomains"
- ;;
- registeraccount)
- registeraccount "$_accountkeylength" "$_eab_kid" "$_eab_hmac_key"
- ;;
- updateaccount)
- updateaccount
- ;;
- deactivateaccount)
- deactivateaccount
- ;;
- list)
- list "$_listraw"
- ;;
- installcronjob) installcronjob "$_confighome" ;;
- uninstallcronjob) uninstallcronjob ;;
- cron) cron ;;
- toPkcs)
- toPkcs "$_domain" "$_password" "$_ecc"
- ;;
- toPkcs8)
- toPkcs8 "$_domain" "$_ecc"
- ;;
- createAccountKey)
- createAccountKey "$_accountkeylength"
- ;;
- createDomainKey)
- createDomainKey "$_domain" "$_keylength"
- ;;
- createCSR)
- createCSR "$_domain" "$_altdomains" "$_ecc"
- ;;
- setnotify)
- setnotify "$_notify_hook" "$_notify_level" "$_notify_mode"
- ;;
- setdefaultca)
- setdefaultca
- ;;
- *)
- if [ "$_CMD" ]; then
- _err "Invalid command: $_CMD"
- fi
- showhelp
- return 1
- ;;
+ install) install "$_nocron" "$_confighome" "$_noprofile" "$_accountemail" ;;
+ uninstall) uninstall "$_nocron" ;;
+ upgrade) upgrade ;;
+ issue)
+ issue "$_webroot" "$_domain" "$_altdomains" "$_keylength" "$_cert_file" "$_key_file" "$_ca_file" "$_reloadcmd" "$_fullchain_file" "$_pre_hook" "$_post_hook" "$_renew_hook" "$_local_address" "$_challenge_alias" "$_preferred_chain"
+ ;;
+ deploy)
+ deploy "$_domain" "$_deploy_hook" "$_ecc"
+ ;;
+ signcsr)
+ signcsr "$_csr" "$_webroot" "$_cert_file" "$_key_file" "$_ca_file" "$_reloadcmd" "$_fullchain_file" "$_pre_hook" "$_post_hook" "$_renew_hook" "$_local_address" "$_challenge_alias"
+ ;;
+ showcsr)
+ showcsr "$_csr" "$_domain"
+ ;;
+ installcert)
+ installcert "$_domain" "$_cert_file" "$_key_file" "$_ca_file" "$_reloadcmd" "$_fullchain_file" "$_ecc"
+ ;;
+ renew)
+ renew "$_domain" "$_ecc"
+ ;;
+ renewAll)
+ renewAll "$_stopRenewOnError"
+ ;;
+ revoke)
+ revoke "$_domain" "$_ecc" "$_revoke_reason"
+ ;;
+ remove)
+ remove "$_domain" "$_ecc"
+ ;;
+ deactivate)
+ deactivate "$_domain,$_altdomains"
+ ;;
+ registeraccount)
+ registeraccount "$_accountkeylength" "$_eab_kid" "$_eab_hmac_key"
+ ;;
+ updateaccount)
+ updateaccount
+ ;;
+ deactivateaccount)
+ deactivateaccount
+ ;;
+ list)
+ list "$_listraw" "$_domain"
+ ;;
+ installcronjob) installcronjob "$_confighome" ;;
+ uninstallcronjob) uninstallcronjob ;;
+ cron) cron ;;
+ toPkcs)
+ toPkcs "$_domain" "$_password" "$_ecc"
+ ;;
+ toPkcs8)
+ toPkcs8 "$_domain" "$_ecc"
+ ;;
+ createAccountKey)
+ createAccountKey "$_accountkeylength"
+ ;;
+ createDomainKey)
+ createDomainKey "$_domain" "$_keylength"
+ ;;
+ createCSR)
+ createCSR "$_domain" "$_altdomains" "$_ecc"
+ ;;
+ setnotify)
+ setnotify "$_notify_hook" "$_notify_level" "$_notify_mode"
+ ;;
+ setdefaultca)
+ setdefaultca
+ ;;
+ *)
+ if [ "$_CMD" ]; then
+ _err "Invalid command: $_CMD"
+ fi
+ showhelp
+ return 1
+ ;;
esac
_ret="$?"
if [ "$_ret" != "0" ]; then
}
-if [ "$INSTALLONLINE" ]; then
- INSTALLONLINE=""
- _installOnline
- exit
-fi
-
main() {
[ -z "$1" ] && showhelp && return
if _startswith "$1" '-'; then _process "$@"; else "$@"; fi