#acme #tls-certificate #letsencrypt #private-key #api-bindings #web-server

acme-micro

用于从 ACME 提供商请求证书的库(acme-lib 分支)

5 个版本 (破坏性更新)

0.12.0 2021 年 9 月 22 日
0.11.0 2021 年 2 月 17 日
0.10.0 2021 年 2 月 9 日
0.9.0 2020 年 6 月 14 日
0.8.0 2020 年 5 月 7 日

网页编程 中排名 920

Download history 35/week @ 2024-03-11 9/week @ 2024-03-18 8/week @ 2024-03-25 30/week @ 2024-04-01 8/week @ 2024-04-08 16/week @ 2024-04-15 23/week @ 2024-04-22 17/week @ 2024-04-29 8/week @ 2024-05-06 24/week @ 2024-05-13 21/week @ 2024-05-20 21/week @ 2024-05-27 10/week @ 2024-06-03 17/week @ 2024-06-10 10/week @ 2024-06-17 13/week @ 2024-06-24

每月下载量 52
acme-redirect 中使用

MIT 许可证

83KB
1.5K SLoC

acme-micro

acme-micro 是 acme-lib 的分支,允许访问 ACME(自动证书管理环境)服务,如 Let's Encrypt

使用 ACME v2 签发/更新证书。

示例

use acme_micro::{Error, Certificate, Directory, DirectoryUrl};
use acme_micro::create_p384_key;
use std::time::Duration;

fn request_cert() -> Result<Certificate, Error> {

// Use DirectoryUrl::LetsEncrypStaging for dev/testing.
let url = DirectoryUrl::LetsEncrypt;

// Create a directory entrypoint.
let dir = Directory::from_url(url)?;

// Your contact addresses, note the `mailto:`
let contact = vec!["mailto:[email protected]".to_string()];

// Generate a private key and register an account with your ACME provider.
// You should write it to disk any use `load_account` afterwards.
let acc = dir.register_account(contact.clone())?;

// Example of how to load an account from string:
let privkey = acc.acme_private_key_pem()?;
let acc = dir.load_account(&privkey, contact)?;

// Order a new TLS certificate for a domain.
let mut ord_new = acc.new_order("mydomain.io", &[])?;

// If the ownership of the domain(s) have already been
// authorized in a previous order, you might be able to
// skip validation. The ACME API provider decides.
let ord_csr = loop {
    // are we done?
    if let Some(ord_csr) = ord_new.confirm_validations() {
        break ord_csr;
    }

    // Get the possible authorizations (for a single domain
    // this will only be one element).
    let auths = ord_new.authorizations()?;

    // For HTTP, the challenge is a text file that needs to
    // be placed in your web server's root:
    //
    // /var/www/.well-known/acme-challenge/<token>
    //
    // The important thing is that it's accessible over the
    // web for the domain(s) you are trying to get a
    // certificate for:
    //
    // http://mydomain.io/.well-known/acme-challenge/<token>
    let chall = auths[0].http_challenge().unwrap();

    // The token is the filename.
    let token = chall.http_token();
    let path = format!(".well-known/acme-challenge/{}", token);

    // The proof is the contents of the file
    let proof = chall.http_proof()?;

    // Here you must do "something" to place
    // the file/contents in the correct place.
    // update_my_web_server(&path, &proof);

    // After the file is accessible from the web, the calls
    // this to tell the ACME API to start checking the
    // existence of the proof.
    //
    // The order at ACME will change status to either
    // confirm ownership of the domain, or fail due to the
    // not finding the proof. To see the change, we poll
    // the API with 5000 milliseconds wait between.
    chall.validate(Duration::from_millis(5000))?;

    // Update the state against the ACME API.
    ord_new.refresh()?;
};

// Ownership is proven. Create a private key for
// the certificate. These are provided for convenience, you
// can provide your own keypair instead if you want.
let pkey_pri = create_p384_key()?;

// Submit the CSR. This causes the ACME provider to enter a
// state of "processing" that must be polled until the
// certificate is either issued or rejected. Again we poll
// for the status change.
let ord_cert =
    ord_csr.finalize_pkey(pkey_pri, Duration::from_millis(5000))?;

// Finally download the certificate.
let cert = ord_cert.download_cert()?;
println!("{:?}", cert);

Ok(cert)
}

域名所有权

大多数网站 TLS 证书都试图证明对所签发域名拥有所有权/控制权。对于 ACME,这意味着证明您控制着响应用户 HTTP 请求的 web 服务器或回答域名查找的 DNS 服务器。

要使用此库,在流程中有几个点需要修改 web 服务器或 DNS 服务器才能继续获取证书。

请参阅 http_challengedns_challenge

多个域名

在创建新的订单时,可以提供多个别名,它们也将成为证书的一部分。ACME API 要求您证明对每个此类域的所有权。请参阅 authorizations

速率限制

ACME API 提供商 Let's Encrypt 使用 速率限制 来确保 API 不被滥用。可能会诱使您将这些库中的某些轮询调用中的 delay_millis 设置得很低,但请权衡这种做法可能带来的实际风险。

开发时使用测试环境!

特别是要注意,在开发时使用 Let's Encrypt 测试环境,那里的速率限制更加宽松。

请参阅 DirectoryUrl::LetsEncryptStaging

实现细节

此库试图引入尽可能少的依赖项。(目前)这意味着使用同步 I/O 和阻塞调用。这并不意味着未来不会出现基于 futures 的版本。

该文档遵循ACME草稿规范18编写,并且高度依赖于openssl库来生成JWK/JWT以及向API发送签名请求。

许可证:MIT

依赖项

~4.5–6.5MB
~150K SLoC