18 个版本
0.9.1 | 2024年1月24日 |
---|---|
0.9.0 | 2023年11月11日 |
0.8.2 | 2021年8月20日 |
0.8.1 | 2020年6月15日 |
0.5.0 | 2019年3月30日 |
在 网页编程 中排名第 178
每月下载量 758
在 7 个包中使用
97KB
2K SLoC
acme-lib
acme-lib 是一个用于访问 ACME(自动证书管理环境)服务(如 Let's Encrypt)的库。
使用 ACME v2 版本来发行/更新证书。
示例
use acme_lib::{Error, Directory, DirectoryUrl};
use acme_lib::persist::FilePersist;
use acme_lib::create_p384_key;
fn request_cert() -> Result<(), Error> {
// Use DirectoryUrl::LetsEncrypStaging for dev/testing.
let url = DirectoryUrl::LetsEncrypt;
// Save/load keys and certificates to current dir.
let persist = FilePersist::new(".");
// Create a directory entrypoint.
let dir = Directory::from_url(persist, url)?;
// Reads the private account key from persistence, or
// creates a new one before accessing the API to establish
// that it's there.
let acc = dir.account("[email protected]")?;
// 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();
// 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(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, 5000)?;
// Now download the certificate. Also stores the cert in
// the persistence.
let cert = ord_cert.download_and_save_cert()?;
Ok(())
}
域名所有权
大多数网站 TLS 证书都试图证明对其签发的域的所有权/控制权。对于 ACME,这意味着证明您控制着响应该域 HTTP 请求的 Web 服务器,或者响应该域名称查询的 DNS 服务器。
要使用此库,在流程中存在需要修改 Web 服务器或 DNS 服务器才能获取证书的点。
请参阅 http_challenge
和 dns_challenge
。
多个域名
创建新的订单时,可以提供多个 alt-names,这些 alt-names 也将成为证书的一部分。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-6MB
~148K SLoC