tuwunel_router/serve/
tls.rs1use std::{
2 net::{SocketAddr, TcpListener},
3 path::Path,
4};
5
6use axum::{Router, extract::connect_info::IntoMakeServiceWithConnectInfo};
7use axum_server::{Handle, from_tcp_rustls};
8use axum_server_dual_protocol::{
9 ServerExt, axum_server::tls_rustls::RustlsConfig, from_tcp_dual_protocol,
10};
11use futures::{FutureExt, future::BoxFuture};
12use tuwunel_core::{Result, debug, err, info};
13
14pub(super) async fn serve<'a>(
15 app: &Router,
16 handle: &Handle<SocketAddr>,
17 cert: &Path,
18 key: &Path,
19 dual_protocol: bool,
20 listeners: impl Iterator<Item = TcpListener>,
21) -> Result<Vec<BoxFuture<'a, Result<(), std::io::Error>>>> {
22 info!(
23 "Note: It is strongly recommended that you use a reverse proxy instead of running \
24 tuwunel directly with TLS."
25 );
26
27 debug!(
28 "Using direct TLS. Certificate path {cert:?} and certificate private key path {key:?}"
29 );
30
31 let conf = RustlsConfig::from_pem_file(cert, key)
32 .await
33 .map_err(|e| err!(Config("tls", "Failed to load certificates or key: {e}")))?;
34
35 let app = app
36 .clone()
37 .into_make_service_with_connect_info::<SocketAddr>();
38
39 if dual_protocol {
40 serve_dual_protocol(&app, &conf, handle, listeners)
41 } else {
42 serve_tls(&app, &conf, handle, listeners)
43 }
44}
45
46fn serve_dual_protocol<'a>(
47 app: &IntoMakeServiceWithConnectInfo<Router, SocketAddr>,
48 conf: &RustlsConfig,
49 handle: &Handle<SocketAddr>,
50 listeners: impl Iterator<Item = TcpListener>,
51) -> Result<Vec<BoxFuture<'a, Result<(), std::io::Error>>>> {
52 listeners
53 .map(|listener| {
54 let acceptor = from_tcp_dual_protocol(listener, conf.clone())?
57 .set_upgrade(false)
58 .handle(handle.clone())
59 .serve(app.clone())
60 .boxed();
61
62 Ok(acceptor)
63 })
64 .collect()
65}
66
67fn serve_tls<'a>(
68 app: &IntoMakeServiceWithConnectInfo<Router, SocketAddr>,
69 conf: &RustlsConfig,
70 handle: &Handle<SocketAddr>,
71 listeners: impl Iterator<Item = TcpListener>,
72) -> Result<Vec<BoxFuture<'a, Result<(), std::io::Error>>>> {
73 listeners
74 .map(|listener| {
75 let acceptor = from_tcp_rustls(listener, conf.clone())?
76 .handle(handle.clone())
77 .serve(app.clone())
78 .boxed();
79
80 Ok(acceptor)
81 })
82 .collect()
83}