mirror of
https://github.com/acmesh-official/acme.sh.git
synced 2025-05-08 11:54:13 +00:00
Update dns_aws.sh
Use `hostedzonesbyname` Route 53 API endpoint instead of `hostedzones` endpoint. The `hostedzones` endpoint returns all hosted zones for a given Route 53 account in groups of 100. For AWS Route 53 accounts with many domains, this could mean a large number of requests to the `hostedzones` endpoint as it progresses through each page of 100 results. This will often result in a "Rate exceeded" API error from Route 53. Instead of using `hostedzones` endpoint, we can use `hostedzonesbyname` and then filter by the specific domain we are looking for and ask for a `max-items` of 1. The while loop in _get_root() starts with a given domain and removes parts from the front of the given domain if no match is found. For example, when requesting a certificate for `test.www.domain.co.uk`, the while loop will check for Route 53 hosted zones for: 1st: test.www.domain.co.uk 2nd: www.domain.co.uk 3rd: domain.co.uk 4th: co.uk 5th: uk The first two checks will result in no matches, while the third check should be successful (if, of course, domain.co.uk is actually a hosted zone in the given AWS account). Now imagine that the given AWS account owns 2500 domains and, therefore, has 2500 hosted zones. Using the `hostedzones` endpoint would result in: 1st: 25 GET requests to the Route 53 API looking for a match to test.www.domain.co.uk 2nd: 25 GET requests to the Route 53 API looking for a match to www.domain.co.uk 3rd: 25 GET requests to the Route 53 API looking for a match to domain.co.uk 4th: 25 GET requests to the Route 53 API looking for a match to co.uk 5th: 25 GET requests to the Route 53 API looking for a match to uk This would far exceed the Route 53 limit of five requests per second. Using `hostedzonesbyname` results in a dramatic reduction in Route 53 API GET requests for AWS accounts with large numbers of hosted zones.
This commit is contained in:
parent
4adb525513
commit
078a431a43
@ -12,7 +12,7 @@
|
|||||||
AWS_HOST="route53.amazonaws.com"
|
AWS_HOST="route53.amazonaws.com"
|
||||||
AWS_URL="https://$AWS_HOST"
|
AWS_URL="https://$AWS_HOST"
|
||||||
|
|
||||||
AWS_WIKI="https://github.com/acmesh-official/acme.sh/wiki/How-to-use-Amazon-Route53-API"
|
AWS_WIKI="https://github.com/Neilpang/acme.sh/wiki/How-to-use-Amazon-Route53-API"
|
||||||
|
|
||||||
######## Public functions #####################
|
######## Public functions #####################
|
||||||
|
|
||||||
@ -152,50 +152,58 @@ dns_aws_rm() {
|
|||||||
|
|
||||||
_get_root() {
|
_get_root() {
|
||||||
domain=$1
|
domain=$1
|
||||||
i=2
|
# Start with field 2 since each domain starts with _acme-challenge
|
||||||
p=1
|
# Example: _acme-challenge.www.domain.com
|
||||||
|
field=2
|
||||||
|
subdomain_part=1
|
||||||
|
|
||||||
if aws_rest GET "2013-04-01/hostedzone"; then
|
while true; do
|
||||||
while true; do
|
hostname=$(printf "%s" "$domain" | cut -d . -f $field-100)
|
||||||
h=$(printf "%s" "$domain" | cut -d . -f $i-100)
|
|
||||||
_debug2 "Checking domain: $h"
|
|
||||||
if [ -z "$h" ]; then
|
|
||||||
if _contains "$response" "<IsTruncated>true</IsTruncated>" && _contains "$response" "<NextMarker>"; then
|
|
||||||
_debug "IsTruncated"
|
|
||||||
_nextMarker="$(echo "$response" | _egrep_o "<NextMarker>.*</NextMarker>" | cut -d '>' -f 2 | cut -d '<' -f 1)"
|
|
||||||
_debug "NextMarker" "$_nextMarker"
|
|
||||||
if aws_rest GET "2013-04-01/hostedzone" "marker=$_nextMarker"; then
|
|
||||||
_debug "Truncated request OK"
|
|
||||||
i=2
|
|
||||||
p=1
|
|
||||||
continue
|
|
||||||
else
|
|
||||||
_err "Truncated request error."
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
#not valid
|
|
||||||
_err "Invalid domain"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if _contains "$response" "<Name>$h.</Name>"; then
|
if [ -z "$hostname" ]
|
||||||
hostedzone="$(echo "$response" | sed 's/<HostedZone>/#&/g' | tr '#' '\n' | _egrep_o "<HostedZone><Id>[^<]*<.Id><Name>$h.<.Name>.*<PrivateZone>false<.PrivateZone>.*<.HostedZone>")"
|
then
|
||||||
|
_debug "There are no more fields in the hostname to check"
|
||||||
|
_err "No matching Route 53 hosted zones for: $domain"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
_debug "Checking domain: $hostname"
|
||||||
|
|
||||||
|
if aws_rest GET "2013-04-01/hostedzonesbyname" "dnsname=$hostname&maxitems=1"; then
|
||||||
|
if _contains "$response" "<Name>$hostname.</Name>"; then
|
||||||
|
hostedzone="$(echo "$response" | sed 's/<HostedZone>/#&/g' | tr '#' '\n' | _egrep_o "<HostedZone><Id>[^<]*<.Id><Name>$hostname.<.Name>.*<PrivateZone>false<.PrivateZone>.*<.HostedZone>")"
|
||||||
_debug hostedzone "$hostedzone"
|
_debug hostedzone "$hostedzone"
|
||||||
if [ "$hostedzone" ]; then
|
if [ "$hostedzone" ]; then
|
||||||
_domain_id=$(printf "%s\n" "$hostedzone" | _egrep_o "<Id>.*<.Id>" | head -n 1 | _egrep_o ">.*<" | tr -d "<>")
|
_domain_id=$(printf "%s\n" "$hostedzone" | _egrep_o "<Id>.*<.Id>" | head -n 1 | _egrep_o ">.*<" | tr -d "<>")
|
||||||
if [ "$_domain_id" ]; then
|
if [ "$_domain_id" ]; then
|
||||||
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p)
|
_sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$subdomain_part)
|
||||||
_domain=$h
|
_domain=$hostname
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
_err "Can't find domain with id: $h"
|
_err "Can't find domain with id: $hostname"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
else
|
||||||
|
_debug "Route 53 does not have a hosted zone for: $hostname."
|
||||||
|
_debug "Moving on to next part of the hostname"
|
||||||
fi
|
fi
|
||||||
p=$i
|
else
|
||||||
i=$(_math "$i" + 1)
|
_err "Getting Route 53 hosted zones by name failed for: $domain"
|
||||||
done
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
subdomain_part=$field
|
||||||
|
field=$(_math "$field" + 1)
|
||||||
|
|
||||||
|
if [ -n "$AWS_DNS_SLOWRATE" ]; then
|
||||||
|
_info "Slow rate activated: sleeping for $AWS_DNS_SLOWRATE seconds"
|
||||||
|
_sleep "$AWS_DNS_SLOWRATE"
|
||||||
|
else
|
||||||
|
_sleep 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
_err "_get_root failed for domain: $domain"
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,21 +230,21 @@ _use_instance_role() {
|
|||||||
|
|
||||||
_use_metadata() {
|
_use_metadata() {
|
||||||
_aws_creds="$(
|
_aws_creds="$(
|
||||||
_get "$1" "" 1 |
|
_get "$1" "" 1 \
|
||||||
_normalizeJson |
|
| _normalizeJson \
|
||||||
tr '{,}' '\n' |
|
| tr '{,}' '\n' \
|
||||||
while read -r _line; do
|
| while read -r _line; do
|
||||||
_key="$(echo "${_line%%:*}" | tr -d '"')"
|
_key="$(echo "${_line%%:*}" | tr -d '"')"
|
||||||
_value="${_line#*:}"
|
_value="${_line#*:}"
|
||||||
_debug3 "_key" "$_key"
|
_debug3 "_key" "$_key"
|
||||||
_secure_debug3 "_value" "$_value"
|
_secure_debug3 "_value" "$_value"
|
||||||
case "$_key" in
|
case "$_key" in
|
||||||
AccessKeyId) echo "AWS_ACCESS_KEY_ID=$_value" ;;
|
AccessKeyId) echo "AWS_ACCESS_KEY_ID=$_value" ;;
|
||||||
SecretAccessKey) echo "AWS_SECRET_ACCESS_KEY=$_value" ;;
|
SecretAccessKey) echo "AWS_SECRET_ACCESS_KEY=$_value" ;;
|
||||||
Token) echo "AWS_SESSION_TOKEN=$_value" ;;
|
Token) echo "AWS_SESSION_TOKEN=$_value" ;;
|
||||||
esac
|
esac
|
||||||
done |
|
done \
|
||||||
paste -sd' ' -
|
| paste -sd' ' -
|
||||||
)"
|
)"
|
||||||
_secure_debug "_aws_creds" "$_aws_creds"
|
_secure_debug "_aws_creds" "$_aws_creds"
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user