PKISharp / ACME-PS

PowerShell module supporting ACME v2 certificate management
MIT License
104 stars 31 forks source link

How to bypass external account parameters #101

Closed DerekJDev closed 4 years ago

DerekJDev commented 4 years ago

I'm getting this error:

Cannot process command because of one or more missing mandatory parameters: ExternalAccountKID ExternalAccountMACKey.

I'm not linking to an external account, but I don't see a way to bypass passing these parameters. If these are required, I'm not really sure where I would get the ID and key from. I'm running script in an Azure runbook to renew SSL certificates in an Application Gateway. Thanks in advance for the time and help!

DerekJDev commented 4 years ago

Here's the script:

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 $state -ServiceName $serviceName -PassThru;

# Get the first anti-replay nonce
New-ACMENonce -State $state;

# Create an account key. The state will make sure it's stored.
New-ACMEAccountKey -State $state -PassThru;

# Register the account key with the acme service. The account key will automatically be read from the state
New-ACMEAccount -State $state -EmailAddresses @("######") -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 $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 $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 $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 $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 $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 $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 "######" -Force -AsPlainText
Export-ACMECertificate -State $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
glatzert commented 4 years ago

Well the answer is "not with Version 1.3.0 - that's a stupid bug", but with 1.3.1 (which is just being uploaded) ;)

DerekJDev commented 4 years ago

Awesome, thanks!