Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issues with Publish-Challenge with Simply.com #502

Closed
kaspersmjohansen opened this issue Jun 30, 2023 · 21 comments
Closed

Issues with Publish-Challenge with Simply.com #502

kaspersmjohansen opened this issue Jun 30, 2023 · 21 comments
Assignees
Labels
bug Something isn't working

Comments

@kaspersmjohansen
Copy link

With Posh-ACME 4.18 it get this error when publishing a challenge for my domain:
image

@rmbolger
Copy link
Owner

rmbolger commented Jul 1, 2023

Hi @kaspersmjohansen, thanks for reaching out. That error appears to be getting thrown by the Simply.com API because it can't find the DNS zone being queried. What's odd is that the URL it's querying would have been built using a info from a previously successful response from the API. So it's weird that the API would then give a 404 error for that URL.

Can you post the output after re-running the command with Debug output so we can get a better idea of what's happening? You can enable debug output by running $DebugPreference = 'Continue' prior to the command.

@rmbolger rmbolger self-assigned this Jul 1, 2023
@rmbolger rmbolger added the bug Something isn't working label Jul 1, 2023
@AlexGuld
Copy link

I have the same problem when using CertifyTheWeb and this PowerShell script.

@webprofusion-chrisc
Copy link
Contributor

@Zaico If you browse to https://api.simply.com/2/my/products/ and enter your api credentials when prompted, does the page load ok? I'm wondering if their api has developed a fault.

@AlexGuld
Copy link

AlexGuld commented Jul 10, 2023

Yes it looks just fine. I have talked with Simply.com and they provided me with the following log from their server.

80.210.78.x [10/Jul/2023:10:40:03 +0200] S480241 "GET /2/my/products/System.Object[]/dns/records HTTP/1.1" 404 130 "Mozilla/5.0 (Windows NT; Windows NT 10.0; en-DK) WindowsPowerShell/5.1.22621.1778" "-" "-"

is the get url suppose to have System.Object[] in it?

@rmbolger
Copy link
Owner

Ooh, that's good info and implies there's a bad assumption in the plugin itself. The code assumed it would get a single matching result from the API to find the zone ID and got multiple instead. So the variable that was inserted into the URL was an array object that gets serialized as that System.Object[] string rather than an actual string value.

Is it possible within the Simply.com control panel to create multiple copies of the same zone? The code that I think is essentially triggering this bug is here:

$match = $products | Where-Object { $zoneTest -eq $_.domain.name_idn }

But it implies that the previous API call to get the list of "products" on the account returns at least two results with the same domain.name_idn property. On a whim, I just manually queried my own old account that doesn't have any domains registered on it anymore. But the API returned results for two old domains that have long since expired.

However, the results contained duplicate data for both domains and I definitely never created more than one copy of either of them. There's also no difference in the data between the two copies of each domain. I'm thinking this is some sort of API or DB issue on the Simply.com side.

I'm really curious if you see the same thing on your account. Can you run the following using your own account ID and API key and maybe post the result here (sanitized if you want)? You could also email it to me at ryan-oss (at) xyto.cc. Here's the code.

$acct = Read-Host "Account ID"
$key = Read-Host "API Key"
$encodedCreds = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("$($acct):$key"))
$getParams = @{
    Uri = 'https://api.simply.com/2/my/products'
    Headers = @{Authorization="Basic $encodedCreds"}
}
Invoke-RestMethod @getParams | ConvertTo-Json -Depth 5

Assuming this is just a weird bug with Simply.com and there's not a legit reason there'd be multiple copies of the same zone on an account, it should be easy enough to work around in the plugin.

@rmbolger
Copy link
Owner

I pushed a change to the main/dev branch that should work around the problem assuming the duplicated domain data is just a mistake. I'd still love to see a copy of the output from the code snippet I posted. But this should theoretically fix your problem for now if you can test it.

@kaspersmjohansen
Copy link
Author

kaspersmjohansen commented Jul 12, 2023

Hi Ryan

I have multiple domains registered on my account at Simply.com and just like you, I see duplicate when running the Invoke-RestMethod command specified above.

Here is the sanitized (hopefully) information from my account:

{
    "products":  [
                     {
                         "object":  "domain1.dk",
                         "name":  "domain1.dk",
                         "autorenew":  true,
                         "cancelled":  false,
                         "domain":  {
                                        "name":  "domain1.dk",
                                        "name_idn":  "domain1.dk"
                                    },
                         "product":  {
                                         "id":  2,
                                         "name":  "basicsuite",
                                         "date_created":  1519015269,
                                         "date_expire":  1582087269
                                     },
                         "usernames":  {
                                           "ftp":  "domain1.dk",
                                           "ssh":  "domain1.dk",
                                           "mysql":  "domain1_dk",
                                           "mssql":  "domain1_dk"
                                       },
                         "servers":  {
                                         "webserver":  {
                                                           "hostname":  "example111.unoeuro.com",
                                                           "ip":  "1.2.3.4"
                                                       }
                                     }
                     },
                     {
                         "object":  "domain1.dk",
                         "name":  "domain1.dk",
                         "autorenew":  true,
                         "cancelled":  false,
                         "domain":  {
                                        "name":  "domain1.dk",
                                        "name_idn":  "domain1.dk"
                                    },
                         "product":  {
                                         "id":  2,
                                         "name":  "basicsuite",
                                         "date_created":  1519015269,
                                         "date_expire":  1708317669
                                     },
                         "usernames":  {
                                           "ftp":  "domain1.dk",
                                           "ssh":  "domain1.dk",
                                           "mysql":  "domain1_dk",
                                           "mssql":  "domain1_dk"
                                       },
                         "servers":  {
                                         "webserver":  {
                                                           "hostname":  "example111.unoeuro.com",
                                                           "ip":  "1.2.3.4"
                                                       }
                                     }
                     },
                     {
                         "object":  "domain1.dk",
                         "name":  "domain1.dk",
                         "autorenew":  true,
                         "cancelled":  false,
                         "domain":  {
                                        "name":  "domain1.dk",
                                        "name_idn":  "domain1.dk"
                                    },
                         "product":  {
                                         "id":  2,
                                         "name":  "basicsuite",
                                         "date_created":  1519015269,
                                         "date_expire":  1676781669
                                     },
                         "usernames":  {
                                           "ftp":  "domain1.dk",
                                           "ssh":  "domain1.dk",
                                           "mysql":  "domain1_dk",
                                           "mssql":  "domain1_dk"
                                       },
                         "servers":  {
                                         "webserver":  {
                                                           "hostname":  "example111.unoeuro.com",
                                                           "ip":  "1.2.3.4"
                                                       }
                                     }
                     },
                     {
                         "object":  "domain1.dk",
                         "name":  "domain1.dk",
                         "autorenew":  true,
                         "cancelled":  false,
                         "domain":  {
                                        "name":  "domain1.dk",
                                        "name_idn":  "domain1.dk"
                                    },
                         "product":  {
                                         "id":  2,
                                         "name":  "basicsuite",
                                         "date_created":  1519015269,
                                         "date_expire":  1613709669
                                     },
                         "usernames":  {
                                           "ftp":  "domain1.dk",
                                           "ssh":  "domain1.dk",
                                           "mysql":  "domain1_dk",
                                           "mssql":  "domain1_dk"
                                       },
                         "servers":  {
                                         "webserver":  {
                                                           "hostname":  "example111.unoeuro.com",
                                                           "ip":  "1.2.3.4"
                                                       }
                                     }
                     },
                     {
                         "object":  "domain1.dk",
                         "name":  "domain1.dk",
                         "autorenew":  true,
                         "cancelled":  false,
                         "domain":  {
                                        "name":  "domain1.dk",
                                        "name_idn":  "domain1.dk"
                                    },
                         "product":  {
                                         "id":  2,
                                         "name":  "basicsuite",
                                         "date_created":  1519015269,
                                         "date_expire":  1550551269
                                     },
                         "usernames":  {
                                           "ftp":  "domain1.dk",
                                           "ssh":  "domain1.dk",
                                           "mysql":  "domain1_dk",
                                           "mssql":  "domain1_dk"
                                       },
                         "servers":  {
                                         "webserver":  {
                                                           "hostname":  "example111.unoeuro.com",
                                                           "ip":  "1.2.3.4"
                                                       }
                                     }
                     },
                     {
                         "object":  "domain1.dk",
                         "name":  "domain1.dk",
                         "autorenew":  true,
                         "cancelled":  false,
                         "domain":  {
                                        "name":  "domain1.dk",
                                        "name_idn":  "domain1.dk"
                                    },
                         "product":  {
                                         "id":  2,
                                         "name":  "basicsuite",
                                         "date_created":  1519015269,
                                         "date_expire":  1550551269
                                     },
                         "usernames":  {
                                           "ftp":  "domain1.dk",
                                           "ssh":  "domain1.dk",
                                           "mysql":  "domain1_dk",
                                           "mssql":  "domain1_dk"
                                       },
                         "servers":  {
                                         "webserver":  {
                                                           "hostname":  "example111.unoeuro.com",
                                                           "ip":  "1.2.3.4"
                                                       }
                                     }
                     },
                     {
                         "object":  "domain1.dk",
                         "name":  "domain1.dk",
                         "autorenew":  true,
                         "cancelled":  false,
                         "domain":  {
                                        "name":  "domain1.dk",
                                        "name_idn":  "domain1.dk"
                                    },
                         "product":  {
                                         "id":  2,
                                         "name":  "basicsuite",
                                         "date_created":  1519015269,
                                         "date_expire":  1550551269
                                     },
                         "usernames":  {
                                           "ftp":  "domain1.dk",
                                           "ssh":  "domain1.dk",
                                           "mysql":  "domain1_dk",
                                           "mssql":  "domain1_dk"
                                       },
                         "servers":  {
                                         "webserver":  {
                                                           "hostname":  "example111.unoeuro.com",
                                                           "ip":  "1.2.3.4"
                                                       }
                                     }
                     },
                     {
                         "object":  "domain1.dk",
                         "name":  "domain1.dk",
                         "autorenew":  true,
                         "cancelled":  false,
                         "domain":  {
                                        "name":  "domain1.dk",
                                        "name_idn":  "domain1.dk"
                                    },
                         "product":  {
                                         "id":  2,
                                         "name":  "basicsuite",
                                         "date_created":  1519015269,
                                         "date_expire":  1645245669
                                     },
                         "usernames":  {
                                           "ftp":  "domain1.dk",
                                           "ssh":  "domain1.dk",
                                           "mysql":  "domain1_dk",
                                           "mssql":  "domain1_dk"
                                       },
                         "servers":  {
                                         "webserver":  {
                                                           "hostname":  "example111.unoeuro.com",
                                                           "ip":  "1.2.3.4"
                                                       }
                                     }
                     },
                     {
                         "object":  "domain2.dk",
                         "name":  "domain2.dk",
                         "autorenew":  true,
                         "cancelled":  false,
                         "domain":  {
                                        "name":  "domain2.dk",
                                        "name_idn":  "domain2.dk"
                                    },
                         "product":  {
                                         "id":  1,
                                         "name":  "dnsservice",
                                         "date_created":  1643709530,
                                         "date_expire":  false
                                     }
                     },
                     {
                         "object":  "domain2.dk",
                         "name":  "domain2.dk",
                         "autorenew":  true,
                         "cancelled":  false,
                         "domain":  {
                                        "name":  "domain2.dk",
                                        "name_idn":  "domain2.dk"
                                    },
                         "product":  {
                                         "id":  1,
                                         "name":  "dnsservice",
                                         "date_created":  1643709530,
                                         "date_expire":  false
                                     }
                     }
                 ],
    "status":  200,
    "message":  "success"
}

@kaspersmjohansen
Copy link
Author

kaspersmjohansen commented Jul 12, 2023

I have just tested with the updated Simply.ps1 script, and I still see the "unauthorized" error:

Just to make sure that it's not an error on my side, I have included a screenshot with the commands I use to update the
certificate on 2 of my domains:
image

EDITED - I just noticed that I am using the "SimplyAPIKeyInsecure" parameter, does that have anything to do with the error message?

@rmbolger
Copy link
Owner

I took the liberty of truncating your output and sanitizing the web server details just in case. But it basically confirms that something changed with how the Simply.com API is returning product details. Your "domain1.dk" has 8 almost identical results. The only difference between them seems to be the date_expire property as if the API is returning a copy of the data for each time you have renewed the domain.

As for your 401 Unauthorized error, that's different than the 404 error from before and implies you might have typo'd the account ID or API key or perhaps copy/pasted some extra characters. Using the "Insecure" vs secure param for it shouldn't make a difference. If you want to just test the plugin without going through the whole cert renewal process, give this a try.

$acct = Get-PAAccount
$Params = @{SimplyAccount='xxxx';SimplyAPIKeyInsecure='xxxx'}
$DebugPreference = 'Continue'
Publish-Challenge domain1.dk $acct faketoken Simply $Params -Verbose
Unpublish-Challenge domain1.dk $acct faketoken Simply $Params -Verbose

@kaspersmjohansen
Copy link
Author

The Publish-Challenge command works with the $Params specified, same with the Unpublish-Challenge.

However the Submit-Renewal now throws a 401 error consistently using the same $Params:
image

@AlexGuld
Copy link

I get the same with multiple domains replied for each domain registered.

I have raised a ticket at simply.com to ask if they have made changes to how the API replies. Perhaps some dev made some change he though was smart...

@AlexGuld
Copy link

Simply.com replies that it's by design, and the script should know what domain it's updating beforhand as is't part of the url when making a post to the server.

I have replied that it's curious that it fails now if they haven't made changes to the API.

@AlexGuld
Copy link

Workaround works.

@AlexGuld
Copy link

Simply.com has now corrected the API sho it only returns valid and active domains. So @kaspersmjohansen if you try now, do you now only see one of each domains you have?

@kaspersmjohansen
Copy link
Author

@Zaico the API fix works. Now I only have 1 entry per domain :)

@kaspersmjohansen
Copy link
Author

I still don't understand why I get the 401 error. As mentioned I am able to publish and unpublish a DNS challenge which I think is evidence that my credentials works with Simply.

Any insights into why the Submit-Renewal command fails?

@rmbolger
Copy link
Owner

@kaspersmjohansen Did your API key or account ID change at any point? It almost seems like the renewal command is using an old set of credentials on one or more of the existing orders. Give this a shot to view the associated credentials with each order:

Get-PAOrder -list | ?{ 'Simply' -in $_.Plugin } | %{ Write-Verbose $_.Name -Verbose; $_ | Get-PAPluginArgs }

Alternatively (or in addition), you could take your known good $Params variable and update the saved credentials on each order like this:

Get-PAOrder -List | ?{ 'Simply' -in $_.Plugin } | Set-PAOrder -PluginArgs $Params -Verbose

@kaspersmjohansen
Copy link
Author

@rmbolger I did rotate my API key recently. I'll update the API key and report back.

@kaspersmjohansen
Copy link
Author

@rmbolger it was the API key that caused the 401 error. With the workaround I am now able to get a new certificate, thank you for your help.

@rmbolger
Copy link
Owner

Hooray, both problems now solved.

Whatever Simply.com did to screw up their API results seems to have been reverted and I no longer get any results from the /my/products API endpoint for my account (as it should be since everything is long expired). I think I'll still push the workaround I commited into a new release in case it happens again though.

And @kaspersmjohansen also fixed the old credentials on saved orders causing 401 errors.

@rmbolger
Copy link
Owner

The workaround is now live in 4.19.0 in case this issue ever pops up again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants