Add tls serving as an option

This commit is contained in:
Jeremy Wall 2023-01-02 19:47:40 -06:00
parent 09058914b0
commit 907af7f23c
5 changed files with 113 additions and 14 deletions

62
Cargo.lock generated
View File

@ -63,6 +63,12 @@ dependencies = [
"serde",
]
[[package]]
name = "arc-swap"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6"
[[package]]
name = "argon2"
version = "0.4.1"
@ -312,6 +318,26 @@ dependencies = [
"tower-service",
]
[[package]]
name = "axum-server"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8456dab8f11484979a86651da8e619b355ede5d61a160755155f6c344bd18c47"
dependencies = [
"arc-swap",
"bytes",
"futures-util",
"http",
"http-body",
"hyper",
"pin-project-lite",
"rustls",
"rustls-pemfile",
"tokio",
"tokio-rustls",
"tower-service",
]
[[package]]
name = "base64"
version = "0.13.0"
@ -1156,9 +1182,9 @@ checksum = "0bfe8eed0a9285ef776bb792479ea3834e8b94e13d615c2f66d03dd50a435a29"
[[package]]
name = "httparse"
version = "1.7.1"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "496ce29bb5a52785b44e0f7ca2847ae0bb839c9bd28f69acac9b99d461c0c04c"
checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
[[package]]
name = "httpdate"
@ -1168,9 +1194,9 @@ checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
[[package]]
name = "hyper"
version = "0.14.20"
version = "0.14.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02c929dc5c39e335a03c405292728118860721b10190d98c2a0f0efd5baafbac"
checksum = "034711faac9d2166cb1baf1a2fb0b60b1f277f8492fd72176c17f3515e1abd3c"
dependencies = [
"bytes",
"futures-channel",
@ -1285,6 +1311,7 @@ dependencies = [
"async-trait",
"axum",
"axum-auth",
"axum-server",
"chrono",
"ciborium",
"clap",
@ -1994,9 +2021,9 @@ checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1"
[[package]]
name = "socket2"
version = "0.4.4"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0"
checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd"
dependencies = [
"libc",
"winapi",
@ -2357,9 +2384,32 @@ dependencies = [
"once_cell",
"pin-project-lite",
"socket2",
"tokio-macros",
"winapi",
]
[[package]]
name = "tokio-macros"
version = "1.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tokio-rustls"
version = "0.23.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59"
dependencies = [
"rustls",
"tokio",
"webpki",
]
[[package]]
name = "tokio-util"
version = "0.7.3"

View File

@ -29,6 +29,10 @@ version = "0.4.1"
version = "0.8.0"
features = ["serde"]
[dependencies.axum-server]
version = "0.4.4"
features = [ "tls-rustls" ]
[dependencies.axum-auth]
version = "0.3.0"
features = ["auth-basic"]

View File

@ -45,7 +45,10 @@ fn create_app<'a>() -> clap::App<'a> {
(@subcommand serve =>
(about: "Serve the interface via the web")
(@arg recipe_dir: -d --dir +takes_value "Directory containing recipe files to use")
(@arg session_dir: --session_dir + takes_value "Session store directory to use")
(@arg session_dir: --session_dir +takes_value "Session store directory to use")
(@arg tls: --tls "Use TLS to serve.")
(@arg cert_path: --cert +takes_value "Certificate path. Required if you specified --tls.")
(@arg key_path: --cert_key +takes_value "Certificate key path. Required if you specified --tls")
(@arg listen: --listen +takes_value "address and port to listen on 0.0.0.0:3030")
)
(@subcommand add_user =>
@ -136,7 +139,22 @@ fn main() {
};
info!(listen=%listen_socket, "Launching web interface...");
async_std::task::block_on(async {
web::ui_main(recipe_dir_path, session_store_path, listen_socket).await
if matches.contains_id("tls") {
web::ui_main_tls(
recipe_dir_path,
session_store_path,
listen_socket,
matches
.value_of("cert_path")
.expect("You must provide a cert path with --cert"),
matches
.value_of("key_path")
.expect("You must provide a key path with --cert_key"),
)
.await
} else {
web::ui_main(recipe_dir_path, session_store_path, listen_socket).await
}
});
} else if let Some(matches) = matches.subcommand_matches("add_user") {
let recipe_dir_path = matches.value_of("recipe_dir").map(|dir| PathBuf::from(dir));

View File

@ -355,8 +355,8 @@ fn mk_v2_routes() -> Router {
)
}
#[instrument(fields(recipe_dir=?recipe_dir_path,listen=?listen_socket), skip_all)]
pub async fn ui_main(recipe_dir_path: PathBuf, store_path: PathBuf, listen_socket: SocketAddr) {
#[instrument(fields(recipe_dir=?recipe_dir_path), skip_all)]
pub async fn make_router(recipe_dir_path: PathBuf, store_path: PathBuf) -> Router {
let store = Arc::new(storage::file_store::AsyncFileStore::new(
recipe_dir_path.clone(),
));
@ -369,7 +369,7 @@ pub async fn ui_main(recipe_dir_path: PathBuf, store_path: PathBuf, listen_socke
.run_migrations()
.await
.expect("Failed to run database migrations");
let router = Router::new()
Router::new()
.route("/", get(|| async { Redirect::temporary("/ui/plan") }))
.route("/favicon.ico", get(|| async { StaticFile("favicon.ico") }))
.route("/ui/*path", get(ui_static_assets))
@ -390,12 +390,39 @@ pub async fn ui_main(recipe_dir_path: PathBuf, store_path: PathBuf, listen_socke
.layer(TraceLayer::new_for_http())
.layer(Extension(store))
.layer(Extension(app_store)),
);
)
}
#[instrument(fields(recipe_dir=?recipe_dir_path,listen=?listen_socket), skip_all)]
pub async fn ui_main_tls(
recipe_dir_path: PathBuf,
store_path: PathBuf,
listen_socket: SocketAddr,
cert_path: &str,
key_path: &str,
) {
let router = make_router(recipe_dir_path, store_path).await;
info!(
http = format!("http://{}", listen_socket),
"Starting server"
);
axum::Server::bind(&listen_socket)
let config = axum_server::tls_rustls::RustlsConfig::from_pem_file(cert_path, key_path)
.await
.expect("Failed to parse config from pem files");
axum_server::bind_rustls(listen_socket, config)
.serve(router.into_make_service())
.await
.expect("Failed to start tls service");
}
#[instrument(fields(recipe_dir=?recipe_dir_path,listen=?listen_socket), skip_all)]
pub async fn ui_main(recipe_dir_path: PathBuf, store_path: PathBuf, listen_socket: SocketAddr) {
let router = make_router(recipe_dir_path, store_path).await;
info!(
http = format!("http://{}", listen_socket),
"Starting server"
);
axum_server::bind(listen_socket)
.serve(router.into_make_service())
.await
.expect("Failed to start service");

2
run.sh
View File

@ -14,5 +14,5 @@
EXAMPLES=${EXAMPLES:-../examples}
make clean wasm kitchen
echo Starting api server serving ${EXAMPLES}
cargo run -- --verbose debug serve --dir ${EXAMPLES}
cargo run -- --verbose debug serve --dir ${EXAMPLES} --tls --cert ~/tls-certs/localhost+2.pem --cert_key ~/tls-certs/localhost+2-key.pem
# This is ghetto but I'm doing it anyway