some comments
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is failing

This commit is contained in:
Quentin 2023-11-30 15:35:32 +01:00
parent b04c2bfb0a
commit ca449ebff4
Signed by: quentin
GPG key ID: E9602264D639FF68

View file

@ -70,6 +70,9 @@ impl CertStore {
loop { loop {
let mut domains: HashSet<String> = HashSet::new(); 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! { select! {
res = rx_proxy_config.changed() => { res = rx_proxy_config.changed() => {
if res.is_err() { if res.is_err() {
@ -78,6 +81,8 @@ impl CertStore {
let proxy_config: Arc<ProxyConfig> = rx_proxy_config.borrow().clone(); let proxy_config: Arc<ProxyConfig> = rx_proxy_config.borrow().clone();
for ent in proxy_config.entries.iter() { 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 HostDescription::Hostname(domain) = &ent.url_prefix.host {
if let Some((host, _port)) = domain.split_once(':') { if let Some((host, _port)) = domain.split_once(':') {
domains.insert(host.to_string()); domains.insert(host.to_string());
@ -85,6 +90,9 @@ impl CertStore {
domains.insert(domain.clone()); domains.insert(domain.clone());
} }
} }
// @TODO Register a map of
// UrlPrefix -> OnDemandTlsAskCheckUrl
} }
} }
need_cert = rx_need_cert.recv() => { 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() { for dom in domains.iter() {
// Exclude from the list domains that were checked less than 60
// seconds ago
match t_last_check.get(dom) { match t_last_check.get(dom) {
Some(t) if Instant::now() - *t < Duration::from_secs(60) => continue, Some(t) if Instant::now() - *t < Duration::from_secs(60) => continue,
_ => t_last_check.insert(dom.to_string(), Instant::now()), _ => 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); debug!("Checking cert for domain: {}", dom);
if let Err(e) = self.check_cert(dom).await { if let Err(e) = self.check_cert(dom).await {
warn!("({}) Could not get certificate: {}", dom, e); warn!("({}) Could not get certificate: {}", dom, e);
@ -186,6 +199,15 @@ impl CertStore {
Ok(()) 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<()> { pub async fn check_cert(self: &Arc<Self>, domain: &str) -> Result<()> {
// First, try locally. // First, try locally.
{ {
@ -226,6 +248,7 @@ impl CertStore {
self.renew_cert(domain).await 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<()> { pub async fn renew_cert(self: &Arc<Self>, domain: &str) -> Result<()> {
info!("({}) Renewing certificate", domain); info!("({}) Renewing certificate", domain);