mirror of
https://github.com/plantroon/acme.sh.git
synced 2024-12-22 13:11:41 +00:00
Merge branch 'master' of https://github.com/Neilpang/acme.sh into ssh-deploy
This commit is contained in:
commit
c809b33161
@ -18,7 +18,7 @@ addons:
|
|||||||
|
|
||||||
install:
|
install:
|
||||||
- if [ "$TRAVIS_OS_NAME" = 'osx' ]; then
|
- if [ "$TRAVIS_OS_NAME" = 'osx' ]; then
|
||||||
brew update && brew install openssl;
|
brew update && brew install openssl socat;
|
||||||
brew info openssl;
|
brew info openssl;
|
||||||
ln -s /usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib /usr/local/lib/;
|
ln -s /usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib /usr/local/lib/;
|
||||||
ln -s /usr/local/opt/openssl/lib/libssl.1.0.0.dylib /usr/local/lib/;
|
ln -s /usr/local/opt/openssl/lib/libssl.1.0.0.dylib /usr/local/lib/;
|
||||||
@ -30,6 +30,7 @@ install:
|
|||||||
openssl version 2>&1 || true;
|
openssl version 2>&1 || true;
|
||||||
$ACME_OPENSSL_BIN version 2>&1 || true;
|
$ACME_OPENSSL_BIN version 2>&1 || true;
|
||||||
export PATH="$_old_path";
|
export PATH="$_old_path";
|
||||||
|
else sudo apt-get install socat;
|
||||||
fi
|
fi
|
||||||
|
|
||||||
script:
|
script:
|
||||||
|
@ -4,7 +4,7 @@ RUN apk update -f \
|
|||||||
&& apk --no-cache add -f \
|
&& apk --no-cache add -f \
|
||||||
openssl \
|
openssl \
|
||||||
curl \
|
curl \
|
||||||
netcat-openbsd \
|
socat \
|
||||||
&& rm -rf /var/cache/apk/*
|
&& rm -rf /var/cache/apk/*
|
||||||
|
|
||||||
ENV LE_CONFIG_HOME /acme.sh
|
ENV LE_CONFIG_HOME /acme.sh
|
||||||
@ -16,7 +16,7 @@ ADD ./ /install_acme.sh/
|
|||||||
RUN cd /install_acme.sh && ([ -f /install_acme.sh/acme.sh ] && /install_acme.sh/acme.sh --install || curl https://get.acme.sh | sh) && rm -rf /install_acme.sh/
|
RUN cd /install_acme.sh && ([ -f /install_acme.sh/acme.sh ] && /install_acme.sh/acme.sh --install || curl https://get.acme.sh | sh) && rm -rf /install_acme.sh/
|
||||||
|
|
||||||
|
|
||||||
RUN ln -s /root/.acme.sh/acme.sh /usr/local/bin/acme.sh && crontab -l | sed 's#> /dev/null##' | crontab -
|
RUN ln -s /root/.acme.sh/acme.sh /usr/local/bin/acme.sh && crontab -l | grep acme.sh | sed 's#> /dev/null##' | crontab -
|
||||||
|
|
||||||
RUN for verb in help \
|
RUN for verb in help \
|
||||||
version \
|
version \
|
||||||
|
181
acme.sh
181
acme.sh
@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env sh
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
VER=2.7.3
|
VER=2.7.4
|
||||||
|
|
||||||
PROJECT_NAME="acme.sh"
|
PROJECT_NAME="acme.sh"
|
||||||
|
|
||||||
@ -100,6 +100,10 @@ _PREPARE_LINK="https://github.com/Neilpang/acme.sh/wiki/Install-preparations"
|
|||||||
|
|
||||||
_STATELESS_WIKI="https://github.com/Neilpang/acme.sh/wiki/Stateless-Mode"
|
_STATELESS_WIKI="https://github.com/Neilpang/acme.sh/wiki/Stateless-Mode"
|
||||||
|
|
||||||
|
_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"
|
||||||
|
|
||||||
__INTERACTIVE=""
|
__INTERACTIVE=""
|
||||||
if [ -t 1 ]; then
|
if [ -t 1 ]; then
|
||||||
__INTERACTIVE="1"
|
__INTERACTIVE="1"
|
||||||
@ -160,11 +164,11 @@ _dlg_versions() {
|
|||||||
echo "nginx doesn't exists."
|
echo "nginx doesn't exists."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "nc:"
|
echo "socat:"
|
||||||
if _exists "nc"; then
|
if _exists "socat"; then
|
||||||
nc -h 2>&1
|
socat -h 2>&1
|
||||||
else
|
else
|
||||||
_debug "nc doesn't exists."
|
_debug "socat doesn't exists."
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1367,6 +1371,10 @@ _time2str() {
|
|||||||
echo "$_t_s_a"
|
echo "$_t_s_a"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
#Busybox
|
||||||
|
if echo "$1" | awk '{ print strftime("%c", $0); }' 2>/dev/null; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
_normalizeJson() {
|
_normalizeJson() {
|
||||||
@ -1806,7 +1814,13 @@ _send_signed_request() {
|
|||||||
|
|
||||||
_CACHED_NONCE="$(echo "$responseHeaders" | grep "Replay-Nonce:" | _head_n 1 | tr -d "\r\n " | cut -d ':' -f 2)"
|
_CACHED_NONCE="$(echo "$responseHeaders" | grep "Replay-Nonce:" | _head_n 1 | tr -d "\r\n " | cut -d ':' -f 2)"
|
||||||
|
|
||||||
if _contains "$response" "JWS has invalid anti-replay nonce"; then
|
_body="$response"
|
||||||
|
if [ "$needbase64" ]; then
|
||||||
|
_body="$(echo "$_body" | _dbase64)"
|
||||||
|
_debug2 _body "$_body"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if _contains "$_body" "JWS has invalid anti-replay nonce"; then
|
||||||
_info "It seems the CA server is busy now, let's wait and retry."
|
_info "It seems the CA server is busy now, let's wait and retry."
|
||||||
_request_retry_times=$(_math "$_request_retry_times" + 1)
|
_request_retry_times=$(_math "$_request_retry_times" + 1)
|
||||||
_sleep 5
|
_sleep 5
|
||||||
@ -1959,68 +1973,22 @@ _startserver() {
|
|||||||
_debug "ncaddr" "$ncaddr"
|
_debug "ncaddr" "$ncaddr"
|
||||||
|
|
||||||
_debug "startserver: $$"
|
_debug "startserver: $$"
|
||||||
nchelp="$(nc -h 2>&1)"
|
|
||||||
|
|
||||||
_debug Le_HTTPPort "$Le_HTTPPort"
|
_debug Le_HTTPPort "$Le_HTTPPort"
|
||||||
_debug Le_Listen_V4 "$Le_Listen_V4"
|
_debug Le_Listen_V4 "$Le_Listen_V4"
|
||||||
_debug Le_Listen_V6 "$Le_Listen_V6"
|
_debug Le_Listen_V6 "$Le_Listen_V6"
|
||||||
_NC="nc"
|
|
||||||
|
|
||||||
|
_NC="socat"
|
||||||
if [ "$Le_Listen_V4" ]; then
|
if [ "$Le_Listen_V4" ]; then
|
||||||
_NC="$_NC -4"
|
_NC="$_NC -4"
|
||||||
elif [ "$Le_Listen_V6" ]; then
|
elif [ "$Le_Listen_V6" ]; then
|
||||||
_NC="$_NC -6"
|
_NC="$_NC -6"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$Le_Listen_V4$Le_Listen_V6$ncaddr" ]; then
|
|
||||||
if ! _contains "$nchelp" "-4"; then
|
|
||||||
_err "The nc doesn't support '-4', '-6' or local-address, please install 'netcat-openbsd' and try again."
|
|
||||||
_err "See $(__green $_PREPARE_LINK)"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if echo "$nchelp" | grep "\-q[ ,]" >/dev/null; then
|
|
||||||
_NC="$_NC -q 1 -l $ncaddr"
|
|
||||||
else
|
|
||||||
if echo "$nchelp" | grep "GNU netcat" >/dev/null && echo "$nchelp" | grep "\-c, \-\-close" >/dev/null; then
|
|
||||||
_NC="$_NC -c -l $ncaddr"
|
|
||||||
elif echo "$nchelp" | grep "\-N" | grep "Shutdown the network socket after EOF on stdin" >/dev/null; then
|
|
||||||
_NC="$_NC -N -l $ncaddr"
|
|
||||||
else
|
|
||||||
_NC="$_NC -l $ncaddr"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
_debug "_NC" "$_NC"
|
_debug "_NC" "$_NC"
|
||||||
|
#todo listen address
|
||||||
#for centos ncat
|
$_NC TCP-LISTEN:$Le_HTTPPort,crlf,reuseaddr,fork SYSTEM:"sleep 0.5; echo HTTP/1.1 200 OK; echo ; echo $content; echo;" &
|
||||||
if _contains "$nchelp" "nmap.org"; then
|
serverproc="$!"
|
||||||
_debug "Using ncat: nmap.org"
|
|
||||||
if ! _exec "printf \"%s\r\n\r\n%s\" \"HTTP/1.1 200 OK\" \"$content\" | $_NC \"$Le_HTTPPort\" >&2"; then
|
|
||||||
_exec_err
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
if [ "$DEBUG" ]; then
|
|
||||||
_exec_err
|
|
||||||
fi
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
# while true ; do
|
|
||||||
if ! _exec "printf \"%s\r\n\r\n%s\" \"HTTP/1.1 200 OK\" \"$content\" | $_NC -p \"$Le_HTTPPort\" >&2"; then
|
|
||||||
_exec "printf \"%s\r\n\r\n%s\" \"HTTP/1.1 200 OK\" \"$content\" | $_NC \"$Le_HTTPPort\" >&2"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$?" != "0" ]; then
|
|
||||||
_err "nc listen error."
|
|
||||||
_exec_err
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
if [ "$DEBUG" ]; then
|
|
||||||
_exec_err
|
|
||||||
fi
|
|
||||||
# done
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_stopserver() {
|
_stopserver() {
|
||||||
@ -2030,25 +1998,8 @@ _stopserver() {
|
|||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
_debug2 "Le_HTTPPort" "$Le_HTTPPort"
|
kill $pid
|
||||||
if [ "$Le_HTTPPort" ]; then
|
|
||||||
if [ "$DEBUG" ] && [ "$DEBUG" -gt "3" ]; then
|
|
||||||
_get "http://localhost:$Le_HTTPPort" "" 1
|
|
||||||
else
|
|
||||||
_get "http://localhost:$Le_HTTPPort" "" 1 >/dev/null 2>&1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
_debug2 "Le_TLSPort" "$Le_TLSPort"
|
|
||||||
if [ "$Le_TLSPort" ]; then
|
|
||||||
if [ "$DEBUG" ] && [ "$DEBUG" -gt "3" ]; then
|
|
||||||
_get "https://localhost:$Le_TLSPort" "" 1
|
|
||||||
_get "https://localhost:$Le_TLSPort" "" 1
|
|
||||||
else
|
|
||||||
_get "https://localhost:$Le_TLSPort" "" 1 >/dev/null 2>&1
|
|
||||||
_get "https://localhost:$Le_TLSPort" "" 1 >/dev/null 2>&1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# sleep sec
|
# sleep sec
|
||||||
@ -2103,7 +2054,7 @@ _starttlsserver() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
__S_OPENSSL="${ACME_OPENSSL_BIN:-openssl} s_server -cert $TLS_CERT -key $TLS_KEY "
|
__S_OPENSSL="${ACME_OPENSSL_BIN:-openssl} s_server -www -cert $TLS_CERT -key $TLS_KEY "
|
||||||
if [ "$opaddr" ]; then
|
if [ "$opaddr" ]; then
|
||||||
__S_OPENSSL="$__S_OPENSSL -accept $opaddr:$port"
|
__S_OPENSSL="$__S_OPENSSL -accept $opaddr:$port"
|
||||||
else
|
else
|
||||||
@ -2120,9 +2071,9 @@ _starttlsserver() {
|
|||||||
|
|
||||||
_debug "$__S_OPENSSL"
|
_debug "$__S_OPENSSL"
|
||||||
if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then
|
if [ "$DEBUG" ] && [ "$DEBUG" -ge "2" ]; then
|
||||||
(printf "%s\r\n\r\n%s" "HTTP/1.1 200 OK" "$content" | $__S_OPENSSL -tlsextdebug) &
|
$__S_OPENSSL -tlsextdebug &
|
||||||
else
|
else
|
||||||
(printf "%s\r\n\r\n%s" "HTTP/1.1 200 OK" "$content" | $__S_OPENSSL >/dev/null 2>&1) &
|
$__S_OPENSSL >/dev/null 2>&1 &
|
||||||
fi
|
fi
|
||||||
|
|
||||||
serverproc="$!"
|
serverproc="$!"
|
||||||
@ -2298,6 +2249,7 @@ _initpath() {
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
_debug2 ACME_DIRECTORY "$ACME_DIRECTORY"
|
||||||
_ACME_SERVER_HOST="$(echo "$ACME_DIRECTORY" | cut -d : -f 2 | tr -s / | cut -d / -f 2)"
|
_ACME_SERVER_HOST="$(echo "$ACME_DIRECTORY" | cut -d : -f 2 | tr -s / | cut -d / -f 2)"
|
||||||
_debug2 "_ACME_SERVER_HOST" "$_ACME_SERVER_HOST"
|
_debug2 "_ACME_SERVER_HOST" "$_ACME_SERVER_HOST"
|
||||||
|
|
||||||
@ -2935,8 +2887,8 @@ _on_before_issue() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if _hasfield "$_chk_web_roots" "$NO_VALUE"; then
|
if _hasfield "$_chk_web_roots" "$NO_VALUE"; then
|
||||||
if ! _exists "nc"; then
|
if ! _exists "socat"; then
|
||||||
_err "Please install netcat(nc) tools first."
|
_err "Please install socat tools first."
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
@ -3042,6 +2994,10 @@ _on_issue_err() {
|
|||||||
)
|
)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "$IS_RENEW" = "1" ] && _hasfield "$Le_Webroot" "dns"; then
|
||||||
|
_err "$_DNS_MANUAL_ERR"
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "$DEBUG" ] && [ "$DEBUG" -gt "0" ]; then
|
if [ "$DEBUG" ] && [ "$DEBUG" -gt "0" ]; then
|
||||||
_debug "$(_dlg_versions)"
|
_debug "$(_dlg_versions)"
|
||||||
fi
|
fi
|
||||||
@ -3074,6 +3030,10 @@ _on_issue_success() {
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if _hasfield "$Le_Webroot" "dns"; then
|
||||||
|
_err "$_DNS_MANUAL_WARN"
|
||||||
|
fi
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
updateaccount() {
|
updateaccount() {
|
||||||
@ -3175,7 +3135,7 @@ _regAccount() {
|
|||||||
fi
|
fi
|
||||||
if [ "$code" = '202' ]; then
|
if [ "$code" = '202' ]; then
|
||||||
_info "Update account tos info success."
|
_info "Update account tos info success."
|
||||||
|
echo "$response" >"$ACCOUNT_JSON_PATH"
|
||||||
CA_KEY_HASH="$(__calcAccountKeyHash)"
|
CA_KEY_HASH="$(__calcAccountKeyHash)"
|
||||||
_debug "Calc CA_KEY_HASH" "$CA_KEY_HASH"
|
_debug "Calc CA_KEY_HASH" "$CA_KEY_HASH"
|
||||||
_savecaconf CA_KEY_HASH "$CA_KEY_HASH"
|
_savecaconf CA_KEY_HASH "$CA_KEY_HASH"
|
||||||
@ -3649,13 +3609,12 @@ issue() {
|
|||||||
_info "Standalone mode server"
|
_info "Standalone mode server"
|
||||||
_ncaddr="$(_getfield "$_local_addr" "$_ncIndex")"
|
_ncaddr="$(_getfield "$_local_addr" "$_ncIndex")"
|
||||||
_ncIndex="$(_math $_ncIndex + 1)"
|
_ncIndex="$(_math $_ncIndex + 1)"
|
||||||
_startserver "$keyauthorization" "$_ncaddr" &
|
_startserver "$keyauthorization" "$_ncaddr"
|
||||||
if [ "$?" != "0" ]; then
|
if [ "$?" != "0" ]; then
|
||||||
_clearup
|
_clearup
|
||||||
_on_issue_err "$_post_hook" "$vlist"
|
_on_issue_err "$_post_hook" "$vlist"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
serverproc="$!"
|
|
||||||
sleep 1
|
sleep 1
|
||||||
_debug serverproc "$serverproc"
|
_debug serverproc "$serverproc"
|
||||||
elif [ "$_currentRoot" = "$MODE_STATELESS" ]; then
|
elif [ "$_currentRoot" = "$MODE_STATELESS" ]; then
|
||||||
@ -3990,7 +3949,10 @@ issue() {
|
|||||||
Le_NextRenewTime=$(_math "$Le_NextRenewTime" - 86400)
|
Le_NextRenewTime=$(_math "$Le_NextRenewTime" - 86400)
|
||||||
_savedomainconf "Le_NextRenewTime" "$Le_NextRenewTime"
|
_savedomainconf "Le_NextRenewTime" "$Le_NextRenewTime"
|
||||||
|
|
||||||
_on_issue_success "$_post_hook" "$_renew_hook"
|
if ! _on_issue_success "$_post_hook" "$_renew_hook"; then
|
||||||
|
_err "Call hook error."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "$_real_cert$_real_key$_real_ca$_reload_cmd$_real_fullchain" ]; then
|
if [ "$_real_cert$_real_key$_real_ca$_reload_cmd$_real_fullchain" ]; then
|
||||||
_savedomainconf "Le_RealCertPath" "$_real_cert"
|
_savedomainconf "Le_RealCertPath" "$_real_cert"
|
||||||
@ -4417,15 +4379,19 @@ _installcert() {
|
|||||||
installcronjob() {
|
installcronjob() {
|
||||||
_c_home="$1"
|
_c_home="$1"
|
||||||
_initpath
|
_initpath
|
||||||
if ! _exists "crontab"; then
|
_CRONTAB="crontab"
|
||||||
_err "crontab doesn't exist, so, we can not install cron jobs."
|
if ! _exists "$_CRONTAB" && _exists "fcrontab"; then
|
||||||
|
_CRONTAB="fcrontab"
|
||||||
|
fi
|
||||||
|
if ! _exists "$_CRONTAB"; then
|
||||||
|
_err "crontab/fcrontab doesn't exist, so, we can not install cron jobs."
|
||||||
_err "All your certs will not be renewed automatically."
|
_err "All your certs will not be renewed automatically."
|
||||||
_err "You must add your own cron job to call '$PROJECT_ENTRY --cron' everyday."
|
_err "You must add your own cron job to call '$PROJECT_ENTRY --cron' everyday."
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
_info "Installing cron job"
|
_info "Installing cron job"
|
||||||
if ! crontab -l | grep "$PROJECT_ENTRY --cron"; then
|
if ! $_CRONTAB -l | grep "$PROJECT_ENTRY --cron"; then
|
||||||
if [ -f "$LE_WORKING_DIR/$PROJECT_ENTRY" ]; then
|
if [ -f "$LE_WORKING_DIR/$PROJECT_ENTRY" ]; then
|
||||||
lesh="\"$LE_WORKING_DIR\"/$PROJECT_ENTRY"
|
lesh="\"$LE_WORKING_DIR\"/$PROJECT_ENTRY"
|
||||||
else
|
else
|
||||||
@ -4439,15 +4405,15 @@ installcronjob() {
|
|||||||
_t=$(_time)
|
_t=$(_time)
|
||||||
random_minute=$(_math $_t % 60)
|
random_minute=$(_math $_t % 60)
|
||||||
if _exists uname && uname -a | grep SunOS >/dev/null; then
|
if _exists uname && uname -a | grep SunOS >/dev/null; then
|
||||||
crontab -l | {
|
$_CRONTAB -l | {
|
||||||
cat
|
cat
|
||||||
echo "$random_minute 0 * * * $lesh --cron --home \"$LE_WORKING_DIR\" $_c_entry> /dev/null"
|
echo "$random_minute 0 * * * $lesh --cron --home \"$LE_WORKING_DIR\" $_c_entry> /dev/null"
|
||||||
} | crontab --
|
} | $_CRONTAB --
|
||||||
else
|
else
|
||||||
crontab -l | {
|
$_CRONTAB -l | {
|
||||||
cat
|
cat
|
||||||
echo "$random_minute 0 * * * $lesh --cron --home \"$LE_WORKING_DIR\" $_c_entry> /dev/null"
|
echo "$random_minute 0 * * * $lesh --cron --home \"$LE_WORKING_DIR\" $_c_entry> /dev/null"
|
||||||
} | crontab -
|
} | $_CRONTAB -
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
if [ "$?" != "0" ]; then
|
if [ "$?" != "0" ]; then
|
||||||
@ -4459,16 +4425,21 @@ installcronjob() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uninstallcronjob() {
|
uninstallcronjob() {
|
||||||
if ! _exists "crontab"; then
|
_CRONTAB="crontab"
|
||||||
|
if ! _exists "$_CRONTAB" && _exists "fcrontab"; then
|
||||||
|
_CRONTAB="fcrontab"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! _exists "$_CRONTAB"; then
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
_info "Removing cron job"
|
_info "Removing cron job"
|
||||||
cr="$(crontab -l | grep "$PROJECT_ENTRY --cron")"
|
cr="$($_CRONTAB -l | grep "$PROJECT_ENTRY --cron")"
|
||||||
if [ "$cr" ]; then
|
if [ "$cr" ]; then
|
||||||
if _exists uname && uname -a | grep solaris >/dev/null; then
|
if _exists uname && uname -a | grep solaris >/dev/null; then
|
||||||
crontab -l | sed "/$PROJECT_ENTRY --cron/d" | crontab --
|
$_CRONTAB -l | sed "/$PROJECT_ENTRY --cron/d" | $_CRONTAB --
|
||||||
else
|
else
|
||||||
crontab -l | sed "/$PROJECT_ENTRY --cron/d" | crontab -
|
$_CRONTAB -l | sed "/$PROJECT_ENTRY --cron/d" | $_CRONTAB -
|
||||||
fi
|
fi
|
||||||
LE_WORKING_DIR="$(echo "$cr" | cut -d ' ' -f 9 | tr -d '"')"
|
LE_WORKING_DIR="$(echo "$cr" | cut -d ' ' -f 9 | tr -d '"')"
|
||||||
_info LE_WORKING_DIR "$LE_WORKING_DIR"
|
_info LE_WORKING_DIR "$LE_WORKING_DIR"
|
||||||
@ -4745,7 +4716,7 @@ _precheck() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "$_nocron" ]; then
|
if [ -z "$_nocron" ]; then
|
||||||
if ! _exists "crontab"; then
|
if ! _exists "crontab" && ! _exists "fcrontab"; then
|
||||||
_err "It is recommended to install crontab first. try to install 'cron, crontab, crontabs or vixie-cron'."
|
_err "It is recommended to install crontab first. try to install 'cron, crontab, crontabs or vixie-cron'."
|
||||||
_err "We need to set cron job to renew the certs automatically."
|
_err "We need to set cron job to renew the certs automatically."
|
||||||
_err "Otherwise, your certs will not be able to be renewed automatically."
|
_err "Otherwise, your certs will not be able to be renewed automatically."
|
||||||
@ -4763,9 +4734,9 @@ _precheck() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! _exists "nc"; then
|
if ! _exists "socat"; then
|
||||||
_err "It is recommended to install nc first, try to install 'nc' or 'netcat'."
|
_err "It is recommended to install socat first."
|
||||||
_err "We use nc for standalone server if you use standalone mode."
|
_err "We use socat for standalone server if you use standalone mode."
|
||||||
_err "If you don't use standalone mode, just ignore this warning."
|
_err "If you don't use standalone mode, just ignore this warning."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -4865,9 +4836,11 @@ install() {
|
|||||||
_debug "Skip install cron job"
|
_debug "Skip install cron job"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! _precheck "$_nocron"; then
|
if [ "$IN_CRON" != "1" ]; then
|
||||||
_err "Pre-check failed, can not install."
|
if ! _precheck "$_nocron"; then
|
||||||
return 1
|
_err "Pre-check failed, can not install."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "$_c_home" ] && [ "$LE_CONFIG_HOME" != "$LE_WORKING_DIR" ]; then
|
if [ -z "$_c_home" ] && [ "$LE_CONFIG_HOME" != "$LE_WORKING_DIR" ]; then
|
||||||
@ -4920,7 +4893,9 @@ install() {
|
|||||||
|
|
||||||
_info "Installed to $LE_WORKING_DIR/$PROJECT_ENTRY"
|
_info "Installed to $LE_WORKING_DIR/$PROJECT_ENTRY"
|
||||||
|
|
||||||
_installalias "$_c_home"
|
if [ "$IN_CRON" != "1" ]; then
|
||||||
|
_installalias "$_c_home"
|
||||||
|
fi
|
||||||
|
|
||||||
for subf in $_SUB_FOLDERS; do
|
for subf in $_SUB_FOLDERS; do
|
||||||
if [ -d "$subf" ]; then
|
if [ -d "$subf" ]; then
|
||||||
@ -5010,7 +4985,7 @@ _uninstallalias() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cron() {
|
cron() {
|
||||||
IN_CRON=1
|
export IN_CRON=1
|
||||||
_initpath
|
_initpath
|
||||||
_info "$(__green "===Starting cron===")"
|
_info "$(__green "===Starting cron===")"
|
||||||
if [ "$AUTO_UPGRADE" = "1" ]; then
|
if [ "$AUTO_UPGRADE" = "1" ]; then
|
||||||
|
@ -4,7 +4,9 @@ Before you can deploy your cert, you must [issue the cert first](https://github.
|
|||||||
|
|
||||||
Here are the scripts to deploy the certs/key to the server/services.
|
Here are the scripts to deploy the certs/key to the server/services.
|
||||||
|
|
||||||
## 1. Deploy the certs to your cpanel host.
|
## 1. Deploy the certs to your cpanel host
|
||||||
|
|
||||||
|
If you want to deploy using cpanel UAPI see 7.
|
||||||
|
|
||||||
(cpanel deploy hook is not finished yet, this is just an example.)
|
(cpanel deploy hook is not finished yet, this is just an example.)
|
||||||
|
|
||||||
@ -18,7 +20,7 @@ export DEPLOY_CPANEL_PASSWORD=PASSWORD
|
|||||||
acme.sh --deploy -d example.com --deploy-hook cpanel
|
acme.sh --deploy -d example.com --deploy-hook cpanel
|
||||||
```
|
```
|
||||||
|
|
||||||
## 2. Deploy ssl cert on kong proxy engine based on api.
|
## 2. Deploy ssl cert on kong proxy engine based on api
|
||||||
|
|
||||||
Before you can deploy your cert, you must [issue the cert first](https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert).
|
Before you can deploy your cert, you must [issue the cert first](https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert).
|
||||||
Currently supports Kong-v0.10.x.
|
Currently supports Kong-v0.10.x.
|
||||||
@ -27,7 +29,7 @@ Currently supports Kong-v0.10.x.
|
|||||||
acme.sh --deploy -d ftp.example.com --deploy-hook kong
|
acme.sh --deploy -d ftp.example.com --deploy-hook kong
|
||||||
```
|
```
|
||||||
|
|
||||||
## 3. Deploy the cert to remote server through SSH access.
|
## 3. Deploy the cert to remote server through SSH access
|
||||||
|
|
||||||
The ssh deploy plugin allows you to deploy certificates to a remote host
|
The ssh deploy plugin allows you to deploy certificates to a remote host
|
||||||
using SSH command to connect to the remote server. The ssh plugin is invoked
|
using SSH command to connect to the remote server. The ssh plugin is invoked
|
||||||
@ -170,7 +172,7 @@ export DEPLOY_SSH_BACKUP=no
|
|||||||
&& service unifi restart
|
&& service unifi restart
|
||||||
```
|
```
|
||||||
|
|
||||||
## 4. Deploy the cert to local vsftpd server.
|
## 4. Deploy the cert to local vsftpd server
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
acme.sh --deploy -d ftp.example.com --deploy-hook vsftpd
|
acme.sh --deploy -d ftp.example.com --deploy-hook vsftpd
|
||||||
@ -192,7 +194,7 @@ export DEPLOY_VSFTPD_RELOAD="/etc/init.d/vsftpd restart"
|
|||||||
acme.sh --deploy -d ftp.example.com --deploy-hook vsftpd
|
acme.sh --deploy -d ftp.example.com --deploy-hook vsftpd
|
||||||
```
|
```
|
||||||
|
|
||||||
## 5. Deploy the cert to local exim4 server.
|
## 5. Deploy the cert to local exim4 server
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
acme.sh --deploy -d ftp.example.com --deploy-hook exim4
|
acme.sh --deploy -d ftp.example.com --deploy-hook exim4
|
||||||
@ -219,3 +221,37 @@ acme.sh --deploy -d ftp.example.com --deploy-hook exim4
|
|||||||
```sh
|
```sh
|
||||||
acme.sh --deploy -d ftp.example.com --deploy-hook keychain
|
acme.sh --deploy -d ftp.example.com --deploy-hook keychain
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## 7. Deploy to cpanel host using UAPI
|
||||||
|
|
||||||
|
This hook is using UAPI and works in cPanel & WHM version 56 or newer.
|
||||||
|
```
|
||||||
|
acme.sh --deploy -d example.com --deploy-hook cpanel_uapi
|
||||||
|
```
|
||||||
|
DEPLOY_CPANEL_USER is required only if you run the script as root and it should contain cpanel username.
|
||||||
|
```sh
|
||||||
|
export DEPLOY_CPANEL_USER=username
|
||||||
|
acme.sh --deploy -d example.com --deploy-hook cpanel_uapi
|
||||||
|
```
|
||||||
|
Please note, that the cpanel_uapi hook will deploy only the first domain when your certificate will automatically renew. Therefore you should issue a separete certificate for each domain.
|
||||||
|
|
||||||
|
## 8. Deploy the cert to your FRITZ!Box router
|
||||||
|
|
||||||
|
You must specify the credentials that have administrative privileges on the FRITZ!Box in order to deploy the certificate, plus the URL of your FRITZ!Box, through the following environment variables:
|
||||||
|
```sh
|
||||||
|
$ export DEPLOY_FRITZBOX_USERNAME=my_username
|
||||||
|
$ export DEPLOY_FRITZBOX_PASSWORD=the_password
|
||||||
|
$ export DEPLOY_FRITZBOX_URL=https://fritzbox.example.com
|
||||||
|
```
|
||||||
|
|
||||||
|
After the first deployment, these values will be stored in your $HOME/.acme.sh/account.conf. You may now deploy the certificate like this:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
acme.sh --deploy -d fritzbox.example.com --deploy-hook fritzbox
|
||||||
|
```
|
||||||
|
|
||||||
|
## 9. Deploy the cert to strongswan
|
||||||
|
|
||||||
|
```sh
|
||||||
|
acme.sh --deploy -d ftp.example.com --deploy-hook strongswan
|
||||||
|
```
|
||||||
|
@ -1,29 +0,0 @@
|
|||||||
#!/usr/bin/env sh
|
|
||||||
|
|
||||||
#Here is the script to deploy the cert to your cpanel account by the cpanel APIs.
|
|
||||||
|
|
||||||
#returns 0 means success, otherwise error.
|
|
||||||
|
|
||||||
#export DEPLOY_CPANEL_USER=myusername
|
|
||||||
#export DEPLOY_CPANEL_PASSWORD=PASSWORD
|
|
||||||
|
|
||||||
######## Public functions #####################
|
|
||||||
|
|
||||||
#domain keyfile certfile cafile fullchain
|
|
||||||
cpanel_deploy() {
|
|
||||||
_cdomain="$1"
|
|
||||||
_ckey="$2"
|
|
||||||
_ccert="$3"
|
|
||||||
_cca="$4"
|
|
||||||
_cfullchain="$5"
|
|
||||||
|
|
||||||
_debug _cdomain "$_cdomain"
|
|
||||||
_debug _ckey "$_ckey"
|
|
||||||
_debug _ccert "$_ccert"
|
|
||||||
_debug _cca "$_cca"
|
|
||||||
_debug _cfullchain "$_cfullchain"
|
|
||||||
|
|
||||||
_err "Not implemented yet"
|
|
||||||
return 1
|
|
||||||
|
|
||||||
}
|
|
64
deploy/cpanel_uapi.sh
Normal file
64
deploy/cpanel_uapi.sh
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
# Here is the script to deploy the cert to your cpanel using the cpanel API.
|
||||||
|
# Uses command line uapi. --user option is needed only if run as root.
|
||||||
|
# Returns 0 when success.
|
||||||
|
# Written by Santeri Kannisto <santeri.kannisto@2globalnomads.info>
|
||||||
|
# Public domain, 2017
|
||||||
|
|
||||||
|
#export DEPLOY_CPANEL_USER=myusername
|
||||||
|
|
||||||
|
######## Public functions #####################
|
||||||
|
|
||||||
|
#domain keyfile certfile cafile fullchain
|
||||||
|
|
||||||
|
cpanel_uapi_deploy() {
|
||||||
|
_cdomain="$1"
|
||||||
|
_ckey="$2"
|
||||||
|
_ccert="$3"
|
||||||
|
_cca="$4"
|
||||||
|
_cfullchain="$5"
|
||||||
|
|
||||||
|
_debug _cdomain "$_cdomain"
|
||||||
|
_debug _ckey "$_ckey"
|
||||||
|
_debug _ccert "$_ccert"
|
||||||
|
_debug _cca "$_cca"
|
||||||
|
_debug _cfullchain "$_cfullchain"
|
||||||
|
|
||||||
|
if ! _exists uapi; then
|
||||||
|
_err "The command uapi is not found."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if ! _exists php; then
|
||||||
|
_err "The command php is not found."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
# read cert and key files and urlencode both
|
||||||
|
_certstr=$(cat "$_ccert")
|
||||||
|
_keystr=$(cat "$_ckey")
|
||||||
|
_cert=$(php -r "echo urlencode(\"$_certstr\");")
|
||||||
|
_key=$(php -r "echo urlencode(\"$_keystr\");")
|
||||||
|
|
||||||
|
_debug _cert "$_cert"
|
||||||
|
_debug _key "$_key"
|
||||||
|
|
||||||
|
if [ "$(id -u)" = 0 ]; then
|
||||||
|
if [ -z "$DEPLOY_CPANEL_USER" ]; then
|
||||||
|
_err "It seems that you are root, please define the target user name: export DEPLOY_CPANEL_USER=username"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
_savedomainconf DEPLOY_CPANEL_USER "$DEPLOY_CPANEL_USER"
|
||||||
|
_response=$(uapi --user="$DEPLOY_CPANEL_USER" SSL install_ssl domain="$_cdomain" cert="$_cert" key="$_key")
|
||||||
|
else
|
||||||
|
_response=$(uapi SSL install_ssl domain="$_cdomain" cert="$_cert" key="$_key")
|
||||||
|
fi
|
||||||
|
error_response="status: 0"
|
||||||
|
if test "${_response#*$error_response}" != "$_response"; then
|
||||||
|
_err "Error in deploying certificate:"
|
||||||
|
_err "$_response"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_debug response "$_response"
|
||||||
|
_info "Certificate successfully deployed"
|
||||||
|
return 0
|
||||||
|
}
|
108
deploy/fritzbox.sh
Normal file
108
deploy/fritzbox.sh
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
#Here is a script to deploy cert to an AVM FRITZ!Box router.
|
||||||
|
|
||||||
|
#returns 0 means success, otherwise error.
|
||||||
|
|
||||||
|
#DEPLOY_FRITZBOX_USERNAME="username"
|
||||||
|
#DEPLOY_FRITZBOX_PASSWORD="password"
|
||||||
|
#DEPLOY_FRITZBOX_URL="https://fritz.box"
|
||||||
|
|
||||||
|
# Kudos to wikrie at Github for his FRITZ!Box update script:
|
||||||
|
# https://gist.github.com/wikrie/f1d5747a714e0a34d0582981f7cb4cfb
|
||||||
|
|
||||||
|
######## Public functions #####################
|
||||||
|
|
||||||
|
#domain keyfile certfile cafile fullchain
|
||||||
|
fritzbox_deploy() {
|
||||||
|
_cdomain="$1"
|
||||||
|
_ckey="$2"
|
||||||
|
_ccert="$3"
|
||||||
|
_cca="$4"
|
||||||
|
_cfullchain="$5"
|
||||||
|
|
||||||
|
_debug _cdomain "$_cdomain"
|
||||||
|
_debug _ckey "$_ckey"
|
||||||
|
_debug _ccert "$_ccert"
|
||||||
|
_debug _cca "$_cca"
|
||||||
|
_debug _cfullchain "$_cfullchain"
|
||||||
|
|
||||||
|
if ! _exists iconv; then
|
||||||
|
_err "iconv not found"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_fritzbox_username="${DEPLOY_FRITZBOX_USERNAME}"
|
||||||
|
_fritzbox_password="${DEPLOY_FRITZBOX_PASSWORD}"
|
||||||
|
_fritzbox_url="${DEPLOY_FRITZBOX_URL}"
|
||||||
|
|
||||||
|
_debug _fritzbox_url "$_fritzbox_url"
|
||||||
|
_debug _fritzbox_username "$_fritzbox_username"
|
||||||
|
_secure_debug _fritzbox_password "$_fritzbox_password"
|
||||||
|
if [ -z "$_fritzbox_username" ]; then
|
||||||
|
_err "FRITZ!Box username is not found, please define DEPLOY_FRITZBOX_USERNAME."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if [ -z "$_fritzbox_password" ]; then
|
||||||
|
_err "FRITZ!Box password is not found, please define DEPLOY_FRITZBOX_PASSWORD."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if [ -z "$_fritzbox_url" ]; then
|
||||||
|
_err "FRITZ!Box url is not found, please define DEPLOY_FRITZBOX_URL."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_saveaccountconf DEPLOY_FRITZBOX_USERNAME "${_fritzbox_username}"
|
||||||
|
_saveaccountconf DEPLOY_FRITZBOX_PASSWORD "${_fritzbox_password}"
|
||||||
|
_saveaccountconf DEPLOY_FRITZBOX_URL "${_fritzbox_url}"
|
||||||
|
|
||||||
|
# Do not check for a valid SSL certificate, because initially the cert is not valid, so it could not install the LE generated certificate
|
||||||
|
export HTTPS_INSECURE=1
|
||||||
|
|
||||||
|
_info "Log in to the FRITZ!Box"
|
||||||
|
_fritzbox_challenge="$(_get "${_fritzbox_url}/login_sid.lua" | sed -e 's/^.*<Challenge>//' -e 's/<\/Challenge>.*$//')"
|
||||||
|
_fritzbox_hash="$(printf "%s-%s" "${_fritzbox_challenge}" "${_fritzbox_password}" | iconv -f ASCII -t UTF16LE | md5sum | awk '{print $1}')"
|
||||||
|
_fritzbox_sid="$(_get "${_fritzbox_url}/login_sid.lua?sid=0000000000000000&username=${_fritzbox_username}&response=${_fritzbox_challenge}-${_fritzbox_hash}" | sed -e 's/^.*<SID>//' -e 's/<\/SID>.*$//')"
|
||||||
|
|
||||||
|
if [ -z "${_fritzbox_sid}" ] || [ "${_fritzbox_sid}" = "0000000000000000" ]; then
|
||||||
|
_err "Logging in to the FRITZ!Box failed. Please check username, password and URL."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_info "Generate form POST request"
|
||||||
|
_post_request="$(_mktemp)"
|
||||||
|
_post_boundary="---------------------------$(date +%Y%m%d%H%M%S)"
|
||||||
|
# _CERTPASSWORD_ is unset because Let's Encrypt certificates don't have a password. But if they ever do, here's the place to use it!
|
||||||
|
_CERTPASSWORD_=
|
||||||
|
{
|
||||||
|
printf -- "--"
|
||||||
|
printf -- "%s\r\n" "${_post_boundary}"
|
||||||
|
printf "Content-Disposition: form-data; name=\"sid\"\r\n\r\n%s\r\n" "${_fritzbox_sid}"
|
||||||
|
printf -- "--"
|
||||||
|
printf -- "%s\r\n" "${_post_boundary}"
|
||||||
|
printf "Content-Disposition: form-data; name=\"BoxCertPassword\"\r\n\r\n%s\r\n" "${_CERTPASSWORD_}"
|
||||||
|
printf -- "--"
|
||||||
|
printf -- "%s\r\n" "${_post_boundary}"
|
||||||
|
printf "Content-Disposition: form-data; name=\"BoxCertImportFile\"; filename=\"BoxCert.pem\"\r\n"
|
||||||
|
printf "Content-Type: application/octet-stream\r\n\r\n"
|
||||||
|
cat "${_ckey}" "${_cfullchain}"
|
||||||
|
printf "\r\n"
|
||||||
|
printf -- "--"
|
||||||
|
printf -- "%s--" "${_post_boundary}"
|
||||||
|
} >>"${_post_request}"
|
||||||
|
|
||||||
|
_info "Upload certificate to the FRITZ!Box"
|
||||||
|
|
||||||
|
export _H1="Content-type: multipart/form-data boundary=${_post_boundary}"
|
||||||
|
_post "$(cat "${_post_request}")" "${_fritzbox_url}/cgi-bin/firmwarecfg" | grep SSL
|
||||||
|
|
||||||
|
retval=$?
|
||||||
|
if [ $retval = 0 ]; then
|
||||||
|
_info "Upload successful"
|
||||||
|
else
|
||||||
|
_err "Upload failed"
|
||||||
|
fi
|
||||||
|
rm "${_post_request}"
|
||||||
|
|
||||||
|
return $retval
|
||||||
|
}
|
32
deploy/strongswan.sh
Normal file
32
deploy/strongswan.sh
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
#Here is a sample custom api script.
|
||||||
|
#This file name is "myapi.sh"
|
||||||
|
#So, here must be a method myapi_deploy()
|
||||||
|
#Which will be called by acme.sh to deploy the cert
|
||||||
|
#returns 0 means success, otherwise error.
|
||||||
|
|
||||||
|
######## Public functions #####################
|
||||||
|
|
||||||
|
#domain keyfile certfile cafile fullchain
|
||||||
|
strongswan_deploy() {
|
||||||
|
_cdomain="$1"
|
||||||
|
_ckey="$2"
|
||||||
|
_ccert="$3"
|
||||||
|
_cca="$4"
|
||||||
|
_cfullchain="$5"
|
||||||
|
|
||||||
|
_debug _cdomain "$_cdomain"
|
||||||
|
_debug _ckey "$_ckey"
|
||||||
|
_debug _ccert "$_ccert"
|
||||||
|
_debug _cca "$_cca"
|
||||||
|
_debug _cfullchain "$_cfullchain"
|
||||||
|
|
||||||
|
cat "$_ckey" >"/etc/ipsec.d/private/$(basename "$_ckey")"
|
||||||
|
cat "$_ccert" >"/etc/ipsec.d/certs/$(basename "$_ccert")"
|
||||||
|
cat "$_cca" >"/etc/ipsec.d/cacerts/$(basename "$_cca")"
|
||||||
|
cat "$_cfullchain" >"/etc/ipsec.d/cacerts/$(basename "$_cfullchain")"
|
||||||
|
|
||||||
|
ipsec reload
|
||||||
|
|
||||||
|
}
|
@ -420,6 +420,7 @@ Ok, let's issue a cert now:
|
|||||||
```
|
```
|
||||||
acme.sh --issue --dns dns_cloudns -d example.com -d www.example.com
|
acme.sh --issue --dns dns_cloudns -d example.com -d www.example.com
|
||||||
```
|
```
|
||||||
|
The `CLOUDNS_AUTH_ID` and `CLOUDNS_AUTH_PASSWORD` will be saved in `~/.acme.sh/account.conf` and will be reused when needed.
|
||||||
|
|
||||||
## 22. Use Infoblox API
|
## 22. Use Infoblox API
|
||||||
|
|
||||||
@ -512,14 +513,11 @@ export DuckDNS_Token="aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
|
|||||||
```
|
```
|
||||||
|
|
||||||
Please note that since DuckDNS uses StartSSL as their cert provider, thus
|
Please note that since DuckDNS uses StartSSL as their cert provider, thus
|
||||||
--insecure must be used when issuing certs:
|
--insecure may need to be used when issuing certs:
|
||||||
```
|
```
|
||||||
acme.sh --insecure --issue --dns dns_duckdns -d mydomain.duckdns.org
|
acme.sh --insecure --issue --dns dns_duckdns -d mydomain.duckdns.org
|
||||||
```
|
```
|
||||||
|
|
||||||
Also, DuckDNS uses the domain name as username for recording changing, so the
|
|
||||||
account file will always store the lastly used domain name.
|
|
||||||
|
|
||||||
For issues, please report to https://github.com/raidenii/acme.sh/issues.
|
For issues, please report to https://github.com/raidenii/acme.sh/issues.
|
||||||
|
|
||||||
## 28. Use Name.com API
|
## 28. Use Name.com API
|
||||||
|
@ -87,6 +87,7 @@ _get_root() {
|
|||||||
_debug "response" "$response"
|
_debug "response" "$response"
|
||||||
while true; do
|
while true; do
|
||||||
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
|
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
|
||||||
|
_debug2 "Checking domain: $h"
|
||||||
if [ -z "$h" ]; then
|
if [ -z "$h" ]; then
|
||||||
if _contains "$response" "<IsTruncated>true</IsTruncated>" && _contains "$response" "<NextMarker>"; then
|
if _contains "$response" "<IsTruncated>true</IsTruncated>" && _contains "$response" "<NextMarker>"; then
|
||||||
_debug "IsTruncated"
|
_debug "IsTruncated"
|
||||||
@ -102,23 +103,23 @@ _get_root() {
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
#not valid
|
#not valid
|
||||||
|
_err "Invalid domain"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if _contains "$response" "<Name>$h.</Name>"; then
|
if _contains "$response" "<Name>$h.</Name>"; then
|
||||||
hostedzone="$(echo "$response" | sed 's/<HostedZone>/#&/g' | tr '#' '\n' | _egrep_o "<HostedZone><Id>[^<]*<.Id><Name>$h.<.Name>.*<PrivateZone>false<.PrivateZone>.*<.HostedZone>")"
|
hostedzone="$(echo "$response" | sed 's/<HostedZone>/#&/g' | tr '#' '\n' | _egrep_o "<HostedZone><Id>[^<]*<.Id><Name>$h.<.Name>.*<PrivateZone>false<.PrivateZone>.*<.HostedZone>")"
|
||||||
_debug hostedzone "$hostedzone"
|
_debug hostedzone "$hostedzone"
|
||||||
if [ -z "$hostedzone" ]; then
|
if [ "$hostedzone" ]; then
|
||||||
_err "Error, can not get hostedzone."
|
_domain_id=$(printf "%s\n" "$hostedzone" | _egrep_o "<Id>.*<.Id>" | head -n 1 | _egrep_o ">.*<" | tr -d "<>")
|
||||||
|
if [ "$_domain_id" ]; then
|
||||||
|
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
|
||||||
|
_domain=$h
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
_err "Can not find domain id: $h"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
_domain_id=$(printf "%s\n" "$hostedzone" | _egrep_o "<Id>.*<.Id>" | head -n 1 | _egrep_o ">.*<" | tr -d "<>")
|
|
||||||
if [ "$_domain_id" ]; then
|
|
||||||
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
|
|
||||||
_domain=$h
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
return 1
|
|
||||||
fi
|
fi
|
||||||
p=$i
|
p=$i
|
||||||
i=$(_math "$i" + 1)
|
i=$(_math "$i" + 1)
|
||||||
|
@ -96,6 +96,16 @@ _dns_cloudns_init_check() {
|
|||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
CLOUDNS_AUTH_ID="${CLOUDNS_AUTH_ID:-$(_readaccountconf_mutable CLOUDNS_AUTH_ID)}"
|
||||||
|
CLOUDNS_AUTH_PASSWORD="${CLOUDNS_AUTH_PASSWORD:-$(_readaccountconf_mutable CLOUDNS_AUTH_PASSWORD)}"
|
||||||
|
if [ -z "$CLOUDNS_AUTH_ID" ] || [ -z "$CLOUDNS_AUTH_PASSWORD" ]; then
|
||||||
|
CLOUDNS_AUTH_ID=""
|
||||||
|
CLOUDNS_AUTH_PASSWORD=""
|
||||||
|
_err "You don't specify cloudns api id and password yet."
|
||||||
|
_err "Please create you id and password and try again."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
if [ -z "$CLOUDNS_AUTH_ID" ]; then
|
if [ -z "$CLOUDNS_AUTH_ID" ]; then
|
||||||
_err "CLOUDNS_AUTH_ID is not configured"
|
_err "CLOUDNS_AUTH_ID is not configured"
|
||||||
return 1
|
return 1
|
||||||
@ -113,6 +123,10 @@ _dns_cloudns_init_check() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
#save the api id and password to the account conf file.
|
||||||
|
_saveaccountconf_mutable CLOUDNS_AUTH_ID "$CLOUDNS_AUTH_ID"
|
||||||
|
_saveaccountconf_mutable CLOUDNS_AUTH_PASSWORD "$CLOUDNS_AUTH_PASSWORD"
|
||||||
|
|
||||||
CLOUDNS_INIT_CHECK_COMPLETED=1
|
CLOUDNS_INIT_CHECK_COMPLETED=1
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
@ -3,11 +3,14 @@
|
|||||||
#Created by RaidenII, to use DuckDNS's API to add/remove text records
|
#Created by RaidenII, to use DuckDNS's API to add/remove text records
|
||||||
#06/27/2017
|
#06/27/2017
|
||||||
|
|
||||||
# Currently only support single domain access
|
# Pass credentials before "acme.sh --issue --dns dns_duckdns ..."
|
||||||
# Due to the fact that DuckDNS uses StartSSL as cert provider, --insecure must be used with acme.sh
|
# --
|
||||||
|
# export DuckDNS_Token="aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
|
||||||
|
# --
|
||||||
|
#
|
||||||
|
# Due to the fact that DuckDNS uses StartSSL as cert provider, --insecure may need to be used with acme.sh
|
||||||
|
|
||||||
DuckDNS_API="https://www.duckdns.org/update"
|
DuckDNS_API="https://www.duckdns.org/update"
|
||||||
API_Params="domains=$DuckDNS_Domain&token=$DuckDNS_Token"
|
|
||||||
|
|
||||||
######## Public functions #####################
|
######## Public functions #####################
|
||||||
|
|
||||||
@ -16,35 +19,36 @@ dns_duckdns_add() {
|
|||||||
fulldomain=$1
|
fulldomain=$1
|
||||||
txtvalue=$2
|
txtvalue=$2
|
||||||
|
|
||||||
# We'll extract the domain/username from full domain
|
DuckDNS_Token="${DuckDNS_Token:-$(_readaccountconf_mutable DuckDNS_Token)}"
|
||||||
DuckDNS_Domain=$(echo "$fulldomain" | _lower_case | _egrep_o '.[^.]*.duckdns.org' | cut -d . -f 2)
|
|
||||||
|
|
||||||
if [ -z "$DuckDNS_Domain" ]; then
|
|
||||||
_err "Error extracting the domain."
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "$DuckDNS_Token" ]; then
|
if [ -z "$DuckDNS_Token" ]; then
|
||||||
DuckDNS_Token=""
|
_err "You must export variable: DuckDNS_Token"
|
||||||
_err "The token for your DuckDNS account is necessary."
|
_err "The token for your DuckDNS account is necessary."
|
||||||
_err "You can look it up in your DuckDNS account."
|
_err "You can look it up in your DuckDNS account."
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Now save the credentials.
|
# Now save the credentials.
|
||||||
_saveaccountconf DuckDNS_Domain "$DuckDNS_Domain"
|
_saveaccountconf_mutable DuckDNS_Token "$DuckDNS_Token"
|
||||||
_saveaccountconf DuckDNS_Token "$DuckDNS_Token"
|
|
||||||
|
|
||||||
# Unfortunately, DuckDNS does not seems to support lookup domain through API
|
# Unfortunately, DuckDNS does not seems to support lookup domain through API
|
||||||
# So I assume your credentials (which are your domain and token) are correct
|
# So I assume your credentials (which are your domain and token) are correct
|
||||||
# If something goes wrong, we will get a KO response from DuckDNS
|
# If something goes wrong, we will get a KO response from DuckDNS
|
||||||
|
|
||||||
|
if ! _duckdns_get_domain; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
# Now add the TXT record to DuckDNS
|
# Now add the TXT record to DuckDNS
|
||||||
_info "Trying to add TXT record"
|
_info "Trying to add TXT record"
|
||||||
if _duckdns_rest GET "$API_Params&txt=$txtvalue" && [ "$response" = "OK" ]; then
|
if _duckdns_rest GET "domains=$_duckdns_domain&token=$DuckDNS_Token&txt=$txtvalue"; then
|
||||||
_info "TXT record has been successfully added to your DuckDNS domain."
|
if [ "$response" = "OK" ]; then
|
||||||
_info "Note that all subdomains under this domain uses the same TXT record."
|
_info "TXT record has been successfully added to your DuckDNS domain."
|
||||||
return 0
|
_info "Note that all subdomains under this domain uses the same TXT record."
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
_err "Errors happened during adding the TXT record, response=$response"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
_err "Errors happened during adding the TXT record."
|
_err "Errors happened during adding the TXT record."
|
||||||
return 1
|
return 1
|
||||||
@ -57,11 +61,28 @@ dns_duckdns_rm() {
|
|||||||
fulldomain=$1
|
fulldomain=$1
|
||||||
txtvalue=$2
|
txtvalue=$2
|
||||||
|
|
||||||
|
DuckDNS_Token="${DuckDNS_Token:-$(_readaccountconf_mutable DuckDNS_Token)}"
|
||||||
|
if [ -z "$DuckDNS_Token" ]; then
|
||||||
|
_err "You must export variable: DuckDNS_Token"
|
||||||
|
_err "The token for your DuckDNS account is necessary."
|
||||||
|
_err "You can look it up in your DuckDNS account."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! _duckdns_get_domain; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
# Now remove the TXT record from DuckDNS
|
# Now remove the TXT record from DuckDNS
|
||||||
_info "Trying to remove TXT record"
|
_info "Trying to remove TXT record"
|
||||||
if _duckdns_rest GET "$API_Params&txt=&clear=true" && [ "$response" = "OK" ]; then
|
if _duckdns_rest GET "domains=$_duckdns_domain&token=$DuckDNS_Token&txt=&clear=true"; then
|
||||||
_info "TXT record has been successfully removed from your DuckDNS domain."
|
if [ "$response" = "OK" ]; then
|
||||||
return 0
|
_info "TXT record has been successfully removed from your DuckDNS domain."
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
_err "Errors happened during removing the TXT record, response=$response"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
_err "Errors happened during removing the TXT record."
|
_err "Errors happened during removing the TXT record."
|
||||||
return 1
|
return 1
|
||||||
@ -70,6 +91,22 @@ dns_duckdns_rm() {
|
|||||||
|
|
||||||
#################### Private functions below ##################################
|
#################### Private functions below ##################################
|
||||||
|
|
||||||
|
#fulldomain=_acme-challenge.domain.duckdns.org
|
||||||
|
#returns
|
||||||
|
# _duckdns_domain=domain
|
||||||
|
_duckdns_get_domain() {
|
||||||
|
|
||||||
|
# We'll extract the domain/username from full domain
|
||||||
|
_duckdns_domain="$(printf "%s" "$fulldomain" | _lower_case | _egrep_o '[.][^.][^.]*[.]duckdns.org' | cut -d . -f 2)"
|
||||||
|
|
||||||
|
if [ -z "$_duckdns_domain" ]; then
|
||||||
|
_err "Error extracting the domain."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
#Usage: method URI
|
#Usage: method URI
|
||||||
_duckdns_rest() {
|
_duckdns_rest() {
|
||||||
method=$1
|
method=$1
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
#
|
#
|
||||||
######## Public functions #####################
|
######## Public functions #####################
|
||||||
|
|
||||||
GANDI_LIVEDNS_API="https://dns.beta.gandi.net/api/v5"
|
GANDI_LIVEDNS_API="https://dns.api.gandi.net/api/v5"
|
||||||
|
|
||||||
#Usage: dns_gandi_livedns_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
#Usage: dns_gandi_livedns_add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||||
dns_gandi_livedns_add() {
|
dns_gandi_livedns_add() {
|
||||||
|
@ -47,7 +47,7 @@ dns_he_add() {
|
|||||||
response="$(_post "$body" "https://dns.he.net/")"
|
response="$(_post "$body" "https://dns.he.net/")"
|
||||||
exit_code="$?"
|
exit_code="$?"
|
||||||
if [ "$exit_code" -eq 0 ]; then
|
if [ "$exit_code" -eq 0 ]; then
|
||||||
_info "TXT record added successfuly."
|
_info "TXT record added successfully."
|
||||||
else
|
else
|
||||||
_err "Couldn't add the TXT record."
|
_err "Couldn't add the TXT record."
|
||||||
fi
|
fi
|
||||||
@ -96,7 +96,7 @@ dns_he_rm() {
|
|||||||
>/dev/null
|
>/dev/null
|
||||||
exit_code="$?"
|
exit_code="$?"
|
||||||
if [ "$exit_code" -eq 0 ]; then
|
if [ "$exit_code" -eq 0 ]; then
|
||||||
_info "Record removed successfuly."
|
_info "Record removed successfully."
|
||||||
else
|
else
|
||||||
_err "Could not clean (remove) up the record. Please go to HE administration interface and clean it by hand."
|
_err "Could not clean (remove) up the record. Please go to HE administration interface and clean it by hand."
|
||||||
return "$exit_code"
|
return "$exit_code"
|
||||||
|
Loading…
Reference in New Issue
Block a user