mirror of
https://github.com/acmesh-official/acme.sh.git
synced 2025-04-29 18:04:14 +00:00
Merge branch 'acmesh-official:dev' into dev
This commit is contained in:
commit
ca9dd69820
2
acme.sh
2
acme.sh
@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env sh
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
VER=3.1.1
|
VER=3.1.2
|
||||||
|
|
||||||
PROJECT_NAME="acme.sh"
|
PROJECT_NAME="acme.sh"
|
||||||
|
|
||||||
|
@ -80,10 +80,15 @@ vault_deploy() {
|
|||||||
if [ -n "$VAULT_RENEW_TOKEN" ]; then
|
if [ -n "$VAULT_RENEW_TOKEN" ]; then
|
||||||
URL="$VAULT_ADDR/v1/auth/token/renew-self"
|
URL="$VAULT_ADDR/v1/auth/token/renew-self"
|
||||||
_info "Renew the Vault token to default TTL"
|
_info "Renew the Vault token to default TTL"
|
||||||
if ! _post "" "$URL" >/dev/null; then
|
_response=$(_post "" "$URL")
|
||||||
|
if [ "$?" != "0" ]; then
|
||||||
_err "Failed to renew the Vault token"
|
_err "Failed to renew the Vault token"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
if echo "$_response" | grep -q '"errors":\['; then
|
||||||
|
_err "Failed to renew the Vault token: $_response"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
URL="$VAULT_ADDR/v1/$VAULT_PREFIX/$_cdomain"
|
URL="$VAULT_ADDR/v1/$VAULT_PREFIX/$_cdomain"
|
||||||
@ -91,29 +96,85 @@ vault_deploy() {
|
|||||||
if [ -n "$VAULT_FABIO_MODE" ]; then
|
if [ -n "$VAULT_FABIO_MODE" ]; then
|
||||||
_info "Writing certificate and key to $URL in Fabio mode"
|
_info "Writing certificate and key to $URL in Fabio mode"
|
||||||
if [ -n "$VAULT_KV_V2" ]; then
|
if [ -n "$VAULT_KV_V2" ]; then
|
||||||
_post "{ \"data\": {\"cert\": \"$_cfullchain\", \"key\": \"$_ckey\"} }" "$URL" >/dev/null || return 1
|
_response=$(_post "{ \"data\": {\"cert\": \"$_cfullchain\", \"key\": \"$_ckey\"} }" "$URL")
|
||||||
|
if [ "$?" != "0" ]; then return 1; fi
|
||||||
|
if echo "$_response" | grep -q '"errors":\['; then
|
||||||
|
_err "Vault error: $_response"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
_post "{\"cert\": \"$_cfullchain\", \"key\": \"$_ckey\"}" "$URL" >/dev/null || return 1
|
_response=$(_post "{\"cert\": \"$_cfullchain\", \"key\": \"$_ckey\"}" "$URL")
|
||||||
|
if [ "$?" != "0" ]; then return 1; fi
|
||||||
|
if echo "$_response" | grep -q '"errors":\['; then
|
||||||
|
_err "Vault error: $_response"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
if [ -n "$VAULT_KV_V2" ]; then
|
if [ -n "$VAULT_KV_V2" ]; then
|
||||||
_info "Writing certificate to $URL/cert.pem"
|
_info "Writing certificate to $URL/cert.pem"
|
||||||
_post "{\"data\": {\"value\": \"$_ccert\"}}" "$URL/cert.pem" >/dev/null || return 1
|
_response=$(_post "{\"data\": {\"value\": \"$_ccert\"}}" "$URL/cert.pem")
|
||||||
|
if [ "$?" != "0" ]; then return 1; fi
|
||||||
|
if echo "$_response" | grep -q '"errors":\['; then
|
||||||
|
_err "Vault error writing cert.pem: $_response"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
_info "Writing key to $URL/cert.key"
|
_info "Writing key to $URL/cert.key"
|
||||||
_post "{\"data\": {\"value\": \"$_ckey\"}}" "$URL/cert.key" >/dev/null || return 1
|
_response=$(_post "{\"data\": {\"value\": \"$_ckey\"}}" "$URL/cert.key")
|
||||||
|
if [ "$?" != "0" ]; then return 1; fi
|
||||||
|
if echo "$_response" | grep -q '"errors":\['; then
|
||||||
|
_err "Vault error writing cert.key: $_response"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
_info "Writing CA certificate to $URL/ca.pem"
|
_info "Writing CA certificate to $URL/ca.pem"
|
||||||
_post "{\"data\": {\"value\": \"$_cca\"}}" "$URL/ca.pem" >/dev/null || return 1
|
_response=$(_post "{\"data\": {\"value\": \"$_cca\"}}" "$URL/ca.pem")
|
||||||
|
if [ "$?" != "0" ]; then return 1; fi
|
||||||
|
if echo "$_response" | grep -q '"errors":\['; then
|
||||||
|
_err "Vault error writing ca.pem: $_response"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
_info "Writing full-chain certificate to $URL/fullchain.pem"
|
_info "Writing full-chain certificate to $URL/fullchain.pem"
|
||||||
_post "{\"data\": {\"value\": \"$_cfullchain\"}}" "$URL/fullchain.pem" >/dev/null || return 1
|
_response=$(_post "{\"data\": {\"value\": \"$_cfullchain\"}}" "$URL/fullchain.pem")
|
||||||
|
if [ "$?" != "0" ]; then return 1; fi
|
||||||
|
if echo "$_response" | grep -q '"errors":\['; then
|
||||||
|
_err "Vault error writing fullchain.pem: $_response"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
_info "Writing certificate to $URL/cert.pem"
|
_info "Writing certificate to $URL/cert.pem"
|
||||||
_post "{\"value\": \"$_ccert\"}" "$URL/cert.pem" >/dev/null || return 1
|
_response=$(_post "{\"value\": \"$_ccert\"}" "$URL/cert.pem")
|
||||||
|
if [ "$?" != "0" ]; then return 1; fi
|
||||||
|
if echo "$_response" | grep -q '"errors":\['; then
|
||||||
|
_err "Vault error writing cert.pem: $_response"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
_info "Writing key to $URL/cert.key"
|
_info "Writing key to $URL/cert.key"
|
||||||
_post "{\"value\": \"$_ckey\"}" "$URL/cert.key" >/dev/null || return 1
|
_response=$(_post "{\"value\": \"$_ckey\"}" "$URL/cert.key")
|
||||||
|
if [ "$?" != "0" ]; then return 1; fi
|
||||||
|
if echo "$_response" | grep -q '"errors":\['; then
|
||||||
|
_err "Vault error writing cert.key: $_response"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
_info "Writing CA certificate to $URL/ca.pem"
|
_info "Writing CA certificate to $URL/ca.pem"
|
||||||
_post "{\"value\": \"$_cca\"}" "$URL/ca.pem" >/dev/null || return 1
|
_response=$(_post "{\"value\": \"$_cca\"}" "$URL/ca.pem")
|
||||||
|
if [ "$?" != "0" ]; then return 1; fi
|
||||||
|
if echo "$_response" | grep -q '"errors":\['; then
|
||||||
|
_err "Vault error writing ca.pem: $_response"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
_info "Writing full-chain certificate to $URL/fullchain.pem"
|
_info "Writing full-chain certificate to $URL/fullchain.pem"
|
||||||
_post "{\"value\": \"$_cfullchain\"}" "$URL/fullchain.pem" >/dev/null || return 1
|
_response=$(_post "{\"value\": \"$_cfullchain\"}" "$URL/fullchain.pem")
|
||||||
|
if [ "$?" != "0" ]; then return 1; fi
|
||||||
|
if echo "$_response" | grep -q '"errors":\['; then
|
||||||
|
_err "Vault error writing fullchain.pem: $_response"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# To make it compatible with the wrong ca path `chain.pem` which was used in former versions
|
# To make it compatible with the wrong ca path `chain.pem` which was used in former versions
|
||||||
@ -121,11 +182,20 @@ vault_deploy() {
|
|||||||
_err "The CA certificate has moved from chain.pem to ca.pem, if you don't depend on chain.pem anymore, you can delete it to avoid this warning"
|
_err "The CA certificate has moved from chain.pem to ca.pem, if you don't depend on chain.pem anymore, you can delete it to avoid this warning"
|
||||||
_info "Updating CA certificate to $URL/chain.pem for backward compatibility"
|
_info "Updating CA certificate to $URL/chain.pem for backward compatibility"
|
||||||
if [ -n "$VAULT_KV_V2" ]; then
|
if [ -n "$VAULT_KV_V2" ]; then
|
||||||
_post "{\"data\": {\"value\": \"$_cca\"}}" "$URL/chain.pem" >/dev/null || return 1
|
_response=$(_post "{\"data\": {\"value\": \"$_cca\"}}" "$URL/chain.pem")
|
||||||
|
if [ "$?" != "0" ]; then return 1; fi
|
||||||
|
if echo "$_response" | grep -q '"errors":\['; then
|
||||||
|
_err "Vault error writing chain.pem: $_response"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
_post "{\"value\": \"$_cca\"}" "$URL/chain.pem" >/dev/null || return 1
|
_response=$(_post "{\"value\": \"$_cca\"}" "$URL/chain.pem")
|
||||||
|
if [ "$?" != "0" ]; then return 1; fi
|
||||||
|
if echo "$_response" | grep -q '"errors":\['; then
|
||||||
|
_err "Vault error writing chain.pem: $_response"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -340,8 +340,17 @@ _azure_getaccess_token() {
|
|||||||
|
|
||||||
if [ "$managedIdentity" = true ]; then
|
if [ "$managedIdentity" = true ]; then
|
||||||
# https://learn.microsoft.com/en-us/entra/identity/managed-identities-azure-resources/how-to-use-vm-token#get-a-token-using-http
|
# https://learn.microsoft.com/en-us/entra/identity/managed-identities-azure-resources/how-to-use-vm-token#get-a-token-using-http
|
||||||
export _H1="Metadata: true"
|
if [ -n "$IDENTITY_ENDPOINT" ]; then
|
||||||
response="$(_get http://169.254.169.254/metadata/identity/oauth2/token\?api-version=2018-02-01\&resource=https://management.azure.com/)"
|
# Some Azure environments may set IDENTITY_ENDPOINT (formerly MSI_ENDPOINT) to have an alternative metadata endpoint
|
||||||
|
url="$IDENTITY_ENDPOINT?api-version=2019-08-01&resource=https://management.azure.com/"
|
||||||
|
headers="X-IDENTITY-HEADER: $IDENTITY_HEADER"
|
||||||
|
else
|
||||||
|
url="http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/"
|
||||||
|
headers="Metadata: true"
|
||||||
|
fi
|
||||||
|
|
||||||
|
export _H1="$headers"
|
||||||
|
response="$(_get "$url")"
|
||||||
response="$(echo "$response" | _normalizeJson)"
|
response="$(echo "$response" | _normalizeJson)"
|
||||||
accesstoken=$(echo "$response" | _egrep_o "\"access_token\":\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \")
|
accesstoken=$(echo "$response" | _egrep_o "\"access_token\":\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \")
|
||||||
expires_on=$(echo "$response" | _egrep_o "\"expires_on\":\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \")
|
expires_on=$(echo "$response" | _egrep_o "\"expires_on\":\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \")
|
||||||
|
163
dnsapi/dns_edgecenter.sh
Normal file
163
dnsapi/dns_edgecenter.sh
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
# shellcheck disable=SC2034
|
||||||
|
|
||||||
|
# EdgeCenter DNS API integration for acme.sh
|
||||||
|
# Author: Konstantin Ruchev <konstantin.ruchev@edgecenter.ru>
|
||||||
|
dns_edgecenter_info='edgecenter DNS API
|
||||||
|
Site: https://edgecenter.ru
|
||||||
|
Docs: github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_edgecenter
|
||||||
|
Options:
|
||||||
|
EDGECENTER_API_KEY auth APIKey'
|
||||||
|
|
||||||
|
EDGECENTER_API="https://api.edgecenter.ru"
|
||||||
|
DOMAIN_TYPE=
|
||||||
|
DOMAIN_MASTER=
|
||||||
|
|
||||||
|
######## Public functions #####################
|
||||||
|
|
||||||
|
#Usage: dns_edgecenter_add _acme-challenge.www.domain.com "TXT_RECORD_VALUE"
|
||||||
|
dns_edgecenter_add() {
|
||||||
|
fulldomain="$1"
|
||||||
|
txtvalue="$2"
|
||||||
|
|
||||||
|
_info "Using EdgeCenter DNS API"
|
||||||
|
|
||||||
|
if ! _dns_edgecenter_init_check; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_debug "Detecting root zone for $fulldomain"
|
||||||
|
if ! _get_root "$fulldomain"; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
subdomain="${fulldomain%."$_zone"}"
|
||||||
|
subdomain=${subdomain%.}
|
||||||
|
|
||||||
|
_debug "Zone: $_zone"
|
||||||
|
_debug "Subdomain: $subdomain"
|
||||||
|
_debug "TXT value: $txtvalue"
|
||||||
|
|
||||||
|
payload='{"resource_records": [ { "content": ["'"$txtvalue"'"] } ], "ttl": 60 }'
|
||||||
|
_dns_edgecenter_http_api_call "post" "dns/v2/zones/$_zone/$subdomain.$_zone/txt" "$payload"
|
||||||
|
|
||||||
|
if _contains "$response" '"error":"rrset is already exists"'; then
|
||||||
|
_debug "RRSet exists, merging values"
|
||||||
|
_dns_edgecenter_http_api_call "get" "dns/v2/zones/$_zone/$subdomain.$_zone/txt"
|
||||||
|
current="$response"
|
||||||
|
newlist=""
|
||||||
|
for v in $(echo "$current" | sed -n 's/.*"content":\["\([^"]*\)"\].*/\1/p'); do
|
||||||
|
newlist="$newlist {\"content\":[\"$v\"]},"
|
||||||
|
done
|
||||||
|
newlist="$newlist{\"content\":[\"$txtvalue\"]}"
|
||||||
|
putdata="{\"resource_records\":[${newlist}]}
|
||||||
|
"
|
||||||
|
_dns_edgecenter_http_api_call "put" "dns/v2/zones/$_zone/$subdomain.$_zone/txt" "$putdata"
|
||||||
|
_info "Updated existing RRSet with new TXT value."
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if _contains "$response" '"exception":'; then
|
||||||
|
_err "Record cannot be added."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_info "TXT record added successfully."
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
#Usage: dns_edgecenter_rm _acme-challenge.www.domain.com "TXT_RECORD_VALUE"
|
||||||
|
dns_edgecenter_rm() {
|
||||||
|
fulldomain="$1"
|
||||||
|
txtvalue="$2"
|
||||||
|
|
||||||
|
_info "Removing TXT record for $fulldomain"
|
||||||
|
|
||||||
|
if ! _dns_edgecenter_init_check; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! _get_root "$fulldomain"; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
subdomain="${fulldomain%."$_zone"}"
|
||||||
|
subdomain=${subdomain%.}
|
||||||
|
|
||||||
|
_dns_edgecenter_http_api_call "delete" "dns/v2/zones/$_zone/$subdomain.$_zone/txt"
|
||||||
|
|
||||||
|
if [ -z "$response" ]; then
|
||||||
|
_info "TXT record deleted successfully."
|
||||||
|
else
|
||||||
|
_info "TXT record may not have been deleted: $response"
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
#################### Private functions below ##################################
|
||||||
|
|
||||||
|
_dns_edgecenter_init_check() {
|
||||||
|
EDGECENTER_API_KEY="${EDGECENTER_API_KEY:-$(_readaccountconf_mutable EDGECENTER_API_KEY)}"
|
||||||
|
if [ -z "$EDGECENTER_API_KEY" ]; then
|
||||||
|
_err "EDGECENTER_API_KEY was not exported."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_saveaccountconf_mutable EDGECENTER_API_KEY "$EDGECENTER_API_KEY"
|
||||||
|
export _H1="Authorization: APIKey $EDGECENTER_API_KEY"
|
||||||
|
|
||||||
|
_dns_edgecenter_http_api_call "get" "dns/v2/clients/me/features"
|
||||||
|
if ! _contains "$response" '"id":'; then
|
||||||
|
_err "Invalid API key."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
_get_root() {
|
||||||
|
domain="$1"
|
||||||
|
i=1
|
||||||
|
while true; do
|
||||||
|
h=$(printf "%s" "$domain" | cut -d . -f "$i"-)
|
||||||
|
if [ -z "$h" ]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
_dns_edgecenter_http_api_call "get" "dns/v2/zones/$h"
|
||||||
|
if ! _contains "$response" 'zone is not found'; then
|
||||||
|
_zone="$h"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
i=$((i + 1))
|
||||||
|
done
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
_dns_edgecenter_http_api_call() {
|
||||||
|
mtd="$1"
|
||||||
|
endpoint="$2"
|
||||||
|
data="$3"
|
||||||
|
|
||||||
|
export _H1="Authorization: APIKey $EDGECENTER_API_KEY"
|
||||||
|
|
||||||
|
case "$mtd" in
|
||||||
|
get)
|
||||||
|
response="$(_get "$EDGECENTER_API/$endpoint")"
|
||||||
|
;;
|
||||||
|
post)
|
||||||
|
response="$(_post "$data" "$EDGECENTER_API/$endpoint")"
|
||||||
|
;;
|
||||||
|
delete)
|
||||||
|
response="$(_post "" "$EDGECENTER_API/$endpoint" "" "DELETE")"
|
||||||
|
;;
|
||||||
|
put)
|
||||||
|
response="$(_post "$data" "$EDGECENTER_API/$endpoint" "" "PUT")"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
_err "Unknown HTTP method $mtd"
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
_debug "HTTP $mtd response: $response"
|
||||||
|
return 0
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user