diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/cert_store.rs | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/src/cert_store.rs b/src/cert_store.rs index 0ced178..e25395d 100644 --- a/src/cert_store.rs +++ b/src/cert_store.rs @@ -70,6 +70,9 @@ impl CertStore { loop { let mut domains: HashSet<String> = HashSet::new(); + // Collect domains that need a TLS certificate + // either from the proxy configuration (eagerly) + // or on reaction to a user request (lazily) select! { res = rx_proxy_config.changed() => { if res.is_err() { @@ -78,6 +81,8 @@ impl CertStore { let proxy_config: Arc<ProxyConfig> = rx_proxy_config.borrow().clone(); for ent in proxy_config.entries.iter() { + // Eagerly generate certificates for domains that + // are not patterns if let HostDescription::Hostname(domain) = &ent.url_prefix.host { if let Some((host, _port)) = domain.split_once(':') { domains.insert(host.to_string()); @@ -85,6 +90,9 @@ impl CertStore { domains.insert(domain.clone()); } } + + // @TODO Register a map of + // UrlPrefix -> OnDemandTlsAskCheckUrl } } need_cert = rx_need_cert.recv() => { @@ -100,12 +108,17 @@ impl CertStore { } } + // Now that we have our list of domains to check, + // actually do something for dom in domains.iter() { + // Exclude from the list domains that were checked less than 60 + // seconds ago match t_last_check.get(dom) { Some(t) if Instant::now() - *t < Duration::from_secs(60) => continue, _ => t_last_check.insert(dom.to_string(), Instant::now()), }; + // Actual Let's Encrypt calls are done here (in sister function) debug!("Checking cert for domain: {}", dom); if let Err(e) = self.check_cert(dom).await { warn!("({}) Could not get certificate: {}", dom, e); @@ -186,6 +199,15 @@ impl CertStore { Ok(()) } + /// Check certificate ensure that the certificate is in the memory store + /// and that it does not need to be renewed. + /// + /// If it's not in the memory store, it tries to load it from Consul, + /// if it's not in Consul, it calls Let's Encrypt. + /// + /// If the certificate is outdated in the memory store, it tries to load + /// a more recent version in Consul, if the Consul version is also outdated, + /// it tries to renew it pub async fn check_cert(self: &Arc<Self>, domain: &str) -> Result<()> { // First, try locally. { @@ -226,6 +248,7 @@ impl CertStore { self.renew_cert(domain).await } + /// This is the place where certificates are generated or renewed pub async fn renew_cert(self: &Arc<Self>, domain: &str) -> Result<()> { info!("({}) Renewing certificate", domain); |