-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
Provide dnsChallenge credentials per resolver #5472
Comments
Hi @bstuff , thanks for reporting this use case. This issue is labelled as "proposal" as there should be a discussion on the topics below: It looks like that implementing this would require the following challenge to be solved:
Finally, please note that this proposal would lead to some changes in Lego (the library used for ACME usage in Traefik), not only on Traefik. |
This comment has been minimized.
This comment has been minimized.
May be a solution is to run the edit: or is there any way to reload bound certificates on-demand? |
I have a specific use case for this, which I hope will bring interest to this feature request. I share a server with someone, and we have two domains, one each. We use Traefik to redirect users to our respective containerized services and provide the respective certificates, which are both wildcard certs. It'd be a great value to add this feature to Traefik, since I think it matches its philosophy quite well. #5632 seems related |
Here is an idealized
Edit: few inconsistencies |
I'm wondering if it would be possible to ask traefik to update the env variables before a call into lego client. It is not ideal, because at the moment traefik does not even know that they exist, and it will have to. But the advantage of that approach is that lego won't need to be changed. Of course it will require synchronisation so no more than one challenge for a particular dns provider is running at the same time, but this seems doable. This could be an interim solution, until we can figure out how to do this better, it does not seem that there are a lot of options though. Otherwise people have no choice but to run two instances of traefik. |
This comment has been minimized.
This comment has been minimized.
I have a similar need -- I am looking for options to leverage multiple godaddy accounts (several different API keys). Here is a link to a thread I started in the community on it (almost identitical to @bstuff original post Any chance of getting this into the road map? Right now it seems the only option is to run multiple copies of traefik (different docker servers). |
any news here ? |
Could a temp solution be to use "External Program" provider? |
Is it possible to use for example "certs bots" and provide the certificat to traefik ? |
Any updates here? |
No news for me ... |
@ldez maybe you have some thoughts on how can this issue be resolved properly? Right now this issue seems to be abandoned and I'd like to bump it. |
I hope this gets fixed soon. I'm stuck using let's encrypt for a whole set of subdomains and I can't assign a new acme provider without dns challenge. I don't want to try to run two traefik instances and combine them or something. - --certificatesresolvers.resolverA.acme.caServer=
- --certificatesresolvers.resolverA.acme.email=
- --certificatesresolvers.resolverA.acme.storage=/acme.json
- --certificatesresolvers.resolverA.acme.eab.kid=
- --certificatesresolvers.resolverA.acme.eab.hmacEncoded=
# cloudflare dns challenge
- --certificatesresolvers.resolverA.acme.dnsChallenge.provider=cloudflare
# this!!! it should be local not global!
- --certificatesresolvers.resolverA.acme.dnsChallenge.env.CF_API_EMAIL=
- --certificatesresolvers.resolverA.acme.dnsChallenge.env.CF_API_KEY= I don't see this being too hard to implement? When registering I would add it in myself but I've never used go before. |
Okay I see the problem. This is where it fetches things: |
Lego calls a function named Which will look for CF_API_EMAIL_FILE and read it's contents. This sounds so silly, but if you were to create a temporary file and write to it before initializing the dns provider... haha nevermind... It doesn't look there's an easy fix other than working together with the lego people to add a new function to replace here: traefik/pkg/provider/acme/provider.go Line 269 in ce2e02b
|
I found this issue after a discussion with a user who is impacted by this. Not sure why recent comments that share community-based investigations toward a solution (for example those by @MAKITSUNE) are being marked as off-topic, especially while repeated comments that only ask for updates remain unflagged. This community-driven sharing is what makes open source productive and useful. I think they should be un-flagged to reveal useful information and add context to what's happening in the code. Indeed, as @MAKITSUNE shows, the underlying ACME library, lego, reads DNS provider credentials from environment variables. This makes it difficult/impossible to configure different provider credentials in a single environment, at least with the current implementation of lego. While my comment will probably get hidden, I wanted to propose a solution to be considered anyway, with some background. About a year and a half ago, I raised an issue in lego similar to this one, and later proposed a change that treated env vars as optional defaults instead of as the only way to configure the credentials. I admit I wasn't able to design a satisfactory solution without making other major changes to the code base, so I let the PR be closed. My solution instead was to write a leaner ACME library named The DNS solver I implemented is in CertMagic, and it's an exported type so it can be used by any library, including lego. Notice that the DNSProvider field is a type that uses any type ACMEDNSProvider interface {
libdns.RecordAppender
libdns.RecordDeleter
}
(We know this works because this is what Caddy 2 uses to support multiple DNS credentials per config.) tl;dr - Using |
@mholt excellent suggestion and approach. Hopefully the traefik team is interested in it. |
To illustrate more concretely, here is what a solution could look like (again, this would have to go inside lego, probably -- and I've omitted details like getting the ACME account and private key): client := acmez.Client{
Client: &acme.Client{
Directory: "https://...",
},
ChallengeSolvers: map[string]acmez.Solver{
acme.ChallengeTypeDNS01: &certmagic.DNS01Solver{
// notice that credentials are not provided by env vars (but could be by using os.Getenv)
DNSProvider: &cloudflare.Provider{
APIToken: "secret",
},
},
},
}
ctx := context.Background()
// put your domains here that are associated with the DNS credentials above
domains := []string{"example.com"}
certs, err := client.ObtainCertificate(ctx, acmeAccount, certPrivateKey, domains) Notice how DNS providers can be plugged into the solver config easily, and doesn't require the use of env vars, but does allow them if you want. An approach/API like this could resolve the issue because you can specify different DNS credentials for different domains in your Traefik config. But I do think actual dev work would need to be tracked in go-acme/lego. |
The suggestions made by @MAKITSUNE and @mholt are based on the same assumption that all DNS providers can be configured via environment variables or with a simple configuration structure but this assumption missed that there are several ways to configure DNS providers and some of them don't use environment variables/configuration structure but elements based on the system configuration. The problem has been already explained here:
Be sure that I know really well the problem, I have already spent a lot of time trying to find a solution, and I still looking for a viable approach.
If you want to discuss more feel free to open an issue on lego. |
Question, have you seen the approach that Posh-Acme? The model he took seems to work well with almost any DNS based system. |
Maybe this sounds silly and might not be possible in go, but when using node sounds reasonable: to spin up a new thread/instance with the resolver defined environment variables and close it when its done. |
I know the other ACME client implementations and in Go we have Go routines (~threads) but it's neither the problem nor the solution. I will repeat: some DNS providers don't use environment variables/configuration structure but elements based on the system. Please, if you want to discuss more feel free to open an issue on lego. |
Can you help us understand what you mean by that? Like what are examples of DNS libraries that can only be configured by external settings and not by code? |
Please, if you want to discuss more feel free to open an issue on lego. |
If going by the replies there seems no option other than to consolidate all domains into one authoritative DNS provider (Cloudflare in my case) and then use |
A solution can be to use CNAME: you add CNAMEs redirecting to only one domain, and you will only need one account. If you have |
Thank you, this works perfect! For anyone using Cloudflare, do not forget to turn off the "Orange" proxy for the |
This comment was marked as off-topic.
This comment was marked as off-topic.
I hit a roadblock with this. I want to get traefik to request wildcard certificates from letsencrypt, for domains hosted on separate Gandi accounts, but it seems that I can only use a single gandi api key. I hope this feature will be added in the near future. |
welcome to 2024. it is shame that traefik cannot handle functionality which can be handled by caddy2. Well if you so stuck with Env variables why just not to have some kind of PROXY env variable which will be filled in before lego lib execution. For example it is possible to have inside traefik API_key1 = "...", API_key2 = "...", API_key3 = "...". And in moment of execution of challenge just to fill in from API_key1 to for example CF_DNS_API_TOKEN . After challenge passed assign next API_key2 to CF_DNS_API_TOKEN and execute next challenge. I really don`t get what problem with it. it is even possible to do hacky way. To attach to process and call setenv . |
Closed by #10496. |
I take it this will not be implemented? If so, that is a bummer. |
Especially because the 'cname' way is not what this feature is about: example.org is not supposed to be an 'alias' for example.com... |
May be as alternative solution will be good to implement directory or certificate watch and reload certificates in moment if updated certificate in certificate folder. In that case it will be quite easy to use certbot and cron to update certs. |
The CNAME alias is not on |
Oooh weew sorry @ldez! I just saw your comment higher up and link, now I get it! |
To clarify the situation, as @ldez explained here, today there is no way to support multiple ACME accounts due to the heterogeneous DNS challenges implementations. The workaround that Let's Encrypt proposes is to use CNAME. Not only this solves this issue, but it brings additional benefits. I invite you to read the Let's Encrypt blog post.
|
Do you want to request a feature or report a bug?
Feature
What did you expect to see?
multiple resolvers is 🔥
but what if I have multiple accounts
something like this:
use case: Traefik running multiple domains that belongs to different accounts on Cloudflare
The text was updated successfully, but these errors were encountered: