Repository: go-acme/lego (language: go)

Issue:
infomaniak: does not create TXT record, so fails to renew certificates
### Welcome

- [X] Yes, I'm using a binary release within 2 latest releases.
- [X] Yes, I've searched similar issues on GitHub and didn't find any.
- [X] Yes, I've included all information below (version, config, etc).

### What did you expect to see?

The Infomaniak DNS provider no longer seems to work with their API. I have experienced this with several of the domains hosted with them.

The issue seems to be that, even though I have set up the appropriate permissions in their API token manager (`domain, domain:read, domain:write, dns:read, dns:write`) the plugin does not seem to automatically create the TXT record as it should.

@L3o-pold was the initial creator of the integration and supports it, so I will tag him.

### What did you see instead?

When running the command given, with a working token (I checked it with cURL) it will never renew the certificate.

```
$ INFOMANIAK_ACCESS_TOKEN=****************** /usr/local/bin/lego --accept-tos --dns.propagation-disable-ans --dns infomaniak --domains sub.domain.io --email security@domain --path /etc/nginx/ssl renew --renew-hook="systemctl restart nginx"
2024/12/02 08:10:33 [INFO] [linked.rism.io] acme: renewalInfo endpoint indicates that renewal is needed
2024/12/02 08:10:33 [INFO] [linked.rism.io] acme: Trying renewal with 485 hours remaining
2024/12/02 08:10:33 [INFO] [linked.rism.io] acme: Obtaining bundled SAN certificate
2024/12/02 08:10:33 [INFO] [linked.rism.io] AuthURL: https://acme-v02.api.letsencrypt.org/acme/authz/1463112246/438693874647
2024/12/02 08:10:33 [INFO] [linked.rism.io] acme: Could not find solver for: tls-alpn-01
2024/12/02 08:10:33 [INFO] [linked.rism.io] acme: Could not find solver for: http-01
2024/12/02 08:10:33 [INFO] [linked.rism.io] acme: use dns-01 solver
2024/12/02 08:10:33 [INFO] [linked.rism.io] acme: Preparing to solve DNS-01
2024/12/02 08:10:34 [INFO] domain "_acme-challenge.sub.domain.io" not found, trying with "sub.domain.io"
2024/12/02 08:10:34 [INFO] domain "linked.rism.io" not found, trying with "domain.io"
2024/12/02 08:10:36 [INFO] [linked.rism.io] acme: Trying to solve DNS-01
2024/12/02 08:10:36 [INFO] [linked.rism.io] acme: Checking DNS record propagation. [nameservers=127.0.0.53:53]
2024/12/02 08:10:38 [INFO] Wait for propagation [timeout: 1m0s, interval: 2s]
2024/12/02 08:10:45 [INFO] [linked.rism.io] acme: Cleaning DNS-01 challenge
2024/12/02 08:10:46 [INFO] Deactivating auth: https://acme-v02.api.letsencrypt.org/acme/authz/1463112246/438693874647
2024/12/02 08:10:46 error: one or more domains had a problem:
[linked.rism.io] acme: error: 400 :: urn:ietf:params:acme:error:dns :: DNS problem: NXDOMAIN looking up TXT for _acme-challenge.sub.domain.io - check that a DNS record exists for this domain
```

### How do you use lego?

Binary

### Reproduction steps

1. Have a domain hosted by Infomaniak
2. Create a new API token with `domain:read, domain:write, dns:read, dns:write` privileges
3. run the lego command with the API token, and it will fail to create the TXT record

### Version of lego

```console
lego version 4.20.4 linux/amd64
```


### Logs

<details>

```console
# paste output here
```

</details>

### Go environment (if applicable)

<details>

```console
$ go version && go env
# paste output here
```

</details>


Discussion / hints:
Can you try with a token that has all the scopes?
Ah, that seems to work?
I think the scope `product:read` is needed, if this scope exists.

Because the client calls:
- `/1/domain/`
- `/1/product/`
If I remember well the `products` scope is needed yes. I'll confirm that and fix the documentation if needed.
I can try and confirm this too. 
can you try with `INFOMANIAK_TTL=300` ?
Hm. I don't see a `product:read` scope?

Here is a list of the scopes that I can see:

```
All 
user_email - Access your profile email address 
user_info - Access your profile informations 
accounts - List and handle client accounts 
users - List and handle account users 
sms - Manage your SMS 
video - Video products 
vod - VOD products 
event - Access Infomaniak Events 
user_info_contact - Access your contact informations 
profile_update - Update your profile informations 
nas - NAS products 
user_password - Manage your passwords 
newsletter - Newsletters 
mail - Hosting mail products 
web - Hosting web products 
invoicing - Bills and orders, use our payment API 
affiliation - Affiliation program 
housing - Housing products 
domain - Domain names products 
vps - VPS products 
certificates - SSL Certificates products 
jelastic - Jelastic products 
eticket - Eticket products 
radio - Radio products 
swiss-backup - Swiss Backup products 
workspace:mail - Manage your emails 
workspace:contact - Manage your contacts 
workspace:calendar - Manage your calendars 
cloud-hd - Cloud HD products 
drive - Drive products 
website_builder - Website Builder products 
kmeet - kMeet 
public_cloud - Managing your Public Cloud 
safetracing - Managing your Safetracing data 
kchat - Access kChat 
ai-tools - AI Tools 
chk - Chk 
domain:read - (API Scope) Access domain products informations 
domain:write - (API Scope) Manage domain products 
dns:read - (API Scope) Access zones and dns records informations 
dns:write - (API Scope) Manage zones and dns records 
```
I don't think that changing the TTL will fix the problem.
If it's a propagation issue, the env var `INFOMANIAK_PROPAGATION_TIMEOUT` will have more impact.
> Hm. I don't see a product:read scope?

no it should not be needed

> I don't think that changing the TTL will fix the problem.

no I think it's an API validation issue.

please try settings a default TTL to 300 to check.
> no I think it's an API validation issue.

I don't think so, NXDOMAIN error is, in 90% of the cases, related to a propagation issue because it's DNS error and not an API error.
So you can try `INFOMANIAK_PROPAGATION_TIMEOUT=120` `INFOMANIAK_POLLING_INTERVAL=20`
Do you remember why you set the default TTL to this huge 7200?
Globally we use a default TTL of 120 with the other implementations.

I was able to get a renewal with `INFOMANIAK_PROPAGATION_TIMEOUT=120 INFOMANIAK_POLLING_INTERVAL=20` on a certificate that had previously failed, even with a token with all scopes. 

I will try to find another domain and see if a token with limited scopes works with that as well? 


> Do you remember why you set the default TTL to this huge 7200?

no but 120 TTL is not yet supported, 300 is
> no but 120 TTL is not yet supported, 300 is 

Ok but this is not the question :smile: 
Why 7200?
it's the no part in the answer, I don't remember.
ok, depending on the @ahankinson feedback, the default propagation timeout can be changed.
If I add `INFOMANIAK_PROPAGATION_TIMEOUT=120 INFOMANIAK_POLLING_INTERVAL=20` to a request with a token with limited scopes (`domain, domain:read, domain:write, dns:read, dns:write`) it seems to work OK.

If I leave off the timeouts and polling intervals, the same token fails with:

`acme: error: 400 :: urn:ietf:params:acme:error:dns :: DNS problem: NXDOMAIN looking up TXT for _acme-challenge.domain.io - check that a DNS record exists for this domain`

So it seems to be a problem with the timeouts? 
ok thank you :+1: we will adjust the default timeout.

Fix patch:
diff --git a/providers/dns/infomaniak/infomaniak.go b/providers/dns/infomaniak/infomaniak.go
index 84f4942148..79c6f577e6 100644
--- a/providers/dns/infomaniak/infomaniak.go
+++ b/providers/dns/infomaniak/infomaniak.go
@@ -47,9 +47,9 @@ type Config struct {
 func NewDefaultConfig() *Config {
 	return &Config{
 		APIEndpoint:        env.GetOrDefaultString(EnvEndpoint, internal.DefaultBaseURL),
-		TTL:                env.GetOrDefaultInt(EnvTTL, 7200),
-		PropagationTimeout: env.GetOrDefaultSecond(EnvPropagationTimeout, dns01.DefaultPropagationTimeout),
-		PollingInterval:    env.GetOrDefaultSecond(EnvPollingInterval, dns01.DefaultPollingInterval),
+		TTL:                env.GetOrDefaultInt(EnvTTL, 300),
+		PropagationTimeout: env.GetOrDefaultSecond(EnvPropagationTimeout, 2*time.Minute),
+		PollingInterval:    env.GetOrDefaultSecond(EnvPollingInterval, 10*time.Second),
 		HTTPClient: &http.Client{
 			Timeout: env.GetOrDefaultSecond(EnvHTTPTimeout, 30*time.Second),
 		},


Test patch: