ACMESharp
ACMESharp copied to clipboard
My powershell script is always returning 'invalid' status
I can't seem to figure out the issue here and hoping someone can pinpoint what's escaping me. If I manually type the alias string, all is well. When I run the script, I get the following:
ChallengePart : ACMESharp.Messages.ChallengePart
Challenge : ACMESharp.ACME.DnsChallenge
Type : dns-01
Uri : https://acme-v01.api.letsencrypt.org/acme/challenge/DwRxfVEea_XlXggdLkeXCRwAbi1jqsi7mXd9DkTIVHA/1723491436
Token : oDH8Z_lXJKD8asjWZXII3iglW0yy8HDJLimaT4OLbzE
Status : invalid
OldChallengeAnswer : [, ]
ChallengeAnswerMessage :
HandlerName : awsRoute53
HandlerHandleDate : 8/10/2017 3:37:16 PM
HandlerCleanUpDate :
SubmitDate : 8/10/2017 3:37:38 PM
SubmitResponse : {StatusCode, Headers, Links, RawContent...}
Here's my ps1:
$acmeIdentifier = "example.example.com"
$certName = $acmeIdentifier -replace '[.]',''
$alias = "aws1-" + "$(get-date -UFormat "%Y%m%d%H%M%S")"
$pfxFileName = "le-" + "$certName" + ".pfx"
$pfxFilePath = Join-Path E:\LetsEncryptVault $pfxFileName
$pwd = "mimikatz"
Import-Module ACMESHarp
Import-Module AWSPowershell
# Start by initializing a Vault to store your Certificates and related artifacts. Default vault - C:\ProgramData\ACMESharp\sysVault Note, if you run as Administrator, your Vault will be created in a system-wide path, otherwise it will be created in a private, user-specific location.
# *** run these command before running this script ***
# Initialze-ACMEVault
# New-ACMERegistration -Contacts mailto:[email protected] -AcceptTos
# Submit a DNS domain name that you want to secure with a PKI certificate
New-ACMEIdentifier -Dns $acmeIdentifier -Alias $alias
# sleep - had problems just running flat
start-sleep 10
# Automate DNS challenge via awsRoute53 handler
Complete-ACMEChallenge $alias -ChallengeType dns-01 -Handler awsRoute53 -HandlerParameters @{ 'HostedZoneId' = ''; 'Region' = 'us-east-1' }
# sleep - had problems just running flat
start-sleep 10
#Submit the challenge response
Submit-ACMEChallenge $alias -ChallengeType dns-01
# sleep - had problems just running flat
start-sleep 10
#Need a check here for .status = pending before moving on to cert request.
# Check the status of the challenge every 6 seconds until we have an answer; fail after a minute
$i = 0
do {
$challenge = (Update-ACMEIdentifier $Alias -ChallengeType dns-01).Challenges | Where-Object {$_.Type -eq "dns-01"}
if($challenge.Status -eq "invalid") {
write-host "Challenge Response is Invalid"
exit
}
if($challenge.Status -eq "pending") {
Start-Sleep 60
$i++
}
} until($challenge.Status -eq "valid" -or $i -gt 10)
# Create the certificate request the certificate.
New-ACMECertificate $alias -Generate -Alias $certName
# Submit the certificate request
Submit-ACMECertificate $certName
# Check the status of the certificate every 6 seconds until we have an answer; fail after a minute
$i = 0
do {
$certInfo = Update-AcmeCertificate $certName
if($certinfo.SerialNumber -ne "") {
Start-Sleep 60
$i++
}
} until($certInfo.SerialNumber -ne "" -or $i -gt 10)
# Export the certificate and related assets in PKCS#12 archive
Get-ACMECertificate $certName -ExportPkcs12 $pfxFilePath -CertificatePassword $pwd
You are only giving it a minute to test for the challenge, but you are using a DNS challenge. If you are lucky, then you are updating the same DNS server as Let's Encrypt request for the challenge line, but the chances are small. If Let's Encrypt request one of the other DNS servers in for your domain, then you have to wait for your update to replicate to that server. How that is set up is hard to say, but it can be anything from few seconds and up to a day.
@kevops -- can you confirm what @WallyRanson said is correct?
@WallyRanson Thanks for that insight. I will attempt to 'stage' the submit and check for status with that in mind.
cc @ebekker
Just a little extra info from https://aws.amazon.com/route53/faqs/
Q. Are changes to resource record sets transactional?
Yes. A transactional change helps ensure that the change is consistent, reliable, and independent of other changes. Amazon Route 53 has been designed so that changes complete entirely on any individual DNS server, or not at all. This helps ensure your DNS queries are always answered consistently, which is important when making changes such as flipping between destination servers. When using the API, each call to ChangeResourceRecordSets returns an identifier that can be used to track the status of the change. Once the status is reported as INSYNC, your change has been performed on all of the Route 53 DNS servers.
and ....
Q. How quickly will changes I make to my DNS settings on Amazon Route 53 propagate globally?
Amazon Route 53 is designed to propagate updates you make to your DNS records to its world-wide network of authoritative DNS servers within 60 seconds under normal conditions. A change is successfully propagated world-wide when the API call returns an INSYNC status listing.
Note that caching DNS resolvers are outside the control of the Amazon Route 53 service and will cache your resource record sets according to their time to live (TTL). The INSYNC or PENDING status of a change refers only to the state of Route 53’s authoritative DNS servers.
I've started seeing the same behavior in my similar code (dns-01, manual handler with GoDaddy DNS API).
Update-ACMEIdentifier comes back as invalid: "detail": "Correct value not found for DNS challenge",
Checking the Record Value matches SHA256 base64 of KeyAuthorization. Allowing for a delay well in excess of the TTL doesn't help.
@kevops Did you ever solve this?
@davehope My issue was resolved by adding a wait command for 65 seconds prior to submitting the ACME challenge. I believe this is required to allow AWS Rt53 DNS to sync. Due to ACME muliti DNS region challenge (in order to circumvent DNS poisoning as an attack), I believe it's required that DNS fully synchronizes.
Thanks @kevops , adding a 60s delay just before Submit-ACMEChallenge worked.