onur / acme-client Goto Github PK
View Code? Open in Web Editor NEWYet another Let's Encrypt client and library written in Rust.
License: MIT License
Yet another Let's Encrypt client and library written in Rust.
License: MIT License
When terminating TLS for several applications on a single server (e.g. webserver, mailserver, xmpp), sometimes you have to provide the certificate and the intermediate in separate files, sometimes in one.
I'd like letsencrypt-rs
to be able to handle that, via multiple options.
Instead of -c
appending the intermediate, there could be:
-o
for the certificate only-i
for the intermediate only-c
(or something non-conflicting) for the whole chainIt might very well be that this is already possible and I just missed it though.
A project with the dependency
acme-client = {version="0.5", default-features = false}
does not even compile:
$ cargo build
Updating crates.io index
error: failed to select a version for the requirement `security-framework = "^0.1.9"`
candidate versions found which didn't match: 2.6.1, 2.6.0, 2.5.0, ...
location searched: crates.io index
required by package `native-tls v0.1.0`
... which satisfies dependency `native-tls = "^0.1"` of package `hyper-native-tls v0.2.0`
... which satisfies dependency `hyper-native-tls = "^0.2"` of package `reqwest v0.6.0`
... which satisfies dependency `reqwest = "^0.6"` of package `acme-client v0.5.0`
... which satisfies dependency `acme-client = "^0.5"` of package `warehouse v0.1.0 (/home/user/warehouse)`
This issue may be related to #43.
A CSR can already have the domains (CN & SAN, although SAN must always contain the CN) embedded.
In that case an option for using those domains automatically (not requiring --domain
) would be desirable.
That way you can generate working CSRs and use letsencrypt-rs without any configuration (except for where the files are of course).
acme-client $ rg contract
src/lib.rs
726: map.insert("contract".to_owned(), to_value(contact)?);
728: map.insert("contract".to_owned(),
contract
should be contact
?
Right now, write_signed_certificate (and save_signed_certificate) will save the chain (or only the certificate) iff the chain_url has been set before. I propose adding explicit methods for it and deprecating the two existing methods. What do you think?
Would be nice for letsencrypt-rs to support signing multiple domains, something like this: https://community.letsencrypt.org/t/host-multiple-domains-with-a-single-certificate/20917/2
acme-client depends on an old version of reqwest which in turn depends on an old version of the openssl crate. The old openssl crate is not able to use at least openssl 1.1.1 (I don't know the exact version where it stops working)
thread 'main' panicked at 'Unable to detect OpenSSL version', /.../registry/src/github.com-1ecc6299db9ec823/openssl-0.9.24/build.rs:16:14
stack backtrace:
0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
at libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
1: std::sys_common::backtrace::print
at libstd/sys_common/backtrace.rs:71
at libstd/sys_common/backtrace.rs:59
2: std::panicking::default_hook::{{closure}}
at libstd/panicking.rs:211
3: std::panicking::default_hook
at libstd/panicking.rs:227
4: std::panicking::rust_panic_with_hook
at libstd/panicking.rs:476
5: std::panicking::begin_panic
6: build_script_build::main
7: std::rt::lang_start::{{closure}}
8: std::panicking::try::do_call
at libstd/rt.rs:59
at libstd/panicking.rs:310
9: __rust_maybe_catch_panic
at libpanic_unwind/lib.rs:102
10: std::rt::lang_start_internal
at libstd/panicking.rs:289
at libstd/panic.rs:392
at libstd/rt.rs:58
11: main
12: __libc_start_main
13: _start
The Documentation link on https://crates.io/crates/letsencrypt-rs links to https://docs.rs/acme-client which currently gives a 403 Forbidden. https://beta.docs.rs/crate/letsencrypt-rs/ works.
Seems to be possibly two issues:
acme-client
instead of letsencrypt-rs
.docs.rs
instead of beta.docs.rs
(not sure if this is actually an issue with letsencrypt-rs
or if docs.rs
needs to be fixed to no longer 403).The README says, "Easy to use Let's Encrypt compatible ACME client to issue, renew and revoke TLS certificates.", but there's no other mention of renewing. Is the renew process just the sign process repeated or are their different steps?
Actually what I wrote below does not make much sense. I'm not sure why the challenge ends up stuck in pending :-/
When testing this client through a TLS SNI tunnel from ngrok letsencrypt likes to solve the TLS SNI challenge most of the time rather than the HTTP challenge. This causes the validation to end up in a bad state (urn:acme:error:malformed Unable to update challenge :: provided key authorization was incorrect
).
The solution here is to do this instead:
let http_challenge = authorization
.get_http_challenge()
.ok_or_else(|| err_msg("HTTP challenge not found"))?;
// ...
if !authorization
.get_tls_sni_challenge()
.map_or(false, |sni_challenge| sni_challenge.validate().is_ok())
{
http_challenge.validate().map_err(SyncFailure::new)?;
}
From the letsencrypt forums it sounds like one should not check against an individual challenge:
There has been some confusion stemming from this change and so I wanted to follow-up with a quick note about challenge status.
If your client creates an authorization object and expects to solve multiple challenges it will appear as though some of the challenges are stuck in a pending state. Once the first challenge for an authorization is satisfied and valid the overall authorization changes to valid and no subsequent challenges will be updated. E.g. if I create an authorization and complete the http-01 challenge the authorization will be marked valid and the dns-01 and sni-01 challenges will remain in a pending state.
The best approach from a client perspective is to check the status of the authorization object rather than individual challenge objects. That way if the authorization object is already in “valid” state the client can cease further processing of challenges.
(https://community.letsencrypt.org/t/upcoming-change-valid-authz-reuse/16982/6?u=cpu)
However from what I can tell checking the authorization object is not supported by this library.
We (ISRG / Let's Encrypt) do not allow clients to use our service's name in their client name. We recommend you use the term "ACME" instead, in reference to the protocol. This is better because there are no trademark issues and the protocol is not specific to our CA so your client should work with other ACME-enabled CAs in the future.
I know this can be a pain but we have to insist that the name change. Thanks for understanding.
The registration is now failing as per announcement:
https://community.letsencrypt.org/t/end-of-life-plan-for-acmev1/88430
Please consider making a version that works with the upgraded openssl package. Perhaps in a different branch? Right now the crate isn't compatible with hyper-native-tls = "0.2.2" (needed for TLS in Hyper 0.10) because of it's older openssl-sys dependency.
The openssl
dependency makes cross-compilation very hard. (Once there is feature parity, I would be in favor of replacing it with webpki
.)
Even when cross-compilation succeeds, the letsencrypt-rs
fails for me at runtime.
I compiled openssl
under Arch Linux, as required by the openssl
crate:
sudo pacman -Syu musl
mkdir /opt/openssl/
cd /srv/installers/
curl --tlsv1.2 -O 'https://www.openssl.org/source/openssl-1.1.0e.tar.gz'
tar xf 'openssl-1.1.0e.tar.gz'
cd 'openssl-1.1.0e/'
export CC='musl-gcc'
./Configure no-unit-test no-async no-afalgeng no-ui \
--prefix=/opt/openssl/ linux-x86_64 -fPIC
make -j"$(nproc)"
sudo make install
Then I compiled letsencrypt-rs
:
cd "$HOME/devel/github.com/onur/letsencrypt-rs/letsencrypt-rs/"
env PKG_CONFIG_ALLOW_CROSS=1 OPENSSL_STATIC=1 OPENSSL_DIR=/opt/openssl/ \
cargo build --release --target=x86_64-unknown-linux-musl
However, when running with some CLI params under Alpine Linux 3.5, letsencrypt-rs
exits with status 1 and message:
The OpenSSL library reported an error
How can I solve this?
Could the error message be improved?
It has been deprecated: announcement.
Is there any functionality you would require from Serde or another library before this would be possible?
I was trying this project out today in my search for a better ACME client and couldn't seem to get past an error stating https://acme-v01.api.letsencrypt.org/directory: The OpenSSL library reported an error: The OpenSSL library reported an error: error:14007086:SSL routines:CONNECT_CR_CERT:certificate verify failed:ssl_clnt.c:1026:
. The binary appears to be statically linked and is using paths to your home directory instead of the default system paths for SSL certificates. Given that OpenSSL is statically linked I'm not sure how useful releasing a binary is, since different distributions all have different places where they keep their CA bundles.
open("/home/onur/code/libressl/etc/ssl/cert.pem", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/home/onur/code/libressl/etc/ssl/certs/2e5ac55d.0", 0x7fffc81ce740) = -1 ENOENT (No such file or directory)
stat("/home/onur/code/libressl/etc/ssl/certs/ef954a4e.0", 0x7fffc81ce740) = -1 ENOENT (No such file or directory)
stat("/home/onur/code/libressl/etc/ssl/certs/b3964d1c.0", 0x7fffc81ce740) = -1 ENOENT (No such file or directory)
This would be a significant breaking change, but I given how the ecosystem is moving in Rust, I think it makes sense for acme-client to move to using the latest hyper version and the tokio ecosystem.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.