From 9db5be96341b1d88a7345ccfa027b8c336d3856f Mon Sep 17 00:00:00 2001 From: Nicholas Sherlock Date: Thu, 14 Jul 2022 17:45:17 +1200 Subject: [PATCH] Wait for Route53 changes to propagate Avoids these errors, which are caused by attempting to issue certs before records have propagated to all Route53 servers: { "type": "urn:ietf:params:acme:error:orderNotReady", "detail": "Order's status (\"invalid\") is not acceptable for finalization", "status": 403 } Fixes #33 --- src/acme/authorize/updateDNSChallenge.js | 16 +++++++++++++++- src/aws/route53/getChangeStatus.js | 7 +++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 src/aws/route53/getChangeStatus.js diff --git a/src/acme/authorize/updateDNSChallenge.js b/src/acme/authorize/updateDNSChallenge.js index b8ef320..45c9e1c 100644 --- a/src/acme/authorize/updateDNSChallenge.js +++ b/src/acme/authorize/updateDNSChallenge.js @@ -1,5 +1,6 @@ const updateTXTRecord = require('../../aws/route53/updateTXTRecord') const getHostedZoneId = require('../../aws/route53/getHostedZoneId') +const getChangeStatus = require('../../aws/route53/getChangeStatus') const RSA = require('rsa-compat').RSA const crypto = require('crypto') const dns = require('dns') @@ -17,6 +18,18 @@ const arrayContainsArray = (superset, subset) => const flatten = input => Array.prototype.concat.apply([], input) +const changePropCheck = (domain, id) => (tryCount) => { + console.log(`Attempt ${tryCount + 1} for DNS record to propagate for ${domain}`) + return getChangeStatus(id) + .then(status => { + ++tryCount + return { + tryCount, + result: status === 'INSYNC' + } + }) +} + const dnsPreCheck = (domain, expect) => (tryCount) => { console.log(`Attempt ${tryCount + 1} to resolve TXT record for ${domain}`) return resolveTxt(`_acme-challenge.${domain}`) @@ -53,7 +66,8 @@ const updateDNSChallenge = (domain, dnsChallenges, acctKeyPair) => { console.log(`Updating DNS TXT Record for ${domainName} to contain ${dnsChallengeTexts} in Route53 hosted zone ${id}`) return updateTXTRecord(id, domainName, dnsChallengeTexts) }) - .then(updated => validateDNSChallenge(domainName, dnsChallengeTexts)) + .then(updated => retry(0, changePropCheck(domainName, updated.ChangeInfo.Id))) + .then(() => validateDNSChallenge(domainName, dnsChallengeTexts)) .catch(e => { console.error(`Couldn't write token digest to DNS record.`, e) throw e diff --git a/src/aws/route53/getChangeStatus.js b/src/aws/route53/getChangeStatus.js new file mode 100644 index 0000000..d56b796 --- /dev/null +++ b/src/aws/route53/getChangeStatus.js @@ -0,0 +1,7 @@ +const getRoute53 = require('../sdk/getRoute53') + +const getChangeStatus = (id) => + getRoute53().getChange({Id: id}).promise() + .then(data => data.Status) + +module.exports = getChangeStatus