Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: first try to optionally serve all endpoints also on HTTP #38

Merged
merged 5 commits into from
Sep 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
84 changes: 51 additions & 33 deletions src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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(),
&registry,
)
.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(&registry);

// Custom domains
let (issuer_certificate_providers, issuer_custom_domain_providers) =
tls::cert::providers::setup_issuer_providers(
cli,
&mut tasks,
http_client.clone(),
&registry,
);

// 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,
Expand All @@ -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(&registry);
// 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,
Expand All @@ -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(),
&registry,
)
.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 {
Expand Down
34 changes: 34 additions & 0 deletions src/tls/cert/providers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -18,3 +23,32 @@ pub struct Pem {
pub trait ProvidesCertificates: Sync + Send + std::fmt::Debug {
async fn get_certificates(&self) -> Result<Vec<Pem>, anyhow::Error>;
}

pub fn setup_issuer_providers(
cli: &Cli,
tasks: &mut TaskManager,
http_client: Arc<dyn Client>,
registry: &Registry,
) -> (
Vec<Arc<dyn ProvidesCertificates>>,
Vec<Arc<dyn ProvidesCustomDomains>>,
) {
let mut cert_providers: Vec<Arc<dyn ProvidesCertificates>> = vec![];
let mut custom_domain_providers: Vec<Arc<dyn ProvidesCustomDomains>> = 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)
}
27 changes: 6 additions & 21 deletions src/tls/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand All @@ -31,7 +31,6 @@ use tokio_util::sync::CancellationToken;

use crate::{
cli::Cli,
routing::domain::ProvidesCustomDomains,
tls::{
cert::{providers, Aggregator},
resolver::AggregatingResolver,
Expand Down Expand Up @@ -136,40 +135,26 @@ pub async fn setup(
cli: &Cli,
tasks: &mut TaskManager,
domains: Vec<FQDN>,
http_client: Arc<dyn Client>,
dns_resolver: Arc<dyn Resolves>,
custom_domain_providers: Vec<Arc<dyn ProvidesCertificates>>,
tls_session_storage: Arc<dyn StoresServerSessions + Send + Sync>,
registry: &Registry,
) -> Result<(ServerConfig, Vec<Arc<dyn ProvidesCustomDomains>>), Error> {
) -> Result<ServerConfig, Error> {
// Prepare certificate storage
let cert_storage = Arc::new(storage::Storage::new(
cli.cert.cert_default.clone(),
storage::Metrics::new(registry),
));

let mut cert_providers: Vec<Arc<dyn ProvidesCertificates>> = vec![];
let mut custom_domain_providers: Vec<Arc<dyn ProvidesCustomDomains>> = 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 {
Expand Down Expand Up @@ -228,5 +213,5 @@ pub async fn setup(
registry,
);

Ok((config, custom_domain_providers))
Ok(config)
}