Rust TLS自动证书管理库rustls-acme的使用,支持ACME协议自动化HTTPS证书签发与续期
以下是关于Rust TLS自动证书管理库rustls-acme的使用介绍,支持ACME协议自动化HTTPS证书签发与续期:
许可证
rustls-acme采用双许可证:
- Apache License 2.0
- MIT license
贡献者提交的代码默认会按上述双许可证授权。
安装方式
在项目目录中运行:
cargo add rustls-acme
或在Cargo.toml中添加:
rustls-acme = "0.14.0"
完整示例
以下是一个使用rustls-acme自动管理TLS证书的完整示例:
use rustls_acme::{AcmeConfig, caches::DirCache};
use tokio::io::{AsyncReadExt, AsyncWriteExt};
#[tokio::main]
async fn main() {
// 创建ACME配置
let mut acme = AcmeConfig::new(["example.com"])
.contact(["mailto:admin@example.com"])
.cache(DirCache::new("./cache"))
.directory_lets_encrypt(true) // 使用Let's Encrypt生产环境
.state_path("./state")
.await;
// 获取TLS配置
let tls_config = acme.tls_config();
// 创建TCP监听
let listener = tokio::net::TcpListener::bind("0.0.0.0:443").await.unwrap();
// 接受和处理连接
loop {
let (mut stream, _) = listener.accept().await.unwrap();
let tls_config = tls_config.clone();
tokio::spawn(async move {
// 建立TLS连接
let mut tls_stream = tokio_rustls::TlsServer::new(stream, tls_config).await.unwrap();
// 处理HTTP请求
let mut buf = [0; 1024];
let n = tls_stream.read(&mut buf).await.unwrap();
let req = String::from_utf8_lossy(&buf[..n]);
// 发送响应
let resp = "HTTP/1.1 200 OK\r\n\r\nHello ACME!";
tls_stream.write_all(resp.as_bytes()).await.unwrap();
});
}
}
功能说明
- 自动获取和续期Let’s Encrypt证书
- 支持多域名配置
- 提供本地缓存功能
- 内置TLS服务器配置
注意事项
- 需要开放80端口用于ACME验证
- 生产环境应确保state目录持久化
- 首次运行可能需要几分钟获取初始证书
这个库特别适合需要自动化TLS证书管理的Rust网络服务,如HTTP服务器、gRPC服务等。
1 回复
Rust TLS自动证书管理库rustls-acme的使用
简介
rustls-acme是一个基于Rust语言的库,实现了ACME协议(如Let’s Encrypt使用的协议)的客户端功能,用于自动化HTTPS证书的签发和续期。它集成了rustls TLS库,可以方便地为Rust网络服务添加自动化的HTTPS证书管理功能。
主要特性
- 支持ACME v2协议(兼容Let’s Encrypt)
- 自动证书签发和续期
- 零配置使用默认证书颁发机构
- 与rustls无缝集成
- 支持HTTP-01和TLS-ALPN-01挑战验证方式
- 内置小型HTTP服务器用于挑战响应
完整示例代码
以下是基于内容中提供的示例代码的完整演示demo:
use rustls_acme::caches::DirCache;
use rustls_acme::AcmeConfig;
use std::net::Ipv4Addr;
use std::path::PathBuf;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio_stream::StreamExt;
#[tokio::main]
async fn main() {
// 配置ACME,使用example.com域名
let mut state = AcmeConfig::new(["example.com"])
.contact(["mailto:admin@example.com"]) // 设置联系邮箱
.cache(DirCache::new(PathBuf::from("/tmp/rustls-acme-cache"))) // 使用临时目录存储证书
.directory_lets_encrypt(true) // 使用Let's Encrypt生产环境
.state();
// 创建Tokio异步任务处理ACME事件
tokio::spawn(async move {
while let Some(event) = state.next().await {
match event {
Ok(event) => println!("ACME事件: {:?}", event),
Err(err) => eprintln!("ACME错误: {:?}", err),
}
}
});
// 获取TLS acceptor
let acceptor = state.acceptor();
// 绑定443端口
let listener = tokio::net::TcpListener::bind((Ipv4Addr::UNSPECIFIED, 443)).await.unwrap();
println!("服务器已启动,监听443端口...");
// 接受并处理连接
while let Ok((stream, _)) = listener.accept().await {
let acceptor = acceptor.clone();
tokio::spawn(async move {
// 进行TLS握手
match acceptor.accept(stream).await {
Ok(mut tls_stream) => {
// 简单的HTTP响应
let response = b"HTTP/1.1 200 OK\r\nContent-Length: 12\r\n\r\nHello, TLS!";
tls_stream.write_all(response).await.unwrap();
}
Err(err) => {
eprintln!("TLS握手失败: {:?}", err);
}
}
});
}
}
配置说明
- Cargo.toml依赖:
[dependencies]
rustls-acme = "0.8"
tokio = { version = "1", features = ["full"] }
tokio-rustls = "0.23"
async-trait = "0.1" # 如果需要自定义缓存实现
- 生产环境注意事项:
- 确保域名已正确解析到服务器IP
- 确保服务器80和443端口可被外部访问
- 建议使用持久化存储而不是临时目录存储证书
- 监控证书续期事件,确保续期成功
- 自定义配置:
// 多个域名配置
AcmeConfig::new(["example.com", "www.example.com", "api.example.com"])
// 使用自定义ACME服务器
.directory_url("https://acme-staging-v02.api.letsencrypt.org/directory")
// 只使用HTTP-01挑战验证
.http01_challenge()
高级用法示例
自定义HTTP处理器
use rustls_acme::futures_rustls::server::TlsStream;
use std::sync::Arc;
async fn handle_client(mut stream: TlsStream<tokio::net::TcpStream>) {
let mut buf = [0u8; 1024];
match stream.read(&mut buf).await {
Ok(n) if n > 0 => {
let request = String::from_utf8_lossy(&buf[..n]);
println!("收到请求:\n{}", request);
let response = "HTTP/1.1 200 OK\r\n\r\nHello from secure server!";
stream.write_all(response.as_bytes()).await.unwrap();
}
_ => eprintln!("读取客户端数据失败"),
}
}
#[tokio::main]
async fn main() {
let tls_acceptor = AcmeConfig::new(["example.com"])
.state()
.acceptor();
let listener = tokio::net::TcpListener::bind("0.0.0.0:443").await.unwrap();
while let Ok((tcp_stream, _)) = listener.accept().await {
let tls_acceptor = tls_acceptor.clone();
tokio::spawn(async move {
match tls_acceptor.accept(tcp_stream).await {
Ok(tls_stream) => handle_client(tls_stream).await,
Err(err) => eprintln!("TLS握手失败: {:?}", err),
}
});
}
}
总结
rustls-acme通过自动化证书管理简化了Rust应用的HTTPS部署,开发者只需关注业务逻辑而无需手动管理证书。该库支持Let’s Encrypt等ACME协议证书颁发机构,提供了灵活的配置选项和扩展接口,是构建安全网络服务的理想选择。