rmbolger / Posh-ACME

PowerShell module and ACME client to create certificates from Let's Encrypt (or other ACME CA)
https://poshac.me/docs/latest/
MIT License
767 stars 186 forks source link

Regru DNS plugin appears to me broken somehow, help pls! #392

Closed aklimkin closed 3 years ago

aklimkin commented 3 years ago

When executing New-PACertificate I got the following error: image

The same URL in the browser returns pretty valid json: image

rmbolger commented 3 years ago

Hi @aklimkin. I can confirm I'm seeing the same error from my own account. It's possible they made a change to the API that is breaking the plugin. Give me a bit to check out what's wrong.

rmbolger commented 3 years ago

It seems like they changed the error code being used when you query a zone that doesn't exist. I pushed a fix that is working for me if you want to test it.

aklimkin commented 3 years ago

thanks for the prompt fix, but it still doesn't work for me gives another error (omitted first lines of the script output):

VERBOSE: received -1-byte response of content type text/plain; charset=utf-8 Submit-ChallengeValidation : Reg.Ru API threw unexpected error: _acme-challenge.klimkin.name is invalid or unsupported zone At C:\Users\klimkin\Documents\WindowsPowerShell\Modules\Posh-ACME\4.9.0\Public\New-PACertificate.ps1:238 char:9

aklimkin commented 3 years ago

in case you're interested here are my powershell commands

$pArgs = @{ RegRuCredential = (Get-Credential) } New-PACertificate 'klimkin.name','*.klimkin.name' -CertKeyLength ec-256 -AcceptTOS -Contact andrey@klimkin.name -Plugin Regru -PluginArgs $pArgs -DNSSleep 4000 -Verbose

rmbolger commented 3 years ago

Bummer. Using your existing $pArgs variable, can you try running this publish command and post the (sanitized) output?

Publish-Challenge klimkin.name (Get-PAAccount) faketoken Regru $pArgs -Verbose
aklimkin commented 3 years ago

sure image

aklimkin commented 3 years ago

i'm starting to wonder if i completely understand the letsencrypt dns-01 challenge procedure until now i thought that it would be _acme-challenge.klimkin.name TXT record with letsencrypt generated unique token as a value but script seems to try to find whole _acme-challenge.klimkin.name zone???

rmbolger commented 3 years ago

Sorry, one more request. Can you post the JSON response if you plug that URL into your browser like you did before?

Your understanding is correct. The problem is that the plugin needs to find the apex zone for the record name _acme-challenge.klimkin.name. But it can't assume it can just cut off the first part of the name and have that be the zone. So it basically starts checking for an existing zone starting with the full FQDN and then shortening it by one label until it finds the apex. What's broken is the code interpreting the response is improperly detecting a critical error rather than just the API saying that particular zone doesn't exist and ignoring it so it tries the next one.

aklimkin commented 3 years ago

{ "charset" : "utf-8", "error_code" : "PARAMETER_INCORRECT", "error_params" : { "param" : "input_data" }, "error_text" : "input_data has incorrect format or data", "messagestore" : null, "result" : "error" }

aklimkin commented 3 years ago

hope that this makes some sense to you ¯_(ツ)_/¯

rmbolger commented 3 years ago

Also, just to verify. You've installed and are now testing with the copy of the Plugin from the main branch, right? And done something like Import-Module Posh-ACME -Force to reload the module in your session or just started a new session from scratch.

aklimkin commented 3 years ago

yes, sure - i've checked on plugin file timestamp

rmbolger commented 3 years ago

Odd, that output makes it look like the URL didn't get copied completely.

aklimkin commented 3 years ago

oops, you're right - my fault, sorry the proper json is as foolows { "answer" : { "domains" : [ { "dname" : "_acme-challenge.klimkin.name", "error_code" : "INVALID_DOMAIN_NAME_FORMAT", "error_params" : { "domain_name" : "_acme-challenge.klimkin.name" }, "error_text" : "_acme-challenge.klimkin.name is invalid or unsupported zone", "result" : "error" } ] }, "charset" : "utf-8", "messagestore" : null, "result" : "success" }

rmbolger commented 3 years ago

So weird. That error should be getting ignored rather than caught and re-thrown. But the logic in this function is a bit funky and making it harder than I'd like to debug. Give me a bit to refactor and clean up some stuff. I'll push another update when I'm done and we can re-test.

aklimkin commented 3 years ago

and one more correction - my previously published json output from the browser test was actually been from the url constructed by hand typing, not exactly the same url copied from script output - that is why it did seem perfectly normal. it was rather demonstrated that i do have some domain and do have some access to it through the dns registrar api.

rmbolger commented 3 years ago

Ok. Give this latest version a try from the main branch using the same Publish command from earlier. This time, you'll want to enable debug output though by running $DebugPreference = 'Continue' first. Some of the raw REST logging is now in Debug instead of Verbose, but it's also sanitized now so you don't have to worry about exposing your password. It will also show the raw response to each request from the server. The plugin is also now much more efficient because it's making fewer API calls overall.

aklimkin commented 3 years ago

Hi, it's me again. Apparently good sleep makes huge difference :D In short, now everything works as it should. I finally even got my certificate from Letsencrypt

You were right - until now I've been working with original plugin version. What I saw as a different timestamp on the plugin file was actually a result of my own pathetic attempts to edit/debug your code. I ran all the commands like Update-Module, Import-Module, Install-Module, etc. I even went as far as Uninstall-Module and then Install-Module from the scratch. The issue is - I'm still getting the original version of the code :-( Finally I just got the raw code from the repository web page and pasted it in the plugin file. Hopefully you'll forgive me my stupidity - I'm not the developer and I'm new to the github either.

I'm truly sorry for giving you such a headache. Thank you very much for all the help.

aklimkin commented 3 years ago

In case you're still interested, here is the debug output I got with the resent plugin version:

VERBOSE: Publishing challenge for Domain klimkin.name with Token faketoken using Plugin Regru and DnsAlias ''. DEBUG: Loading PAAccount list from disk DEBUG: Calling Regru plugin to add _acme-challenge.klimkin.name TXT with value GRDBoDLhVp9Yc7w9CmcGUaey8yHx1lvl35NCtPQ8uKo VERBOSE: Searching for existing TXT record DEBUG: Querying records for zones: _acme-challenge.klimkin.name, klimkin.name DEBUG: GET https://api.reg.ru/api/regru2/zone/get_resource_records?input_format=json&input_data=%7B%22username%22%3A%22andrej.klim kin%40gmail.com%22%2C%22domains%22%3A%5B%7B%22dname%22%3A%22_acme-challenge.klimkin.name%22%7D%2C%7B%22dname%22%3A%22kl imkin.name%22%7D%5D%2C%22password%22%3A%22XXXXXXXX%22%2C%22output_content_type%22%3A%22plain%22%7D DEBUG: Response: { "answer": { "domains": [ { "dname": "_acme-challenge.klimkin.name", "error_code": "INVALID_DOMAIN_NAME_FORMAT", "error_params": { "domain_name": "_acme-challenge.klimkin.name" }, "error_text": "_acme-challenge.klimkin.name is invalid or unsupported zone", "result": "error" }, { "dname": "klimkin.name", "result": "success", "rrs": [ { --- my tin foil hat forced me to omit resource records list, trust me they all been listed there :) } ], "service_id": "47057807", "servtype": "domain", "soa": { "minimum_ttl": "3h", "ttl": "1d" } } ] }, "charset": "utf-8", "messagestore": null, "result": "success" } VERBOSE: Adding a TXT record for _acme-challenge.klimkin.name with value GRDBoDLhVp9Yc7w9CmcGUaey8yHx1lvl35NCtPQ8uKo DEBUG: GET https://api.reg.ru/api/regru2/zone/add_txt?input_format=json&input_data=%7B%22password%22%3A%22XXXXXXXX%22%2C%22domains %22%3A%5B%7B%22dname%22%3A%22klimkin.name%22%7D%5D%2C%22text%22%3A%22GRDBoDLhVp9Yc7w9CmcGUaey8yHx1lvl35NCtPQ8uKo%22%2C% 22output_content_type%22%3A%22plain%22%2C%22username%22%3A%22andrej.klimkin%40gmail.com%22%2C%22subdomain%22%3A%22_acme -challenge%22%7D DEBUG: Response: { "answer": { "domains": [ { "dname": "klimkin.name", "result": "success", "service_id": "47057807" } ] }, "charset": "utf-8", "messagestore": null, "result": "success" }

rmbolger commented 3 years ago

It's totally ok. I should have been more clear about how to test the updated version. And it gave me an excuse to improve the plugin overall. So thanks!

When I fix stuff in the main branch, it doesn't immediately get added to a new release that would be available using Install-Module. It's only available in Github until I get around to pushing the new release. For future reference for a plugin fix like this, you can usually just download the plugin's file directly from Github (rather than the whole repo) and overwrite the installed copy with the downloaded copy. The other way is to use the Installation (Development) instructions from the readme which are basically running this command:

iex (irm https://raw.githubusercontent.com/rmbolger/Posh-ACME/main/instdev.ps1)

Then once a new release is out, just delete whatever local copies of the module you have and re-download via Install-Module.

It sounds like the current changes have fixed everything. Thanks again for testing. I'll hopefully push a new release this week.