Replies: 7 comments 15 replies
-
I don't know how that works and handling TSL directly is out of scope for axum. It can be handled by hooks provided by hyper. Does the existing TSL examples help you? |
Beta Was this translation helpful? Give feedback.
-
Thanks, I just did that. If it bear fruits, I will submit a pull request with the example. |
Beta Was this translation helpful? Give feedback.
-
I thing the Let's Encrypt part is pretty specific, and without the help of @FlorianUekermann, I would still be searching. use async_rustls::rustls::Session;
use async_rustls::TlsAcceptor;
use axum::extract::ConnectInfo;
use axum::routing::get;
use axum::Router;
use clap::Parser;
use futures_util::future::poll_fn;
use hyper::server::accept::Accept;
use hyper::server::conn::AddrIncoming;
use hyper::server::conn::Http;
use rustls_acme::acme::ACME_TLS_ALPN_NAME;
use rustls_acme::caches::DirCache;
use rustls_acme::AcmeConfig;
use std::net::SocketAddr;
use std::path::PathBuf;
use std::pin::Pin;
use tokio_stream::StreamExt;
use tokio_util::compat::FuturesAsyncReadCompatExt;
use tokio_util::compat::TokioAsyncReadCompatExt;
use tower::MakeService;
#[derive(Parser, Debug)]
struct Args {
/// Domains
#[clap(short, required = true)]
domains: Vec<String>,
/// Contact info
#[clap(short)]
email: Vec<String>,
/// Cache directory
#[clap(short, parse(from_os_str))]
cache: Option<PathBuf>,
/// Use Let's Encrypt production environment
/// (see https://letsencrypt.org/docs/staging-environment/)
#[clap(long)]
prod: Option<bool>,
#[clap(short, long, default_value = "443")]
port: u16,
}
#[tokio::main]
async fn main() {
simple_logger::init_with_level(log::Level::Info).unwrap();
let args = Args::parse();
let mut state = AcmeConfig::new(args.domains)
.contact(args.email.iter().map(|e| format!("mailto:{}", e)))
.cache_option(args.cache.clone().map(DirCache::new))
.state();
let acceptor = state.acceptor();
tokio::spawn(async move {
loop {
match state.next().await.unwrap() {
Ok(ok) => log::info!("event: {:?}", ok),
Err(err) => log::error!("error: {:?}", err),
}
}
});
serve(acceptor, args.port).await;
}
async fn serve(acceptor: TlsAcceptor, port: u16) {
let listener = tokio::net::TcpListener::bind(format!("[::]:{}", port))
.await
.unwrap();
let mut addr_incoming = AddrIncoming::from_listener(listener).unwrap();
// Create axum application
let mut app = Router::new()
.route("/", get(handler))
.into_make_service_with_connect_info::<SocketAddr>();
loop {
let stream = poll_fn(|cx| Pin::new(&mut addr_incoming).poll_accept(cx))
.await
.unwrap()
.unwrap();
let acceptor = acceptor.clone();
let app = app.make_service(&stream).await.unwrap();
tokio::spawn(async move {
let tls = acceptor.accept(stream.compat()).await.unwrap().compat();
match tls.get_ref().get_ref().1.get_alpn_protocol() {
Some(ACME_TLS_ALPN_NAME) => log::info!("received TLS-ALPN-01 validation request"),
_ => Http::new().serve_connection(tls, app).await.unwrap(),
}
});
}
}
async fn handler(ConnectInfo(addr): ConnectInfo<SocketAddr>) -> String {
format!("Hello Tls!\nYour address is: {addr}")
} |
Beta Was this translation helpful? Give feedback.
-
A quick question by the way : any idea to allow a graceful shutdown in this case with the low level serve_connection API ? |
Beta Was this translation helpful? Give feedback.
-
Hello, I managed the graceful shutdown by using tokio channels and a loop. On a broader subject, can you give a look here : FlorianUekermann/rustls-acme#27 (comment) . The creator of rustls-acme aims to improve the compatibility. I confess I am out of my league, but maybe you can propose something ?! |
Beta Was this translation helpful? Give feedback.
-
There is now a proper adaptor and an example for axum : https://github.com/FlorianUekermann/rustls-acme/blob/main/examples/low_level_axum.rs ! |
Beta Was this translation helpful? Give feedback.
-
May I ask why not use certbot from EFF for ACME and let axum handle the web stuff? Putting ACME into a web framework may be the first step towards turning said framework into a big bloated caddy bear. Certbot has another massive benefit in not using any resources when not actually running certificate updates. |
Beta Was this translation helpful? Give feedback.
-
Hi @davidpdrsn
Can you please add an example for Lets Encrypt automatic certificates?
Once you add this, Axum will have almost all the features provided by caddyserver
Thank you.
Beta Was this translation helpful? Give feedback.
All reactions