Digital Ocean acme-challenge breaks when over 20 domains

I’m not sure where to submit a bug report for a module (specifically the digital ocean dns auto-validate powershell script: DOcean.ps1)

I dug into the code and the error seems to be that ‘Find-DOZone’ Doesn’t properly support pagination
This breaks the ability to use the script when you have more than 20 domains across all of your certificates

See:
https://docs.digitalocean.com/reference/api/api-reference/#section/Introduction/Links-and-Pagination

For ease of debugging here’s the code to replicate the “check domains” part of Find-DOZone in DOcean.ps1

$ApiRoot = 'https://api.digitalocean.com/v2/domains'
$RestParams = @{
    Headers =  @{Authorization='Bearer {your api token}'}
    ContentType = 'application/json'}
$script:UseBasic = @{UseBasicParsing=$True}
(Invoke-RestMethod "$ApiRoot" @RestParams @script:UseBasic).domains|tee -va domains
$domains.count

Here’s equivalent code to the above that does support the pagination and gathers all the domains into $zones (as used in the script)

$ApiRoot = 'https://api.digitalocean.com/v2/domains'
$RestParams = @{
    Headers =  @{Authorization='Bearer {Your API Key}'}
    ContentType = 'application/json'}
$script:UseBasic = @{UseBasicParsing=$True}

		$zones = @()
		$responses = @()
		$request = $ApiRoot
		do {
			try {
				$responses += Invoke-RestMethod "$request" @RestParams @script:UseBasic
			} catch {
				throw
			}
			$zones += ($responses[-1]).domains
			$request = $responses[-1].links.pages.next
		} until (
			($null -eq $request)
		)

Thanks, so the best place to log this issue is in the Posh-ACME github:

The source code for the Digital Ocean plugin is here and I’m sure they’d really appreciate a pull request with a fix, it looks like you know your PowerShell:

I see Ryan has updated the script in Posh-ACME. To try it out with Certify you’d need to overwrite C:\Program Files\CertifyTheWeb\Scripts\DNS\PoshACME\Plugins\DOcean.ps1 with the latest version from https://github.com/rmbolger/Posh-ACME/blob/main/Posh-ACME/Plugins/DOcean.ps1

Apparently I never got around to creating an account over here. But I’m here now. So you can tag me on stuff when necessary. :grinning:

1 Like

Awesome, thanks Ryan!

To get this particular fix I’ll probably need to update the version of Posh-ACME we pull during build, currently it’s fairly old (v4.2.0) but I think I’ll need to re-test some of the providers we pull in as I think the parameters have changed or retired (we currently use the plain text version of the params).

I didn’t even realize CTW was limited to the plaintext param sets. Technically, none of them have been removed yet and will continue to work as long as 4.x exists. But I was planning on ditching them in 5.x. And for new plugins, I haven’t been adding new plaintext param sets.

if someone can point me at the parts that pull in the Posh-ACME providers I can take a look and see if there’s anything I can contribute

This is the integration code: https://github.com/webprofusion/certify/blob/development/src/Certify.Core/Management/Challenges/DNS/DnsProviderPoshACME.cs

I can probably get time to look at this in about a week, after the Let’s Encrypt root expiry fallout as settled. You should be able to just copy the powershell into your Certify install overwriting the existing DOcean.ps1 though, just to get it working for you. You’d need to do it again if we release any updates in the meantime.

oh I solved it myself this time by extracting the live parameters to a file, then running manual simulations until I had code I could put in to support pagination.

I’m mainly doing this to help future me next time around

I took a look at that code but I don’t see where it calls DOcean.ps1
Or more accurately where it calls the posh-ACME component that ends up calling DOcean.ps1

I’m trying to mentally model the interactions between them and the most reliable way I know to do that is to see where they link together so I can trace forward and backward

Re: Losing support for the plain text parameters

Based on the plugin documentation

The parameter definition would probably be something like changing this line to the following, note the addition of a flag to indicate it needs to be of SecureString type. However changes would need to be made wherever the provider is digested in order to support the SecureString parameter type.

new ProviderParameter { 
    Key = "DOTokenSecure",
    Name = "API Token",
    IsRequired = true,
    Description = "Personal Access Token",
    IsCredential = true,
    AsSecureString = true
},

Here’s the example given in the Plugin documentation

$pArgs = @{
    DOTokenSecure = (Read-Host 'Access Token' -AsSecureString)
}
New-PACertificate example.com -Plugin DOcean -PluginArgs $pArgs
1 Like