use std::sync::Arc;
use futures::StreamExt;
use tokio_rustls::rustls::version::{TLS12, TLS13};
use tokio_rustls::rustls::ServerConfig;
use tokio_rustls_acme::caches::DirCache;
use tokio_rustls_acme::{AcmeAcceptor, AcmeConfig};
use crate::config::Config;
pub struct AcmeSetup {
pub acceptor: AcmeAcceptor,
pub rustls_config: Arc<ServerConfig>,
}
pub fn build_acme_acceptor(config: &Config) -> anyhow::Result<AcmeSetup> {
let domain = config.domain.clone();
let cache_dir = config.acme.cache_dir.clone();
let acme_config = AcmeConfig::new([domain])
.contact_push(format!("mailto:{}", config.acme.email))
.cache(DirCache::new(cache_dir))
.directory_lets_encrypt(!config.acme.staging);
let mut state = acme_config.state();
let acceptor = state.acceptor();
let resolver = state.resolver();
let mut rustls_config = ServerConfig::builder_with_protocol_versions(&[&TLS13, &TLS12])
.with_no_client_auth()
.with_cert_resolver(resolver);
rustls_config.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec()];
let rustls_config = Arc::new(rustls_config);
tokio::spawn(async move {
loop {
match state.next().await {
Some(Ok(event)) => {
tracing::info!("ACME event: {:?}", event);
}
Some(Err(e)) => {
tracing::error!("ACME error: {:?}", e);
}
None => break,
}
}
});
Ok(AcmeSetup {
acceptor,
rustls_config,
})
}