-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
luci-app-acme: rename keylength to key_type #6415
Conversation
webroot should not be customizable. All httpds should just use the standardized path. Listing all credentials for all dns providers is impossible, since acme tries to be client agnostic. Users are expected to specify values pertain to the client they use. In other words, the Token example you use might only work for acme-acmesh, but not acme-uacme (if it’s created in the future). |
Ok, I added a DNS API specific fields. At first step only some popular but later I'll add all of them. I just want to make a cleanup in the acme.sh itself because now it's a mess. So a user now see The credentials field will be anyway visible and this may be confusing. I think that this is negligible a trade off. |
2a71070
to
171325a
Compare
@stokito First off, I want to thank you for taking the time writing this. Listing the DNS values must be a nontrivial work. However, as I mentioned previously, the values like I personally think we shouldn't explicitly list them. Users are expected to check OpenWrt documentation on acme (which should be updated) and use the dns value for the client they choose (e.g, acme-acmesh, acme-uacme, etc). For acme-acmesh it's |
The acme-uacme is not even created yet (right?). But also I honestly don't see any reason why to use it: it's written in C (so needs to be compiled for all routers and waste CI time), depends on gnutls and much bigger than acme.sh. The acme.sh is also bloated but still is smaller than the uacme. Currently uacme dns-01 supports only nsupdate, CF, gandi, deSEC.io. If in future the uacme will be supported we anyway need to change the UI to at least change translation keys and I'll do that. Instead of uacme maybe in future the only one alternative ACME client that can be supported is LE certbot. But it's depends on Python and heavy. Maybe for x86 it may make sense. |
acme-uacme only serves as an example. There are other potential clients like lego, which also has comprehensive support for dns-01. I think my point is, it's best if this package is client agnostic. Asking you and other maintainers to keep this package up-to-date whenever a new client is added is unsustainable, and supporting all DNS values for all clients could also bloat this package. |
The Lego is bloated too so I don't feel that this will be an issue in nearest years. We can solve problems for users today and once a new problems occur we can solve them latter. But maybe this won't happen if solve a root of a problem of many DSP APIs:
If none of them solved we can add a variable transform into OpenWrt acme. Today most users will use DuckDNS or some popular DNS provider like Gandi and use the acme.sh so this already covers 99% of users. The credetials edit is still visible for users so even if we won't update in future users still can add any credential var that they need. I really don't see problems here |
I'm not sure I understand the solutions you mentioned:
We are in circles. The current solution forces maintainers into a corner (supporting all DNS values for all clients). I don't understand why you would dismiss it as a non-issue. The acme package previously tried to update all available httpds after a certificate renews, and we migrated away from that. We should not fall into the same trap here. |
Yes but if they don't then we can convert here.
It works like: you configure a CNAME for your subdomain to the acme-dns.io subdomain and the TXT record is updated there. This works only for subdomains but covers many cases.
https://community.letsencrypt.org/t/dns-api-standard-or-specification/189887
There is no corner. A user can add any variable directly to the credentials input. If the acme.sh has a new provider then a user still can edit a UCI config manually. |
Not just credentials, also this:
This works for acme.sh but not lego for example.
There is no way to standardize DNS provider names, since they are endless. I think I've made my point clear and would stop from further reiterating. I'll leave it to @tohojo and @jow- to make the call. |
The whole discussion around multiple backends is a bit hypothetical given that we don't have more than one currently. I don't think we should be limiting ourselves because future clients may not support the same feature set; if this is the case, we can just add a check to the UI and remove/grey out the providers that are not supported by the currently installed backend. It a second client shows up that supports the same backend, but uses a different variable name to do so, that backend will just have to translate appropriately. Yes, this way we're making the acme.sh variable names the de facto "acme framework" names for those providers, but I don't think that's such a big deal: the names are a bit arbitrary anyway, and they're tied to the (often proprietary) provider anyway, so it's not like we have much say in the matter anyway. The best we can do is maybe bikeshed the names a bit, and sidestepping that by just going with the names that already exist is fine by me... However, I don't think we should be endorsing any particular provider by setting a default value. Users will need to have an account with a provider before configuring this anyway, so let's just list the providers alphabetically, and they can pick whichever one works for them. |
Why not? Because lego doesn't support that provider at all? Then we can just prune the list according to which backend is installed, as mentioned above... (Side note, I don't think lego is going to be usable on openwrt at all since golang only has limited architecture support, sadly) |
I agree and I even implemented some JS code to pre-selct the dns_duckdns if the domain ends with .duckdns.org and similarly for freedns. But it works with a bug so I didn't included it into the PR. The main reason why I kept the duckdns by default is that if no default specified then anyway a first item will be selected e.g. 1984.is. So anyway we have a problem here so I decided to keep the DuckDNS by default which I believe should be the most popular option in context of routers. Generally speaking this can be solved in a nice way. @tohojo JFYI the Lego has a PR for the DuckDNS and also Golang can be compiled to MIPS (I used a Golang program on TPLINK wrn1043nd) |
I'm writing acme-lego as we speak, I don't have an ETA, but it's not very far away.
Because this value, as far as acme-common is concerned, is passed directly to the client. It's
I want to add that acme-common doesn't care what's the de facto acme framework, it just passes down the specified value to clients.
That's another issue. This means this package also needs to have a list of what providers are supported by each client. The whole name conversion and provider list could be avoided, if this package simply offers a text field like how acme-common handles it. |
Right, but that's kinda fundamental when the clients can't agree, no? Either acme.sh has to convert from "cloudflare" to "dns_cf", or lego has to do the reverse.
Right, but that's just bailing out and leaving the user to deal with the incompatibility. If acme-common is supposed to be an abstraction layer, we need to deal with this sort of incompatibility somehow. The goal of having a common format for |
I'm not sure this was considered when developing acme-common. Even the same config can mean different things for different clients. For example, days mean how many days have passed in acme.sh, but how many remains in lego. The calias and dalias options aren't guaranteed to work the same way across different clients either. Precisely define what each config means and have different clients do the conversion is not really feasible, even if it is, users aren't supposed to switch clients frequently, is it really worth every client maintainer's effort to support this? IMHO acme-common exists mostly to address code reuse. |
Another difference: days is only consulted when issuing in acme.sh, but for lego, it's only consulted when renewing. There is no way to make lego behave the same as acme.sh. There can be many subtle differences like this. The point is, have an universal config that works across clients is a really hard promise to keep. |
A small off topic: On the UI we need to show a link to acme.sh Wiki with instructions for the DNS provider. I just added anchors for each DNS provider with the same name as it's code e.g. https://github.com/acmesh-official/acme.sh/wiki/dnsapi#dns_aws So now we need to add some JS handler that will change the link to a wiki when the DNS provider dropdown is changed |
7c6c728
to
576a6be
Compare
Ok, so I made the dynamic URL to DSN API Wiki with instructions. |
applications/luci-app-acme/root/usr/share/rpcd/acl.d/luci-app-acme.json
Outdated
Show resolved
Hide resolved
applications/luci-app-acme/htdocs/luci-static/resources/view/acme.js
Outdated
Show resolved
Hide resolved
Yes, I definitely think we should strive for compatibility. It may not be achievable for all things, but it's fine to have some things that are only supported by one client, when that is not avoidable. Then we can just disable those config options when an incompatible client is installed (or consider not supporting such options at all if they're not really needed). Having different semantics for the same config option we should definitely avoid, though! In that case they should have different names (and only work for the client that supports them). It's not really clear to me why supporting a lot of different clients is useful, though. I can maybe see the value of supporting uacme assuming it can be made smaller than acme.sh (since acme.sh pulls in the openssl binaries), but what's the benefit of lego, exactly? :) |
@tohojo I fixed your comments, please check |
@tohojo It turns out that we can allow only to list files without reading them. So I restored the certificates tab because I believe it will be useful. |
For a new client author, finding out what options are unsupportable is the easy part. It doesn't create compatibility issues since the client can just ignore the options.
The hard part is that author has to be aware it's different before she can avoid. Unless we provide a clear document or the author is very familiar with acme.sh, it can be really hard to discover days might not mean what she thought it meant for example. The extra effort involves understanding how the options work in acme.sh and how they differ from the new client. Another big issue is that how credentials should be supported. Currently, this package uses acme.sh specific values like This package, as it is, means it will be very difficult for me to contribute the lego client.
It has both comprehensive DNS support and no dependencies on openssl. acme.sh and uacme only has either one of the benefits. It shouldn't matter unless we want to endorse acme.sh and discourage other new clients.
I'm not sure this is a good strategy. The original goal was that writing a new client should be easy, since it can leverage a lot of existing code from acme-common, but now it becomes that writing a new client is discouraged, because we thought "supporting a lot of different clients isn't useful" and it requires deep understanding of acme.sh first. Even if good acme clients are few now (which I'm not sure is true), the acme spec can still innovate and warrants new client to pop up. |
To provide a more concrete example. Let’s say the lego package wants to support days, what it should do? Since converting remaining days to days passed requires parsing the notAfter value from the certificate, and the lego cli doesn’t offer that, the package has to introduce another option like days_remain. So now the user has to modify the config any way in order for it to work the same way after switching from acme.sh to lego. And what should this LuCI package do? Detecting what client is used and hide show options as needed? Plus the DNS provision list it has to support, this quickly gets out of hand. I want to propose that we standardize option names, not their precise meanings. This means we shouldn’t standardize option values, unless it’s a well defined one like key_type (and doesn’t have many values, so it’s manageable for clients to convert from). This makes writing both new client packages and this package much simpler. The only downside is that users are required to modify config when they switch clients. I think it should be obvious it’s a good trade? And as I mentioned, that downside can’t be eliminated anyway. |
The columns makes little sense and instead we can keep more space for domains. The days is really advanced option that is better not to change and it's support may be removed for simplicity. Signed-off-by: Sergey Ponomarev <[email protected]>
The keylength option was renamed to key_type and values changed. See openwrt/packages@6d61014 Make it optional to let acme.sh to decide (currently ec256) Signed-off-by: Sergey Ponomarev <[email protected]>
Signed-off-by: Sergey Ponomarev <[email protected]>
The options are useful only for experienced users. Signed-off-by: Sergey Ponomarev <[email protected]>
The options now removed completely and hotplug hooks will be used instead. Signed-off-by: Sergey Ponomarev <[email protected]>
The validation_method is now set to webroot by default. This is the most used option. The webroot option is now empty by default. Into the description added that by default will be used /var/run/acme/challenge/ Webservers should serve the folder under /.well-known/acme-challenge/ url. The folder is automatically created by the acmesh service on renewal. The Challenge Validation Tab is split to Webroot and DNS and the validation method moved to general tab. So ideally a user won't see the webroot folder option from other tab. And a user can basically enable the webroot just in the general tab without leaving it. The DNS validation needs too many options to it needs for own tab. Signed-off-by: Sergey Ponomarev <[email protected]>
To simplify configuration we need a list of all supported providers. Each provider has own set of params. We should show them when a user selected a provider. To help a user to find instruction for the provider we will generate a link to Wiki. A user still can change the Credentials option manually. Signed-off-by: Sergey Ponomarev <[email protected]>
Add rationale how the email is used. The translation key is separate to keep an existing translation. Signed-off-by: Sergey Ponomarev <[email protected]>
Add Certificates section to help users to see issued certificates and path to them. Signed-off-by: Sergey Ponomarev <[email protected]>
Keys were rearranged automatically. Signed-off-by: Sergey Ponomarev <[email protected]>
Signed-off-by: Sergey Ponomarev <[email protected]>
Signed-off-by: Sergey Ponomarev <[email protected]>
Signed-off-by: Sergey Ponomarev <[email protected]>
The key type was rearranged. Signed-off-by: Sergey Ponomarev <[email protected]>
@tohojo @systemcrash I fixed many small issues and re-committed with more clear changes. |
Right, so after reviewing this discussion again: if the expectation is that the supported fields and/or there semantics is going to vary between different clients, that means that we're going to have to make adjustments in the UI depending on which client is installed in any case. In which case I don't see any obstacles to merging this, including the DNS provider list. @hgl WDYT? |
Not if we only standardize option names and not values, but I guess making the UI offer values does make it more user friendly. I can get behind it since you gave the green light. And maybe we only need to consider this once multi-client support is really needed, but just to put it out there: we might need to consider what should happen if the user uninstalls the current client and installs a new one. For new options, maybe we can just display an empty value. For options with the same name but different values (e.g., DNS provider), the current value is invalid, maybe the field should be marked with error or something? |
Cool. Merging, then :)
Yeah, hard to discuss all that in the abstract, let's evaluate once we actually have another client implementation to look at... |
thank you all! |
FYI: I sent a PR to acmesh where proposed to get automatically the list of DNS provides and their options acmesh-official/acme.sh#4738 |
So, I had to change this manually in my config still in |
@LokeYourC3PH it's already merged and available. About a month ago I also added a script to migrate the old options to new. FYI: You can remove the key_type and by default it will be ec256 which is shorter and supported by all modern servers. |
Well whatever it is, on my Linksys E7350 (ramips/mt7621) running OpenWRT 23.05.3 r23809-234f1a2efa, the latest |
Maybe the change wasn't backported yet to the 23.05 (i.e. May of 2023, the PR was merged later). |
It's as a matter of fact completely deprecated and doesn't work as it seems:
|
Ryan ***@***.***> writes:
> Maybe the change wasn't backported yet to the 23.05 (i.e. May of 2023, the PR was merged later).
> This is a minor thing and the old keysize option is still supported.
It's as a matter of fact completely deprecated and doesn't work as it seems:
`daemon.warn acme: Option "keylength" is deprecated, please use key_type (e.g., ec256, rsa2048) instead.`
The code that emits this warning goes on to convert the old value, so
things should work just fine apart from that message in the logs...
|
The acme.sh package was changed recently:
@tohojo @hgl Please explain how to specify that I do really want to use a webroot but with the new
/var/run/acme/challenge
folder. The entire webroot option was deprecated so how the acme can distinguish webroot with a custom path like/var/www/acme/
and the new folder?For now I made the
/var/run/acme/challenge
as a default value. So in the script you can just check if it's not the default value or empty and only then write a deprecation notice.The current validation method is standalone, maybe we should change it to a webroot?
@jow- Please give an advice. We have a DNS API and for example for the DuckDNS:
The problem is that the credentials is list of properties but I wish to turn it into a plain form. So when selecting a provider it's specific fields will be shown.
E.g. for the DuckDNS just show a field "Token" but on the form save it will be added to the
list credentials 'DuckDNS_Token
. How to make this saving?For each provider we need a separate fields but it should be enough to just support a few main (Gandi, Cloudflare) and some standard like acmedns and nsupdate.
CC @jannispinter @zhanhb