diff --git a/Cargo.lock b/Cargo.lock index 6ab02a6..655540b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1427,8 +1427,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86ed14aa9c9f927213c6e4f3ef75faaad3406134efe84ba2cb7983431d5f0931" dependencies = [ "futures-core", - "prost 0.13.2", - "prost-types 0.13.2", + "prost 0.13.3", + "prost-types 0.13.3", "tonic 0.12.2", "tracing-core", ] @@ -1446,8 +1446,8 @@ dependencies = [ "hdrhistogram", "humantime", "hyper-util", - "prost 0.13.2", - "prost-types 0.13.2", + "prost 0.13.3", + "prost-types 0.13.3", "serde", "serde_json", "thread_local", @@ -4672,9 +4672,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] name = "plotters" @@ -4914,12 +4914,12 @@ dependencies = [ [[package]] name = "prost" -version = "0.13.2" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b2ecbe40f08db5c006b5764a2645f7f3f141ce756412ac9e1dd6087e6d32995" +checksum = "7b0487d90e047de87f984913713b85c601c05609aad5b0df4b4573fbf69aa13f" dependencies = [ "bytes", - "prost-derive 0.13.2", + "prost-derive 0.13.3", ] [[package]] @@ -4958,9 +4958,9 @@ dependencies = [ [[package]] name = "prost-derive" -version = "0.13.2" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acf0c195eebb4af52c752bec4f52f645da98b6e92077a04110c7f349477ae5ac" +checksum = "e9552f850d5f0964a4e4d0bf306459ac29323ddfbae05e35a7c0d35cb0803cc5" dependencies = [ "anyhow", "itertools 0.13.0", @@ -4994,11 +4994,11 @@ dependencies = [ [[package]] name = "prost-types" -version = "0.13.2" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60caa6738c7369b940c3d49246a8d1749323674c65cb13010134f5c9bad5b519" +checksum = "4759aa0d3a6232fb8dbdb97b61de2c20047c68aca932c7ed76da9d788508d670" dependencies = [ - "prost 0.13.2", + "prost 0.13.3", ] [[package]] @@ -6245,9 +6245,9 @@ dependencies = [ [[package]] name = "simdutf8" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" [[package]] name = "simple_asn1" @@ -6306,11 +6306,11 @@ dependencies = [ [[package]] name = "snafu" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b835cb902660db3415a672d862905e791e54d306c6e8189168c7f3d9ae1c79d" +checksum = "223891c85e2a29c3fe8fb900c1fae5e69c2e42415e3177752e8718475efa5019" dependencies = [ - "snafu-derive 0.8.4", + "snafu-derive 0.8.5", ] [[package]] @@ -6327,9 +6327,9 @@ dependencies = [ [[package]] name = "snafu-derive" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d1e02fca405f6280643174a50c942219f0bbf4dbf7d480f1dd864d6f211ae5" +checksum = "03c3c6b7927ffe7ecaa769ee0e3994da3b8cafc8f444578982c83ecb161af917" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -6666,18 +6666,18 @@ checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" [[package]] name = "thiserror" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ "proc-macro2", "quote", @@ -6969,7 +6969,7 @@ dependencies = [ "hyper-util", "percent-encoding", "pin-project", - "prost 0.13.2", + "prost 0.13.3", "socket2", "tokio", "tokio-stream", @@ -7709,7 +7709,7 @@ dependencies = [ "sha-1", "sha2 0.10.8", "sha3", - "snafu 0.8.4", + "snafu 0.8.5", "snap", "strip-ansi-escapes", "syslog_loose", diff --git a/src/cli.rs b/src/cli.rs index a06ebe6..466188c 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -234,6 +234,12 @@ pub struct Cert { #[clap(env, long, default_value = "5s", value_parser = parse_duration)] pub cert_provider_poll_interval: Duration, + /// Default certificate to serve when there's no SNI in the request. + /// Tries to find a certificate that covers given FQDN. + /// If not found or not specified - picks the first one available. + #[clap(env, long)] + pub cert_default: Option, + /// Disable OCSP stapling #[clap(env, long)] pub cert_ocsp_stapling_disable: bool, diff --git a/src/tls/cert/mod.rs b/src/tls/cert/mod.rs index 820785a..a6182e9 100644 --- a/src/tls/cert/mod.rs +++ b/src/tls/cert/mod.rs @@ -341,9 +341,10 @@ pub mod test { AtomicUsize::new(0), ); - let storage = Arc::new(storage::StorageKey::new(storage::Metrics::new( - &Registry::new(), - ))); + let storage = Arc::new(storage::StorageKey::new( + None, + storage::Metrics::new(&Registry::new()), + )); let aggregator = Aggregator::new( vec![Arc::new(prov1), Arc::new(prov2)], storage, diff --git a/src/tls/cert/storage.rs b/src/tls/cert/storage.rs index 52d7d4f..07c2519 100644 --- a/src/tls/cert/storage.rs +++ b/src/tls/cert/storage.rs @@ -45,6 +45,7 @@ struct StorageInner { pub struct Storage { #[new(default)] inner: ArcSwapOption>, + cert_default: Option, metrics: Metrics, } @@ -75,12 +76,19 @@ impl Storage { let inner = self.inner.load_full()?; // Try to find some certificate - inner - .certs - .first_key_value() - .or_else(|| inner.certs_wildcard.first_key_value()) - .map(|x| x.1) - .cloned() + self.cert_default + .as_ref() + // Try to find the default one if specified first + .and_then(|x| self.lookup_cert(x)) + // Then just pick first available + .or_else(|| { + inner + .certs + .first_key_value() + .or_else(|| inner.certs_wildcard.first_key_value()) + .map(|x| x.1) + .cloned() + }) } } @@ -160,7 +168,8 @@ pub mod test { use super::*; pub fn create_test_storage() -> Storage { - let storage: Storage = Storage::new(Metrics::new(&Registry::new())); + let storage: Storage = + Storage::new(Some(fqdn!("foo.baz")), Metrics::new(&Registry::new())); let certs = vec![ Cert { @@ -244,8 +253,8 @@ pub mod test { "foo.bar.cert" ); - // Check any - assert_eq!(storage.any().unwrap().cert, "foo.bar.cert"); + // Check any, make sure it returns the cert_default + assert_eq!(storage.any().unwrap().cert, "foo.baz.cert"); Ok(()) } diff --git a/src/tls/mod.rs b/src/tls/mod.rs index 74b1b31..d17655c 100644 --- a/src/tls/mod.rs +++ b/src/tls/mod.rs @@ -142,7 +142,10 @@ pub async fn setup( registry: &Registry, ) -> Result<(ServerConfig, Vec>), Error> { // Prepare certificate storage - let cert_storage = Arc::new(storage::Storage::new(storage::Metrics::new(registry))); + let cert_storage = Arc::new(storage::Storage::new( + cli.cert.cert_default.clone(), + storage::Metrics::new(registry), + )); let mut cert_providers: Vec> = vec![]; let mut custom_domain_providers: Vec> = vec![];