diff --git a/src/cli.rs b/src/cli.rs index 466188c..c15932d 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -184,6 +184,10 @@ pub struct HttpServer { /// Lifetime of a TLS1.3 ticket, due to key rotation the actual lifetime will be twice than this. #[clap(env, long, default_value = "9h", value_parser = parse_duration)] pub http_server_tls_ticket_lifetime: Duration, + + /// Option to only serve HTTP instead for testing. + #[clap(env, long)] + pub http_server_insecure_serve_http_only: bool, } #[derive(Args)] diff --git a/src/core.rs b/src/core.rs index de1fc54..4e30f6d 100644 --- a/src/core.rs +++ b/src/core.rs @@ -73,12 +73,6 @@ pub async fn main(cli: &Cli) -> Result<(), Error> { let reqwest_client = http::client::new(http_client_opts.clone())?; let http_client = Arc::new(http::ReqwestClient::new(http_client_opts)?); - // TLS session cache - let tls_session_cache = Arc::new(sessions::Storage::new( - cli.http_server.http_server_tls_session_cache_size, - cli.http_server.http_server_tls_session_cache_tti, - )); - // Event sinks let clickhouse = if cli.log.clickhouse.log_clickhouse_url.is_some() { Some(Arc::new( @@ -103,23 +97,28 @@ pub async fn main(cli: &Cli) -> Result<(), Error> { let handler_token = token.clone(); ctrlc::set_handler(move || handler_token.cancel())?; - // Prepare TLS related stuff - let (rustls_cfg, custom_domain_providers) = tls::setup( - cli, - &mut tasks, - domains.clone(), - http_client.clone(), - Arc::new(dns_resolver), - tls_session_cache.clone(), - ®istry, - ) - .await - .context("unable to setup TLS")?; + // TLS session cache + let tls_session_cache = Arc::new(sessions::Storage::new( + cli.http_server.http_server_tls_session_cache_size, + cli.http_server.http_server_tls_session_cache_tti, + )); + + // HTTP server metrics + let http_metrics = http::server::Metrics::new(®istry); + + // Custom domains + let (issuer_certificate_providers, issuer_custom_domain_providers) = + tls::cert::providers::setup_issuer_providers( + cli, + &mut tasks, + http_client.clone(), + ®istry, + ); - // Create routers - let https_router = routing::setup_router( + // Create gateway router to serve all endpoints + let gateway_router = routing::setup_router( cli, - custom_domain_providers, + issuer_custom_domain_providers, &mut tasks, http_client.clone(), reqwest_client, @@ -128,12 +127,15 @@ pub async fn main(cli: &Cli) -> Result<(), Error> { vector.clone(), ) .await?; - let http_router = Router::new().fallback(routing::redirect_to_https); - // HTTP server metrics - let http_metrics = http::server::Metrics::new(®istry); + // Set up HTTP router (redirecting to HTTPS or serving all endpoints) + let http_router = if !cli.http_server.http_server_insecure_serve_http_only { + Router::new().fallback(routing::redirect_to_https) + } else { + gateway_router.clone() + }; - // Set up HTTP + // Create HTTP server let http_server = Arc::new(http::Server::new( http::server::Addr::Tcp(cli.http_server.http_server_listen_plain), http_router, @@ -143,14 +145,30 @@ pub async fn main(cli: &Cli) -> Result<(), Error> { )); tasks.add("http_server", http_server); - let https_server = Arc::new(http::Server::new( - http::server::Addr::Tcp(cli.http_server.http_server_listen_tls), - https_router, - (&cli.http_server).into(), - http_metrics.clone(), - Some(rustls_cfg), - )); - tasks.add("https_server", https_server); + // Create HTTPS server + if !cli.http_server.http_server_insecure_serve_http_only { + // Prepare TLS related stuff + let rustls_cfg = tls::setup( + cli, + &mut tasks, + domains.clone(), + Arc::new(dns_resolver), + issuer_certificate_providers, + tls_session_cache.clone(), + ®istry, + ) + .await + .context("unable to setup TLS")?; + + let https_server = Arc::new(http::Server::new( + http::server::Addr::Tcp(cli.http_server.http_server_listen_tls), + gateway_router, + (&cli.http_server).into(), + http_metrics.clone(), + Some(rustls_cfg), + )); + tasks.add("https_server", https_server); + } // Setup metrics if let Some(addr) = cli.metrics.metrics_listen { diff --git a/src/tls/cert/providers/mod.rs b/src/tls/cert/providers/mod.rs index 176e8f9..e6e936e 100644 --- a/src/tls/cert/providers/mod.rs +++ b/src/tls/cert/providers/mod.rs @@ -5,6 +5,11 @@ pub use dir::Provider as Dir; pub use issuer::CertificatesImporter as Issuer; use async_trait::async_trait; +use ic_bn_lib::{http::Client, tasks::TaskManager}; +use prometheus::Registry; +use std::sync::Arc; + +use crate::{cli::Cli, routing::domain::ProvidesCustomDomains}; #[derive(Clone, Debug, Eq, PartialEq)] pub struct Pem { @@ -18,3 +23,32 @@ pub struct Pem { pub trait ProvidesCertificates: Sync + Send + std::fmt::Debug { async fn get_certificates(&self) -> Result, anyhow::Error>; } + +pub fn setup_issuer_providers( + cli: &Cli, + tasks: &mut TaskManager, + http_client: Arc, + registry: &Registry, +) -> ( + Vec>, + Vec>, +) { + let mut cert_providers: Vec> = vec![]; + let mut custom_domain_providers: Vec> = vec![]; + + let issuer_metrics = issuer::Metrics::new(registry); + for v in &cli.cert.cert_provider_issuer_url { + let issuer = Arc::new(Issuer::new( + http_client.clone(), + v.clone(), + cli.cert.cert_provider_issuer_poll_interval, + issuer_metrics.clone(), + )); + + cert_providers.push(issuer.clone()); + custom_domain_providers.push(issuer.clone()); + tasks.add(&format!("{issuer:?}"), issuer); + } + + (cert_providers, custom_domain_providers) +} diff --git a/src/tls/mod.rs b/src/tls/mod.rs index d17655c..2559b37 100644 --- a/src/tls/mod.rs +++ b/src/tls/mod.rs @@ -7,7 +7,7 @@ use anyhow::{anyhow, Context, Error}; use async_trait::async_trait; use fqdn::FQDN; use ic_bn_lib::{ - http::{dns::Resolves, Client, ALPN_ACME, ALPN_H1, ALPN_H2}, + http::{dns::Resolves, ALPN_ACME, ALPN_H1, ALPN_H2}, tasks::{Run, TaskManager}, tls::{ acme::{ @@ -31,7 +31,6 @@ use tokio_util::sync::CancellationToken; use crate::{ cli::Cli, - routing::domain::ProvidesCustomDomains, tls::{ cert::{providers, Aggregator}, resolver::AggregatingResolver, @@ -136,11 +135,11 @@ pub async fn setup( cli: &Cli, tasks: &mut TaskManager, domains: Vec, - http_client: Arc, dns_resolver: Arc, + custom_domain_providers: Vec>, tls_session_storage: Arc, registry: &Registry, -) -> Result<(ServerConfig, Vec>), Error> { +) -> Result { // Prepare certificate storage let cert_storage = Arc::new(storage::Storage::new( cli.cert.cert_default.clone(), @@ -148,28 +147,14 @@ pub async fn setup( )); let mut cert_providers: Vec> = vec![]; - let mut custom_domain_providers: Vec> = vec![]; // Create Dir providers for v in &cli.cert.cert_provider_dir { cert_providers.push(Arc::new(providers::Dir::new(v.clone()))); } - // Create CertIssuer providers - // It's a custom domain & cert provider at the same time. - let issuer_metrics = providers::issuer::Metrics::new(registry); - for v in &cli.cert.cert_provider_issuer_url { - let issuer = Arc::new(providers::Issuer::new( - http_client.clone(), - v.clone(), - cli.cert.cert_provider_issuer_poll_interval, - issuer_metrics.clone(), - )); - - cert_providers.push(issuer.clone()); - custom_domain_providers.push(issuer.clone()); - tasks.add(&format!("{issuer:?}"), issuer); - } + // Add custom domain certificate providers + cert_providers.extend(custom_domain_providers); // Prepare ACME if configured let acme_resolver = if let Some(v) = &cli.acme.acme_challenge { @@ -228,5 +213,5 @@ pub async fn setup( registry, ); - Ok((config, custom_domain_providers)) + Ok(config) }