Invalid status after updating to ACMEv2

Hey,

Since i updated the Azure Automation account to use ACMEv2 since it was showing an error saying ACMEv1 is no longer supported it hasn’t worked.

It comes back with:

Server returned problem (Status: 403). @{type=urn:ietf:params:acme:error:orderNotReady; detail=Order’s status (“invalid”) is not acceptable for finalization; status=403} (Server returned problem (Status: 403). @{type=urn:ietf:params:acme:error:orderNotReady; detail=Order’s status (“invalid”) is not acceptable for finalization; status=403})

the auth url is:
https://acme-v02.api.letsencrypt.org/acme/authz-v3/2567279969

It says on here that it is ‘unauthorized’ and that it gets an invalid response from:
https://dev.cwac.echoweb.co.uk/.well-known/acme-challenge/i-d1BmdVdFubd0EFiDvupA7jPVan-zflFtffWF6oWXo

I’ve checked that the storage account is public and it has all of the files it creates when you run the job and it accepts unsecure connections.

I have the CNAME and A record setup which is why i’ve been able to do it locally with a certificate.

I’ve also checked the ‘check your web server’ site and everything looks ok so i am not sure what it could be.

1 Like

Hi @Benjuno

please answer all of the following questions:


Please fill out the fields below so we can help you better. Note: you must provide your domain name to get help. Domain names for issued certificates are all made public in Certificate Transparency logs (e.g. https://crt.sh/?q=example.com), so withholding your domain name here does not increase secrecy, but only makes it harder for us to provide help.

My domain is:

I ran this command:

It produced this output:

My web server is (include version):

The operating system my web server runs on is (include version):

My hosting provider, if applicable, is:

I can login to a root shell on my machine (yes or no, or I don’t know):

I’m using a control panel to manage my site (no, or provide the name and version of the control panel):

The version of my client is (e.g. output of certbot --version or certbot-auto --version if you’re using Certbot):

1 Like

My domain is: echoweb.co.uk

I ran this command:
#######################################################################################

Script that renews a Let’s Encrypt certificate for an Azure Application Gateway

Pre-requirements:

- Have a storage account in which the folder path has been created:

‘/.well-known/acme-challenge/’, to put here the Let’s Encrypt DNS check files

- Add “Path-based” rule in the Application Gateway with this configuration:

- Path: ‘/.well-known/acme-challenge/*’

- Check the configure redirection option

- Choose redirection type: permanent

- Choose redirection target: External site

- Target URL:

- Example: ‘https://test.blob.core.windows.net/public

- For execution on Azure Automation: Import ‘AzureRM.profile’, ‘AzureRM.Network’

and ‘ACMESharp’ modules in Azure

UPDATE 2019-11-27

- Due to deprecation of ACMEv1, a new script is required to use ACMEv2.

The module to use is called ACME-PS.

#######################################################################################

Param(
[string]$domain,
[string]$EmailAddress,
[string]$STResourceGroupName,
[string]$storageName,
[string]$AGResourceGroupName,
[string]$AGName,
[string]$AGOldCertName
)

Azure Login

If Runbook for Azure Automation

$connection = Get-AutomationConnection -Name AzureRunAsConnection
Login-AzureRmAccount -ServicePrincipal -Tenant $connection.TenantID -ApplicationID $connection.ApplicationID -CertificateThumbprint $connection.CertificateThumbprint

Create a state object and save it to the harddrive

$state = New-ACMEState -Path $env:TEMP
$serviceName = ‘LetsEncrypt’

Fetch the service directory and save it in the state

Get-ACMEServiceDirectory $state -ServiceName $serviceName -PassThru;

Get the first anti-replay nonce

New-ACMENonce $state;

Create an account key. The state will make sure it’s stored.

New-ACMEAccountKey $state -PassThru;

Register the account key with the acme service. The account key will automatically be read from the state

New-ACMEAccount $state -EmailAddresses $EmailAddress -AcceptTOS;

Load an state object to have service directory and account keys available

$state = Get-ACMEState -Path $env:TEMP;

It might be neccessary to acquire a new nonce, so we’ll just do it for the sake of the example.

New-ACMENonce $state -PassThru;

Create the identifier for the DNS name

$identifier = New-ACMEIdentifier $domain;

Create the order object at the ACME service.

$order = New-ACMEOrder $state -Identifiers $identifier;

Fetch the authorizations for that order

$authZ = Get-ACMEAuthorization -State $state -Order $order;

Select a challenge to fullfill

$challenge = Get-ACMEChallenge $state $authZ “http-01”;

Inspect the challenge data

$challenge.Data;

Create the file requested by the challenge

$fileName = $env:TMP + ‘’ + $challenge.Token;
Set-Content -Path $fileName -Value $challenge.Data.Content -NoNewline;

$blobName = “.well-known/acme-challenge/” + $challenge.Token
$storageAccount = Get-AzureRmStorageAccount -ResourceGroupName $STResourceGroupName -Name $storageName
$ctx = $storageAccount.Context
Set-AzureStorageBlobContent -File $fileName -Container “public” -Context $ctx -Blob $blobName

Signal the ACME server that the challenge is ready

$challenge | Complete-ACMEChallenge $state;

Wait a little bit and update the order, until we see the states

while($order.Status -notin (“ready”,“invalid”)) {
Start-Sleep -Seconds 10;
$order | Update-ACMEOrder $state -PassThru;
}

We should have a valid order now and should be able to complete it

Therefore we need a certificate key

$certKey = New-ACMECertificateKey -Path “$env:TEMP$domain.key.xml”;

Complete the order - this will issue a certificate singing request

Complete-ACMEOrder $state -Order $order -CertificateKey $certKey;

Now we wait until the ACME service provides the certificate url

while(-not $order.CertificateUrl) {
Start-Sleep -Seconds 15
$order | Update-Order $state -PassThru
}

As soon as the url shows up we can create the PFX

$password = ConvertTo-SecureString -String “Passw@rd123***” -Force -AsPlainText
Export-ACMECertificate $state -Order $order -CertificateKey $certKey -Path “$env:TEMP$domain.pfx” -Password $password;

Delete blob to check DNS

Remove-AzureStorageBlob -Container “public” -Context $ctx -Blob $blobName

RENEW APPLICATION GATEWAY CERTIFICATE

$appgw = Get-AzureRmApplicationGateway -ResourceGroupName $AGResourceGroupName -Name $AGName
Set-AzureRmApplicationGatewaySSLCertificate -Name $AGOldCertName -ApplicationGateway $appgw -CertificateFile “$env:TEMP$domain.pfx” -Password $password
Set-AzureRmApplicationGateway -ApplicationGateway $appgw

It produced this output:

Server returned problem (Status: 403). @{type=urn:ietf:params:acme:error:orderNotReady; detail=Order’s status (“invalid”) is not acceptable for finalization; status=403} (Server returned problem (Status: 403). @{type=urn:ietf:params:acme:error:orderNotReady; detail=Order’s status (“invalid”) is not acceptable for finalization; status=403})

My web server is (include version):
it is an automation account in azure which is used to renew a windows server attached to an application gateway.

The operating system my web server runs on is (include version):
see above
My hosting provider, if applicable, is:
see above
I can login to a root shell on my machine (yes or no, or I don’t know):
?
I’m using a control panel to manage my site (no, or provide the name and version of the control panel):
?
The version of my client is (e.g. output of certbot --version or certbot-auto --version if you’re using Certbot):
?

1 Like

So that script is buggy. If a script sees an invalid order, it must stop, not try to finalize the order.

And there is no error message why the validation has failed.

Check, if there is an update. Or switch to another client.


PS: Is this

done and does this work?

1 Like