mirror of
https://github.com/acmesh-official/acme.sh.git
synced 2026-01-07 23:28:20 +08:00
Merge pull request #6745 from acmesh-official/dev
Some checks failed
DNS / CheckToken (push) Has been cancelled
DragonFlyBSD / DragonFlyBSD (, , , LetsEncrypt.org_test, (STAGING)) (push) Has been cancelled
FreeBSD / FreeBSD (, , , LetsEncrypt.org_test, (STAGING)) (push) Has been cancelled
FreeBSD / FreeBSD (1, , , , LetsEncrypt.org_test, (STAGING)) (push) Has been cancelled
Linux / Linux (almalinux:latest) (push) Has been cancelled
Linux / Linux (alpine:latest) (push) Has been cancelled
Linux / Linux (archlinux:latest) (push) Has been cancelled
Linux / Linux (debian:latest) (push) Has been cancelled
Linux / Linux (fedora:latest) (push) Has been cancelled
Linux / Linux (gentoo/stage3) (push) Has been cancelled
Linux / Linux (kalilinux/kali) (push) Has been cancelled
Linux / Linux (opensuse/leap:latest) (push) Has been cancelled
Linux / Linux (oraclelinux:8) (push) Has been cancelled
Linux / Linux (ubuntu:latest) (push) Has been cancelled
MacOS / MacOS (, , , LetsEncrypt.org_test, (STAGING)) (push) Has been cancelled
NetBSD / NetBSD (, , , LetsEncrypt.org_test, (STAGING)) (push) Has been cancelled
Omnios / Omnios (, , , LetsEncrypt.org_test, (STAGING)) (push) Has been cancelled
Omnios / Omnios (1, , , , LetsEncrypt.org_test, (STAGING)) (push) Has been cancelled
OpenBSD / OpenBSD (, , , LetsEncrypt.org_test, (STAGING)) (push) Has been cancelled
OpenBSD / OpenBSD (1, , , , LetsEncrypt.org_test, (STAGING)) (push) Has been cancelled
OpenIndiana / OpenIndiana (, , , LetsEncrypt.org_test, (STAGING)) (push) Has been cancelled
OpenIndiana / OpenIndiana (1, , , , LetsEncrypt.org_test, (STAGING)) (push) Has been cancelled
PebbleStrict / PebbleStrict (push) Has been cancelled
PebbleStrict / PebbleStrict_IPCert (push) Has been cancelled
Solaris / Solaris (, , , LetsEncrypt.org_test, (STAGING)) (push) Has been cancelled
Solaris / Solaris (1, , , , LetsEncrypt.org_test, (STAGING)) (push) Has been cancelled
Ubuntu / Ubuntu (, , , LetsEncrypt.org_test, (STAGING)) (push) Has been cancelled
Ubuntu / Ubuntu (1, , , , LetsEncrypt.org_test, (STAGING)) (push) Has been cancelled
Ubuntu / Ubuntu (Smallstep Intermediate CA, Smallstep Intermediate CA, , 1, https://localhost:9000/acme/acme/directory, ) (push) Has been cancelled
Ubuntu / Ubuntu (Smallstep Intermediate CA, Smallstep Intermediate CA, , 1, https://localhost:9000/acme/acme/directory, 1, , 172.17.0.1) (push) Has been cancelled
Ubuntu / Ubuntu (ZeroSSL RSA Domain Secure Site CA, ZeroSSL ECC Domain Secure Site CA, githubtest@acme.sh, ZeroSSL.com, ) (push) Has been cancelled
Windows / Windows (, , , LetsEncrypt.org_test, (STAGING)) (push) Has been cancelled
Build DockerHub / CheckToken (push) Has been cancelled
Shellcheck / ShellCheck (push) Has been cancelled
Shellcheck / shfmt (push) Has been cancelled
DNS / Fail (push) Has been cancelled
DNS / Docker (push) Has been cancelled
DNS / MacOS (push) Has been cancelled
DNS / Windows (push) Has been cancelled
DNS / FreeBSD (push) Has been cancelled
DNS / OpenBSD (push) Has been cancelled
DNS / NetBSD (push) Has been cancelled
DNS / DragonFlyBSD (push) Has been cancelled
DNS / Solaris (push) Has been cancelled
DNS / Omnios (push) Has been cancelled
DNS / OpenIndiana (push) Has been cancelled
Build DockerHub / build (push) Has been cancelled
Some checks failed
DNS / CheckToken (push) Has been cancelled
DragonFlyBSD / DragonFlyBSD (, , , LetsEncrypt.org_test, (STAGING)) (push) Has been cancelled
FreeBSD / FreeBSD (, , , LetsEncrypt.org_test, (STAGING)) (push) Has been cancelled
FreeBSD / FreeBSD (1, , , , LetsEncrypt.org_test, (STAGING)) (push) Has been cancelled
Linux / Linux (almalinux:latest) (push) Has been cancelled
Linux / Linux (alpine:latest) (push) Has been cancelled
Linux / Linux (archlinux:latest) (push) Has been cancelled
Linux / Linux (debian:latest) (push) Has been cancelled
Linux / Linux (fedora:latest) (push) Has been cancelled
Linux / Linux (gentoo/stage3) (push) Has been cancelled
Linux / Linux (kalilinux/kali) (push) Has been cancelled
Linux / Linux (opensuse/leap:latest) (push) Has been cancelled
Linux / Linux (oraclelinux:8) (push) Has been cancelled
Linux / Linux (ubuntu:latest) (push) Has been cancelled
MacOS / MacOS (, , , LetsEncrypt.org_test, (STAGING)) (push) Has been cancelled
NetBSD / NetBSD (, , , LetsEncrypt.org_test, (STAGING)) (push) Has been cancelled
Omnios / Omnios (, , , LetsEncrypt.org_test, (STAGING)) (push) Has been cancelled
Omnios / Omnios (1, , , , LetsEncrypt.org_test, (STAGING)) (push) Has been cancelled
OpenBSD / OpenBSD (, , , LetsEncrypt.org_test, (STAGING)) (push) Has been cancelled
OpenBSD / OpenBSD (1, , , , LetsEncrypt.org_test, (STAGING)) (push) Has been cancelled
OpenIndiana / OpenIndiana (, , , LetsEncrypt.org_test, (STAGING)) (push) Has been cancelled
OpenIndiana / OpenIndiana (1, , , , LetsEncrypt.org_test, (STAGING)) (push) Has been cancelled
PebbleStrict / PebbleStrict (push) Has been cancelled
PebbleStrict / PebbleStrict_IPCert (push) Has been cancelled
Solaris / Solaris (, , , LetsEncrypt.org_test, (STAGING)) (push) Has been cancelled
Solaris / Solaris (1, , , , LetsEncrypt.org_test, (STAGING)) (push) Has been cancelled
Ubuntu / Ubuntu (, , , LetsEncrypt.org_test, (STAGING)) (push) Has been cancelled
Ubuntu / Ubuntu (1, , , , LetsEncrypt.org_test, (STAGING)) (push) Has been cancelled
Ubuntu / Ubuntu (Smallstep Intermediate CA, Smallstep Intermediate CA, , 1, https://localhost:9000/acme/acme/directory, ) (push) Has been cancelled
Ubuntu / Ubuntu (Smallstep Intermediate CA, Smallstep Intermediate CA, , 1, https://localhost:9000/acme/acme/directory, 1, , 172.17.0.1) (push) Has been cancelled
Ubuntu / Ubuntu (ZeroSSL RSA Domain Secure Site CA, ZeroSSL ECC Domain Secure Site CA, githubtest@acme.sh, ZeroSSL.com, ) (push) Has been cancelled
Windows / Windows (, , , LetsEncrypt.org_test, (STAGING)) (push) Has been cancelled
Build DockerHub / CheckToken (push) Has been cancelled
Shellcheck / ShellCheck (push) Has been cancelled
Shellcheck / shfmt (push) Has been cancelled
DNS / Fail (push) Has been cancelled
DNS / Docker (push) Has been cancelled
DNS / MacOS (push) Has been cancelled
DNS / Windows (push) Has been cancelled
DNS / FreeBSD (push) Has been cancelled
DNS / OpenBSD (push) Has been cancelled
DNS / NetBSD (push) Has been cancelled
DNS / DragonFlyBSD (push) Has been cancelled
DNS / Solaris (push) Has been cancelled
DNS / Omnios (push) Has been cancelled
DNS / OpenIndiana (push) Has been cancelled
Build DockerHub / build (push) Has been cancelled
sync
This commit is contained in:
44
.github/workflows/DNS.yml
vendored
44
.github/workflows/DNS.yml
vendored
@@ -251,7 +251,11 @@ jobs:
|
||||
fi
|
||||
cd ../acmetest
|
||||
./letest.sh
|
||||
|
||||
- name: onError
|
||||
if: ${{ failure() }}
|
||||
run: |
|
||||
echo "See how to debug in VM:"
|
||||
echo "https://github.com/acmesh-official/acme.sh/wiki/debug-in-VM"
|
||||
|
||||
|
||||
|
||||
@@ -302,7 +306,11 @@ jobs:
|
||||
fi
|
||||
cd ../acmetest
|
||||
./letest.sh
|
||||
|
||||
- name: onError
|
||||
if: ${{ failure() }}
|
||||
run: |
|
||||
echo "See how to debug in VM:"
|
||||
echo "https://github.com/acmesh-official/acme.sh/wiki/debug-in-VM"
|
||||
|
||||
|
||||
|
||||
@@ -354,7 +362,11 @@ jobs:
|
||||
fi
|
||||
cd ../acmetest
|
||||
./letest.sh
|
||||
|
||||
- name: onError
|
||||
if: ${{ failure() }}
|
||||
run: |
|
||||
echo "See how to debug in VM:"
|
||||
echo "https://github.com/acmesh-official/acme.sh/wiki/debug-in-VM"
|
||||
|
||||
|
||||
|
||||
@@ -406,7 +418,11 @@ jobs:
|
||||
fi
|
||||
cd ../acmetest
|
||||
./letest.sh
|
||||
|
||||
- name: onError
|
||||
if: ${{ failure() }}
|
||||
run: |
|
||||
echo "See how to debug in VM:"
|
||||
echo "https://github.com/acmesh-official/acme.sh/wiki/debug-in-VM"
|
||||
|
||||
|
||||
|
||||
@@ -464,6 +480,11 @@ jobs:
|
||||
fi
|
||||
cd ../acmetest
|
||||
./letest.sh
|
||||
- name: onError
|
||||
if: ${{ failure() }}
|
||||
run: |
|
||||
echo "See how to debug in VM:"
|
||||
echo "https://github.com/acmesh-official/acme.sh/wiki/debug-in-VM"
|
||||
|
||||
|
||||
Omnios:
|
||||
@@ -513,6 +534,12 @@ jobs:
|
||||
fi
|
||||
cd ../acmetest
|
||||
./letest.sh
|
||||
- name: onError
|
||||
if: ${{ failure() }}
|
||||
run: |
|
||||
echo "See how to debug in VM:"
|
||||
echo "https://github.com/acmesh-official/acme.sh/wiki/debug-in-VM"
|
||||
|
||||
|
||||
|
||||
OpenIndiana:
|
||||
@@ -539,7 +566,7 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Clone acmetest
|
||||
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
|
||||
- uses: vmactions/openindiana-vm@v0
|
||||
- uses: vmactions/openindiana-vm@v1
|
||||
with:
|
||||
envs: 'TEST_DNS TestingDomain TEST_DNS_NO_WILDCARD TEST_DNS_NO_SUBDOMAIN TEST_DNS_SLEEP CASE TEST_LOCAL DEBUG http_proxy https_proxy HTTPS_INSECURE TokenName1 TokenName2 TokenName3 TokenName4 TokenName5 ${{ secrets.TokenName1}} ${{ secrets.TokenName2}} ${{ secrets.TokenName3}} ${{ secrets.TokenName4}} ${{ secrets.TokenName5}}'
|
||||
sync: nfs
|
||||
@@ -562,5 +589,12 @@ jobs:
|
||||
fi
|
||||
cd ../acmetest
|
||||
./letest.sh
|
||||
- name: onError
|
||||
if: ${{ failure() }}
|
||||
run: |
|
||||
echo "See how to debug in VM:"
|
||||
echo "https://github.com/acmesh-official/acme.sh/wiki/debug-in-VM"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
6
.github/workflows/DragonFlyBSD.yml
vendored
6
.github/workflows/DragonFlyBSD.yml
vendored
@@ -67,5 +67,9 @@ jobs:
|
||||
run: |
|
||||
cd ../acmetest \
|
||||
&& ./letest.sh
|
||||
|
||||
- name: onError
|
||||
if: ${{ failure() }}
|
||||
run: |
|
||||
echo "See how to debug in VM:"
|
||||
echo "https://github.com/acmesh-official/acme.sh/wiki/debug-in-VM"
|
||||
|
||||
|
||||
6
.github/workflows/FreeBSD.yml
vendored
6
.github/workflows/FreeBSD.yml
vendored
@@ -72,5 +72,9 @@ jobs:
|
||||
run: |
|
||||
cd ../acmetest \
|
||||
&& ./letest.sh
|
||||
|
||||
- name: onError
|
||||
if: ${{ failure() }}
|
||||
run: |
|
||||
echo "See how to debug in VM:"
|
||||
echo "https://github.com/acmesh-official/acme.sh/wiki/debug-in-VM"
|
||||
|
||||
|
||||
8
.github/workflows/NetBSD.yml
vendored
8
.github/workflows/NetBSD.yml
vendored
@@ -67,5 +67,9 @@ jobs:
|
||||
run: |
|
||||
cd ../acmetest \
|
||||
&& ./letest.sh
|
||||
|
||||
|
||||
- name: onError
|
||||
if: ${{ failure() }}
|
||||
run: |
|
||||
echo "See how to debug in VM:"
|
||||
echo "https://github.com/acmesh-official/acme.sh/wiki/debug-in-VM"
|
||||
|
||||
|
||||
6
.github/workflows/Omnios.yml
vendored
6
.github/workflows/Omnios.yml
vendored
@@ -71,5 +71,9 @@ jobs:
|
||||
run: |
|
||||
cd ../acmetest \
|
||||
&& ./letest.sh
|
||||
|
||||
- name: onError
|
||||
if: ${{ failure() }}
|
||||
run: |
|
||||
echo "See how to debug in VM:"
|
||||
echo "https://github.com/acmesh-official/acme.sh/wiki/debug-in-VM"
|
||||
|
||||
|
||||
6
.github/workflows/OpenBSD.yml
vendored
6
.github/workflows/OpenBSD.yml
vendored
@@ -72,5 +72,9 @@ jobs:
|
||||
run: |
|
||||
cd ../acmetest \
|
||||
&& ./letest.sh
|
||||
|
||||
- name: onError
|
||||
if: ${{ failure() }}
|
||||
run: |
|
||||
echo "See how to debug in VM:"
|
||||
echo "https://github.com/acmesh-official/acme.sh/wiki/debug-in-VM"
|
||||
|
||||
|
||||
8
.github/workflows/OpenIndiana.yml
vendored
8
.github/workflows/OpenIndiana.yml
vendored
@@ -61,7 +61,7 @@ jobs:
|
||||
run: echo "TestingDomain=${{steps.tunnel.outputs.server}}" >> $GITHUB_ENV
|
||||
- name: Clone acmetest
|
||||
run: cd .. && git clone --depth=1 https://github.com/acmesh-official/acmetest.git && cp -r acme.sh acmetest/
|
||||
- uses: vmactions/openindiana-vm@v0
|
||||
- uses: vmactions/openindiana-vm@v1
|
||||
with:
|
||||
envs: 'TEST_LOCAL TestingDomain TEST_ACME_Server CA_ECDSA CA CA_EMAIL TEST_PREFERRED_CHAIN ACME_USE_WGET'
|
||||
nat: |
|
||||
@@ -71,5 +71,9 @@ jobs:
|
||||
run: |
|
||||
cd ../acmetest \
|
||||
&& ./letest.sh
|
||||
|
||||
- name: onError
|
||||
if: ${{ failure() }}
|
||||
run: |
|
||||
echo "See how to debug in VM:"
|
||||
echo "https://github.com/acmesh-official/acme.sh/wiki/debug-in-VM"
|
||||
|
||||
|
||||
6
.github/workflows/Solaris.yml
vendored
6
.github/workflows/Solaris.yml
vendored
@@ -73,5 +73,9 @@ jobs:
|
||||
run: |
|
||||
cd ../acmetest \
|
||||
&& ./letest.sh
|
||||
|
||||
- name: onError
|
||||
if: ${{ failure() }}
|
||||
run: |
|
||||
echo "See how to debug in VM:"
|
||||
echo "https://github.com/acmesh-official/acme.sh/wiki/debug-in-VM"
|
||||
|
||||
|
||||
56
acme.sh
56
acme.sh
@@ -1466,7 +1466,7 @@ _toPkcs() {
|
||||
${ACME_OPENSSL_BIN:-openssl} pkcs12 -export -out "$_cpfx" -inkey "$_ckey" -in "$_ccert" -certfile "$_cca"
|
||||
fi
|
||||
if [ "$?" = "0" ]; then
|
||||
_savedomainconf "Le_PFXPassword" "$pfxPassword"
|
||||
_savedomainconf "Le_PFXPassword" "$pfxPassword" "base64"
|
||||
fi
|
||||
|
||||
}
|
||||
@@ -2783,6 +2783,7 @@ _clearAPI() {
|
||||
ACME_REVOKE_CERT=""
|
||||
ACME_NEW_NONCE=""
|
||||
ACME_AGREEMENT=""
|
||||
ACME_RENEWAL_INFO=""
|
||||
}
|
||||
|
||||
#server
|
||||
@@ -2827,6 +2828,9 @@ _initAPI() {
|
||||
ACME_AGREEMENT=$(echo "$response" | _egrep_o 'termsOfService" *: *"[^"]*"' | cut -d '"' -f 3)
|
||||
export ACME_AGREEMENT
|
||||
|
||||
ACME_RENEWAL_INFO=$(echo "$response" | _egrep_o 'renewalInfo" *: *"[^"]*"' | cut -d '"' -f 3)
|
||||
export ACME_RENEWAL_INFO
|
||||
|
||||
_debug "ACME_KEY_CHANGE" "$ACME_KEY_CHANGE"
|
||||
_debug "ACME_NEW_AUTHZ" "$ACME_NEW_AUTHZ"
|
||||
_debug "ACME_NEW_ORDER" "$ACME_NEW_ORDER"
|
||||
@@ -2834,6 +2838,7 @@ _initAPI() {
|
||||
_debug "ACME_REVOKE_CERT" "$ACME_REVOKE_CERT"
|
||||
_debug "ACME_AGREEMENT" "$ACME_AGREEMENT"
|
||||
_debug "ACME_NEW_NONCE" "$ACME_NEW_NONCE"
|
||||
_debug "ACME_RENEWAL_INFO" "$ACME_RENEWAL_INFO"
|
||||
if [ "$ACME_NEW_ACCOUNT" ] && [ "$ACME_NEW_ORDER" ]; then
|
||||
return 0
|
||||
fi
|
||||
@@ -4465,7 +4470,7 @@ issue() {
|
||||
Le_NextRenewTime=$(_readdomainconf Le_NextRenewTime)
|
||||
_debug Le_NextRenewTime "$Le_NextRenewTime"
|
||||
if [ -z "$FORCE" ] && [ "$Le_NextRenewTime" ] && [ "$(_time)" -lt "$Le_NextRenewTime" ]; then
|
||||
_valid_to_saved=$(_readdomainconf Le_Valid_to)
|
||||
_valid_to_saved=$(_readdomainconf Le_Valid_To)
|
||||
if [ "$_valid_to_saved" ] && ! _startswith "$_valid_to_saved" "+"; then
|
||||
_info "The domain is set to be valid to: $_valid_to_saved"
|
||||
_info "It cannot be renewed automatically"
|
||||
@@ -5450,10 +5455,10 @@ $_authorizations_map"
|
||||
_savedomainconf "Le_NextRenewTime" "$Le_NextRenewTime"
|
||||
|
||||
#convert to pkcs12
|
||||
Le_PFXPassword="$(_readdomainconf Le_PFXPassword)"
|
||||
if [ "$Le_PFXPassword" ]; then
|
||||
_toPkcs "$CERT_PFX_PATH" "$CERT_KEY_PATH" "$CERT_PATH" "$CA_CERT_PATH" "$Le_PFXPassword"
|
||||
fi
|
||||
export CERT_PFX_PATH
|
||||
|
||||
if [ "$_real_cert$_real_key$_real_ca$_reload_cmd$_real_fullchain" ]; then
|
||||
_savedomainconf "Le_RealCertPath" "$_real_cert"
|
||||
@@ -5563,6 +5568,10 @@ renew() {
|
||||
Le_RenewHook="$(_readdomainconf Le_RenewHook)"
|
||||
Le_Preferred_Chain="$(_readdomainconf Le_Preferred_Chain)"
|
||||
Le_Certificate_Profile="$(_readdomainconf Le_Certificate_Profile)"
|
||||
Le_Valid_From="$(_readdomainconf Le_Valid_From)"
|
||||
Le_Valid_To="$(_readdomainconf Le_Valid_To)"
|
||||
Le_ExtKeyUse="$(_readdomainconf Le_ExtKeyUse)"
|
||||
|
||||
# When renewing from an old version, the empty Le_Keylength means 2048.
|
||||
# Note, do not use DEFAULT_DOMAIN_KEY_LENGTH as that value may change over
|
||||
# time but an empty value implies 2048 specifically.
|
||||
@@ -5744,6 +5753,10 @@ signcsr() {
|
||||
_local_addr="${11}"
|
||||
_challenge_alias="${12}"
|
||||
_preferred_chain="${13}"
|
||||
_valid_f="${14}"
|
||||
_valid_t="${15}"
|
||||
_cert_prof="${16}"
|
||||
_en_key_usage="${17}"
|
||||
|
||||
_csrsubj=$(_readSubjectFromCSR "$_csrfile")
|
||||
if [ "$?" != "0" ]; then
|
||||
@@ -5787,7 +5800,7 @@ signcsr() {
|
||||
_info "Copying CSR to: $CSR_PATH"
|
||||
cp "$_csrfile" "$CSR_PATH"
|
||||
|
||||
issue "$_csrW" "$_csrsubj" "$_csrdomainlist" "$_csrkeylength" "$_real_cert" "$_real_key" "$_real_ca" "$_reload_cmd" "$_real_fullchain" "$_pre_hook" "$_post_hook" "$_renew_hook" "$_local_addr" "$_challenge_alias" "$_preferred_chain"
|
||||
issue "$_csrW" "$_csrsubj" "$_csrdomainlist" "$_csrkeylength" "$_real_cert" "$_real_key" "$_real_ca" "$_reload_cmd" "$_real_fullchain" "$_pre_hook" "$_post_hook" "$_renew_hook" "$_local_addr" "$_challenge_alias" "$_preferred_chain" "$_valid_f" "$_valid_t" "$_cert_prof" "$_en_key_usage"
|
||||
|
||||
}
|
||||
|
||||
@@ -5840,7 +5853,8 @@ list() {
|
||||
if [ -z "$_domain" ]; then
|
||||
printf "%s\n" "Main_Domain${_sep}KeyLength${_sep}SAN_Domains${_sep}Profile${_sep}CA${_sep}Created${_sep}Renew"
|
||||
fi
|
||||
for di in "${CERT_HOME}"/{*.*,*:*}/; do
|
||||
for di in "${CERT_HOME}"/*.* "${CERT_HOME}"/*:*; do
|
||||
[ -d "$di" ] || continue
|
||||
d=$(basename "$di")
|
||||
_debug d "$d"
|
||||
(
|
||||
@@ -6537,6 +6551,36 @@ deactivate() {
|
||||
done
|
||||
}
|
||||
|
||||
#cert
|
||||
_getAKI() {
|
||||
_cert="$1"
|
||||
openssl x509 -in "$_cert" -text -noout | grep "X509v3 Authority Key Identifier" -A 1 | _tail_n 1 | tr -d ' :'
|
||||
}
|
||||
|
||||
#cert
|
||||
_getSerial() {
|
||||
_cert="$1"
|
||||
openssl x509 -in "$_cert" -serial -noout | cut -d = -f 2
|
||||
}
|
||||
|
||||
#cert
|
||||
_get_ARI() {
|
||||
_cert="$1"
|
||||
_aki=$(_getAKI "$_cert")
|
||||
_ser=$(_getSerial "$_cert")
|
||||
_debug2 "_aki" "$_aki"
|
||||
_debug2 "_ser" "$_ser"
|
||||
|
||||
_akiurl="$(echo "$_aki" | _h2b | _base64 | tr -d = | _url_encode)"
|
||||
_debug2 "_akiurl" "$_akiurl"
|
||||
_serurl="$(echo "$_ser" | _h2b | _base64 | tr -d = | _url_encode)"
|
||||
_debug2 "_serurl" "$_serurl"
|
||||
|
||||
_ARI_URL="$ACME_RENEWAL_INFO/$_akiurl.$_serurl"
|
||||
_get "$_ARI_URL"
|
||||
|
||||
}
|
||||
|
||||
# Detect profile file if not specified as environment variable
|
||||
_detect_profile() {
|
||||
if [ -n "$PROFILE" -a -f "$PROFILE" ]; then
|
||||
@@ -8112,7 +8156,7 @@ _process() {
|
||||
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" "$_preferred_chain"
|
||||
signcsr "$_csr" "$_webroot" "$_cert_file" "$_key_file" "$_ca_file" "$_reloadcmd" "$_fullchain_file" "$_pre_hook" "$_post_hook" "$_renew_hook" "$_local_address" "$_challenge_alias" "$_preferred_chain" "$_valid_from" "$_valid_to" "$_certificate_profile" "$_extended_key_usage"
|
||||
;;
|
||||
showcsr)
|
||||
showcsr "$_csr" "$_domain"
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
# export QINIU_CDN_DOMAIN="cdn.example.com"
|
||||
# If you have more than one domain, just
|
||||
# export QINIU_CDN_DOMAIN="cdn1.example.com cdn2.example.com"
|
||||
# Optional: force HTTPS redirect (default: false)
|
||||
# export QINIU_FORCE_HTTPS="true"
|
||||
|
||||
QINIU_API_BASE="https://api.qiniu.com"
|
||||
|
||||
@@ -44,6 +46,12 @@ qiniu_deploy() {
|
||||
QINIU_CDN_DOMAIN="$_cdomain"
|
||||
fi
|
||||
|
||||
if [ -z "$QINIU_FORCE_HTTPS" ]; then
|
||||
QINIU_FORCE_HTTPS="false"
|
||||
else
|
||||
_savedomainconf QINIU_FORCE_HTTPS "$QINIU_FORCE_HTTPS"
|
||||
fi
|
||||
|
||||
## upload certificate
|
||||
string_fullchain=$(sed 's/$/\\n/' "$_cfullchain" | tr -d '\n')
|
||||
string_key=$(sed 's/$/\\n/' "$_ckey" | tr -d '\n')
|
||||
@@ -69,7 +77,7 @@ qiniu_deploy() {
|
||||
_debug certId "$_certId"
|
||||
|
||||
## update domain ssl config
|
||||
update_body="{\"certid\":$_certId,\"forceHttps\":false}"
|
||||
update_body="{\"certid\":$_certId,\"forceHttps\":$QINIU_FORCE_HTTPS}"
|
||||
for domain in $QINIU_CDN_DOMAIN; do
|
||||
update_path="/domain/$domain/httpsconf"
|
||||
update_access_token="$(_make_access_token "$update_path")"
|
||||
|
||||
216
dnsapi/dns_qc.sh
Executable file
216
dnsapi/dns_qc.sh
Executable file
@@ -0,0 +1,216 @@
|
||||
#!/usr/bin/env sh
|
||||
# shellcheck disable=SC2034
|
||||
dns_qc_info='QUIC.cloud
|
||||
Site: quic.cloud
|
||||
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_qc
|
||||
Options:
|
||||
QC_API_KEY QC API Key
|
||||
QC_API_EMAIL Your account email
|
||||
'
|
||||
|
||||
QC_Api="https://api.quic.cloud/v2"
|
||||
|
||||
######## Public functions #####################
|
||||
|
||||
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||
dns_qc_add() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
_debug "Enter dns_qc_add fulldomain: $fulldomain, txtvalue: $txtvalue"
|
||||
QC_API_KEY="${QC_API_KEY:-$(_readaccountconf_mutable QC_API_KEY)}"
|
||||
QC_API_EMAIL="${QC_API_EMAIL:-$(_readaccountconf_mutable QC_API_EMAIL)}"
|
||||
|
||||
if [ "$QC_API_KEY" ]; then
|
||||
_saveaccountconf_mutable QC_API_KEY "$QC_API_KEY"
|
||||
else
|
||||
_err "You didn't specify a QUIC.cloud api key as QC_API_KEY."
|
||||
_err "You can get yours from here https://my.quic.cloud/up/api."
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! _contains "$QC_API_EMAIL" "@"; then
|
||||
_err "It seems that the QC_API_EMAIL=$QC_API_EMAIL is not a valid email address."
|
||||
_err "Please check and retry."
|
||||
return 1
|
||||
fi
|
||||
#save the api key and email to the account conf file.
|
||||
_saveaccountconf_mutable QC_API_EMAIL "$QC_API_EMAIL"
|
||||
|
||||
_debug "First detect the root zone"
|
||||
if ! _get_root "$fulldomain"; then
|
||||
_err "invalid domain during add"
|
||||
return 1
|
||||
fi
|
||||
_debug _domain_id "$_domain_id"
|
||||
_debug _sub_domain "$_sub_domain"
|
||||
_debug _domain "$_domain"
|
||||
|
||||
_debug "Getting txt records"
|
||||
_qc_rest GET "zones/${_domain_id}/records"
|
||||
|
||||
if ! echo "$response" | tr -d " " | grep \"success\":true >/dev/null; then
|
||||
_err "Error failed response from QC GET: $response"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# For wildcard cert, the main root domain and the wildcard domain have the same txt subdomain name, so
|
||||
# we can not use updating anymore.
|
||||
# count=$(printf "%s\n" "$response" | _egrep_o "\"count\":[^,]*" | cut -d : -f 2)
|
||||
# _debug count "$count"
|
||||
# if [ "$count" = "0" ]; then
|
||||
_info "Adding txt record"
|
||||
if _qc_rest POST "zones/$_domain_id/records" "{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":1800}"; then
|
||||
if _contains "$response" "$txtvalue"; then
|
||||
_info "Added txt record, OK"
|
||||
return 0
|
||||
elif _contains "$response" "Same record already exists"; then
|
||||
_info "txt record already exists, OK"
|
||||
return 0
|
||||
else
|
||||
_err "Add txt record error: $response"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
_err "Add txt record error: POST failed: $response"
|
||||
return 1
|
||||
|
||||
}
|
||||
|
||||
#fulldomain txtvalue
|
||||
dns_qc_rm() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
_debug "Enter dns_qc_rm fulldomain: $fulldomain, txtvalue: $txtvalue"
|
||||
QC_API_KEY="${QC_API_KEY:-$(_readaccountconf_mutable QC_API_KEY)}"
|
||||
QC_API_EMAIL="${QC_API_EMAIL:-$(_readaccountconf_mutable QC_API_EMAIL)}"
|
||||
|
||||
_debug "First detect the root zone"
|
||||
if ! _get_root "$fulldomain"; then
|
||||
_err "invalid domain during rm"
|
||||
return 1
|
||||
fi
|
||||
_debug _domain_id "$_domain_id"
|
||||
_debug _sub_domain "$_sub_domain"
|
||||
_debug _domain "$_domain"
|
||||
|
||||
_debug "Getting txt records"
|
||||
_qc_rest GET "zones/${_domain_id}/records"
|
||||
|
||||
if ! echo "$response" | tr -d " " | grep \"success\":true >/dev/null; then
|
||||
_err "Error rm GET response: $response"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug "Pre-jq response:" "$response"
|
||||
# Do not use jq or subsequent code
|
||||
#response=$(echo "$response" | jq ".result[] | select(.id) | select(.content == \"$txtvalue\") | select(.type == \"TXT\")")
|
||||
#_debug "get txt response" "$response"
|
||||
#if [ "${response}" = "" ]; then
|
||||
# _info "Don't need to remove txt records."
|
||||
# return 0
|
||||
#fi
|
||||
#record_id=$(echo "$response" | grep \"id\" | awk -F ' ' '{print $2}' | sed 's/,$//')
|
||||
#_debug "txt record_id" "$record_id"
|
||||
#Instead of jq
|
||||
array=$(echo "$response" | grep -o '\[[^]]*\]' | sed 's/^\[\(.*\)\]$/\1/')
|
||||
if [ -z "$array" ]; then
|
||||
_err "Expected array in QC response: $response"
|
||||
return 1
|
||||
fi
|
||||
# Temporary file to hold matched content (one per line)
|
||||
tmpfile=$(_mktemp)
|
||||
echo "$array" | grep -o '{[^}]*}' | sed 's/^{//;s/}$//' >"$tmpfile"
|
||||
record_id=""
|
||||
|
||||
while IFS= read -r obj || [ -n "$obj" ]; do
|
||||
if echo "$obj" | grep -q '"TXT"' && echo "$obj" | grep -q '"id"' && echo "$obj" | grep -q "$txtvalue"; then
|
||||
_debug "response includes" "$obj"
|
||||
record_id=$(echo "$obj" | sed 's/^\"id\":\([0-9]\+\).*/\1/')
|
||||
break
|
||||
fi
|
||||
done <"$tmpfile"
|
||||
|
||||
rm "$tmpfile"
|
||||
|
||||
if [ -z "$record_id" ]; then
|
||||
_info "TXT record, or $txtvalue not found, nothing to remove"
|
||||
return 0
|
||||
fi
|
||||
|
||||
#End of jq replacement
|
||||
if ! _qc_rest DELETE "zones/$_domain_id/records/$record_id"; then
|
||||
_info "Delete txt record error."
|
||||
return 1
|
||||
fi
|
||||
|
||||
_info "TXT Record ID: $record_id successfully deleted"
|
||||
return 0
|
||||
|
||||
}
|
||||
|
||||
#################### Private functions below ##################################
|
||||
#_acme-challenge.www.domain.com
|
||||
#returns
|
||||
# _sub_domain=_acme-challenge.www
|
||||
# _domain=domain.com
|
||||
# _domain_id=sdjkglgdfewsdfg
|
||||
_get_root() {
|
||||
domain=$1
|
||||
i=1
|
||||
p=1
|
||||
|
||||
h=$(printf "%s" "$domain" | cut -d . -f2-)
|
||||
_debug h "$h"
|
||||
if [ -z "$h" ]; then
|
||||
_err "$h ($domain) is an invalid domain"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! _qc_rest GET "zones"; then
|
||||
_err "qc_rest failed"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if _contains "$response" "\"name\":\"$h\"" || _contains "$response" "\"name\":\"$h.\""; then
|
||||
_domain_id=$h
|
||||
if [ "$_domain_id" ]; then
|
||||
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-"$p")
|
||||
_domain=$h
|
||||
return 0
|
||||
fi
|
||||
_err "Empty domain_id $h"
|
||||
return 1
|
||||
fi
|
||||
_err "Missing domain_id $h"
|
||||
return 1
|
||||
}
|
||||
|
||||
_qc_rest() {
|
||||
m=$1
|
||||
ep="$2"
|
||||
data="$3"
|
||||
_debug "$ep"
|
||||
|
||||
email_trimmed=$(echo "$QC_API_EMAIL" | tr -d '"')
|
||||
token_trimmed=$(echo "$QC_API_KEY" | tr -d '"')
|
||||
|
||||
export _H1="Content-Type: application/json"
|
||||
export _H2="X-Auth-Email: $email_trimmed"
|
||||
export _H3="X-Auth-Key: $token_trimmed"
|
||||
|
||||
if [ "$m" != "GET" ]; then
|
||||
_debug data "$data"
|
||||
response="$(_post "$data" "$QC_Api/$ep" "" "$m")"
|
||||
else
|
||||
response="$(_get "$QC_Api/$ep")"
|
||||
fi
|
||||
|
||||
if [ "$?" != "0" ]; then
|
||||
_err "error $ep"
|
||||
return 1
|
||||
fi
|
||||
_debug2 response "$response"
|
||||
return 0
|
||||
}
|
||||
229
dnsapi/dns_virakcloud.sh
Executable file
229
dnsapi/dns_virakcloud.sh
Executable file
@@ -0,0 +1,229 @@
|
||||
#!/usr/bin/env sh
|
||||
# shellcheck disable=SC2034
|
||||
dns_virakcloud_info='VirakCloud DNS API
|
||||
Site: VirakCloud.com
|
||||
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_virakcloud
|
||||
Options:
|
||||
VIRAKCLOUD_API_TOKEN VirakCloud API Bearer Token
|
||||
'
|
||||
|
||||
VIRAKCLOUD_API_URL="https://public-api.virakcloud.com/dns"
|
||||
|
||||
######## Public functions #####################
|
||||
|
||||
#Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs"
|
||||
#Used to add txt record
|
||||
dns_virakcloud_add() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
VIRAKCLOUD_API_TOKEN="${VIRAKCLOUD_API_TOKEN:-$(_readaccountconf_mutable VIRAKCLOUD_API_TOKEN)}"
|
||||
|
||||
if [ -z "$VIRAKCLOUD_API_TOKEN" ]; then
|
||||
_err "You haven't configured your VirakCloud API token yet."
|
||||
_err "Please set VIRAKCLOUD_API_TOKEN environment variable or run:"
|
||||
_err " export VIRAKCLOUD_API_TOKEN=\"your-api-token\""
|
||||
return 1
|
||||
fi
|
||||
|
||||
_saveaccountconf_mutable VIRAKCLOUD_API_TOKEN "$VIRAKCLOUD_API_TOKEN"
|
||||
|
||||
_debug "First detect the root zone"
|
||||
if ! _get_root "$fulldomain"; then
|
||||
http_code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\r\n")"
|
||||
if [ "$http_code" = "401" ]; then
|
||||
return 1
|
||||
fi
|
||||
_err "Invalid domain"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug _domain "$_domain"
|
||||
_debug fulldomain "$fulldomain"
|
||||
|
||||
_info "Adding TXT record"
|
||||
|
||||
if _virakcloud_rest POST "domains/${_domain}/records" "{\"record\":\"${fulldomain}\",\"type\":\"TXT\",\"ttl\":3600,\"content\":\"${txtvalue}\"}"; then
|
||||
if echo "$response" | grep -q "success" || echo "$response" | grep -q "\"data\""; then
|
||||
_info "Added, OK"
|
||||
return 0
|
||||
elif echo "$response" | grep -q "already exists" || echo "$response" | grep -q "duplicate"; then
|
||||
_info "Record already exists, OK"
|
||||
return 0
|
||||
else
|
||||
_err "Add TXT record error."
|
||||
_err "Response: $response"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
_err "Add TXT record error."
|
||||
return 1
|
||||
}
|
||||
|
||||
#Usage: fulldomain txtvalue
|
||||
#Used to remove the txt record after validation
|
||||
dns_virakcloud_rm() {
|
||||
fulldomain=$1
|
||||
txtvalue=$2
|
||||
|
||||
VIRAKCLOUD_API_TOKEN="${VIRAKCLOUD_API_TOKEN:-$(_readaccountconf_mutable VIRAKCLOUD_API_TOKEN)}"
|
||||
|
||||
if [ -z "$VIRAKCLOUD_API_TOKEN" ]; then
|
||||
_err "You haven't configured your VirakCloud API token yet."
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug "First detect the root zone"
|
||||
if ! _get_root "$fulldomain"; then
|
||||
http_code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\r\n")"
|
||||
if [ "$http_code" = "401" ]; then
|
||||
return 1
|
||||
fi
|
||||
_err "Invalid domain"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug _domain "$_domain"
|
||||
_debug fulldomain "$fulldomain"
|
||||
_debug txtvalue "$txtvalue"
|
||||
|
||||
_info "Removing TXT record"
|
||||
|
||||
_debug "Getting list of records to find content ID"
|
||||
if ! _virakcloud_rest GET "domains/${_domain}/records" ""; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug2 "Records response" "$response"
|
||||
|
||||
contentid=""
|
||||
# Extract innermost objects (content objects) which look like {"id":"...","content_raw":"..."}
|
||||
# We filter for the one containing txtvalue
|
||||
|
||||
target_obj=$(echo "$response" | grep -o '{[^}]*}' | grep "$txtvalue" | _head_n 1)
|
||||
|
||||
if [ -n "$target_obj" ]; then
|
||||
contentid=$(echo "$target_obj" | _egrep_o '"id":"[^"]*"' | cut -d '"' -f 4)
|
||||
fi
|
||||
|
||||
if [ -z "$contentid" ]; then
|
||||
_debug "Could not find matching record ID in response"
|
||||
_info "Record not found, may have been already removed"
|
||||
return 0
|
||||
fi
|
||||
|
||||
_debug contentid "$contentid"
|
||||
|
||||
if _virakcloud_rest DELETE "domains/${_domain}/records/${fulldomain}/TXT/${contentid}" ""; then
|
||||
if echo "$response" | grep -q "success" || [ -z "$response" ]; then
|
||||
_info "Removed, OK"
|
||||
return 0
|
||||
elif echo "$response" | grep -q "not found" || echo "$response" | grep -q "404"; then
|
||||
_info "Record not found, OK"
|
||||
return 0
|
||||
else
|
||||
_err "Remove TXT record error."
|
||||
_err "Response: $response"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
_err "Remove TXT record error."
|
||||
return 1
|
||||
}
|
||||
|
||||
#################### Private functions below ##################################
|
||||
|
||||
#_acme-challenge.www.domain.com
|
||||
#returns
|
||||
# _domain=domain.com
|
||||
_get_root() {
|
||||
domain=$1
|
||||
i=1
|
||||
p=1
|
||||
|
||||
# Optimization: skip _acme-challenge subdomain to avoid 422 errors
|
||||
if echo "$domain" | grep -q "^_acme-challenge."; then
|
||||
i=2
|
||||
fi
|
||||
|
||||
while true; do
|
||||
h=$(printf "%s" "$domain" | cut -d . -f "$i"-100)
|
||||
_debug h "$h"
|
||||
|
||||
if [ -z "$h" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! _virakcloud_rest GET "domains/$h" ""; then
|
||||
http_code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\r\n")"
|
||||
if [ "$http_code" = "401" ]; then
|
||||
return 1
|
||||
fi
|
||||
p=$i
|
||||
i=$(_math "$i" + 1)
|
||||
continue
|
||||
fi
|
||||
|
||||
if echo "$response" | grep -q "\"name\""; then
|
||||
_domain="$h"
|
||||
return 0
|
||||
fi
|
||||
|
||||
p=$i
|
||||
i=$(_math "$i" + 1)
|
||||
done
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
_virakcloud_rest() {
|
||||
m=$1
|
||||
ep="$2"
|
||||
data="$3"
|
||||
|
||||
_debug "$ep"
|
||||
|
||||
export _H1="Content-Type: application/json"
|
||||
export _H2="Authorization: Bearer $VIRAKCLOUD_API_TOKEN"
|
||||
|
||||
if [ "$m" != "GET" ]; then
|
||||
_debug data "$data"
|
||||
response="$(_post "$data" "$VIRAKCLOUD_API_URL/$ep" "" "$m")"
|
||||
else
|
||||
response="$(_get "$VIRAKCLOUD_API_URL/$ep")"
|
||||
fi
|
||||
|
||||
_ret="$?"
|
||||
|
||||
if [ "$_ret" != "0" ]; then
|
||||
_err "error on $m $ep"
|
||||
return 1
|
||||
fi
|
||||
|
||||
http_code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\r\n")"
|
||||
_debug "http response code" "$http_code"
|
||||
|
||||
if [ "$http_code" = "401" ]; then
|
||||
_err "VirakCloud API returned 401 Unauthorized."
|
||||
_err "Your VIRAKCLOUD_API_TOKEN is invalid or expired."
|
||||
_err "Please check your API token and try again."
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ "$http_code" = "403" ]; then
|
||||
_err "VirakCloud API returned 403 Forbidden."
|
||||
_err "Your API token does not have permission to access this resource."
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ -n "$http_code" ] && [ "$http_code" -ge 400 ]; then
|
||||
_err "VirakCloud API error. HTTP code: $http_code"
|
||||
_err "Response: $response"
|
||||
return 1
|
||||
fi
|
||||
|
||||
_debug2 response "$response"
|
||||
return 0
|
||||
}
|
||||
@@ -46,8 +46,8 @@ pushover_send() {
|
||||
fi
|
||||
|
||||
export _H1="Content-Type: application/json"
|
||||
_content="$(printf "*%s*\n" "$_content" | _json_encode)"
|
||||
_subject="$(printf "*%s*\n" "$_subject" | _json_encode)"
|
||||
_content="$(printf "%s" "$_content" | _json_encode)"
|
||||
_subject="$(printf "%s" "$_subject" | _json_encode)"
|
||||
_data="{\"token\": \"$PUSHOVER_TOKEN\",\"user\": \"$PUSHOVER_USER\",\"title\": \"$_subject\",\"message\": \"$_content\",\"sound\": \"$PUSHOVER_SOUND\", \"device\": \"$PUSHOVER_DEVICE\", \"priority\": \"$PUSHOVER_PRIORITY\"}"
|
||||
|
||||
response="$(_post "$_data" "$PUSHOVER_URI")"
|
||||
|
||||
Reference in New Issue
Block a user