From 2e3442faa9625f706b4131417381d8fd2fb3bda3 Mon Sep 17 00:00:00 2001 From: Alex Auvolat Date: Sun, 11 Dec 2022 16:42:00 +0100 Subject: [PATCH] Fix subdomain matching --- src/dns_updater.rs | 29 +++++++++++++++++++---------- src/provider/gandi.rs | 30 ++++++++++++++++++++++++------ src/provider/mod.rs | 17 ++++++++++++++--- 3 files changed, 57 insertions(+), 19 deletions(-) diff --git a/src/dns_updater.rs b/src/dns_updater.rs index e65689d..e525f8a 100644 --- a/src/dns_updater.rs +++ b/src/dns_updater.rs @@ -51,7 +51,10 @@ pub async fn dns_updater_task( } // Skip entries for unallowed domains - if !allowed_domains.iter().any(|d| key.dns_path.ends_with(d)) { + if !allowed_domains + .iter() + .any(|d| key.dns_path == *d || key.dns_path.ends_with(&format!(".{}", d))) + { error!( domain = key.dns_path, "domain/subdomain/hostname not in allowed list", @@ -59,7 +62,9 @@ pub async fn dns_updater_task( continue; } - let provider = providers.iter().find(|p| key.dns_path.ends_with(&p.domain)); + let provider = providers.iter().find(|p| { + key.dns_path == p.domain || key.dns_path.ends_with(&format!(".{}", p.domain)) + }); if let Some(provider) = provider { if let Err(e) = update_dns_entry(key, value, provider).await { @@ -87,11 +92,15 @@ async fn update_dns_entry( value: &DnsEntryValue, provider: &DomainProvider, ) -> Result<()> { - let subdomain = key - .dns_path - .strip_suffix(&provider.domain) - .unwrap() - .trim_end_matches('.'); + let subdomain = if key.dns_path == provider.domain { + None + } else { + Some( + key.dns_path + .strip_suffix(&format!(".{}", provider.domain)) + .unwrap(), + ) + }; info!( record = key.to_string(), target = value.to_string(), @@ -116,7 +125,7 @@ async fn update_dns_entry( } provider .provider - .update_a(&provider.domain, &subdomain, &targets) + .update_a(&provider.domain, subdomain, &targets) .await?; } DnsRecordType::AAAA => { @@ -129,7 +138,7 @@ async fn update_dns_entry( } provider .provider - .update_aaaa(&provider.domain, &subdomain, &targets) + .update_aaaa(&provider.domain, subdomain, &targets) .await?; } DnsRecordType::CNAME => { @@ -145,7 +154,7 @@ async fn update_dns_entry( } provider .provider - .update_cname(&provider.domain, &subdomain, &targets[0]) + .update_cname(&provider.domain, subdomain, &targets[0]) .await?; } } diff --git a/src/provider/gandi.rs b/src/provider/gandi.rs index eeff641..0658db2 100644 --- a/src/provider/gandi.rs +++ b/src/provider/gandi.rs @@ -56,10 +56,16 @@ impl DnsProvider for GandiProvider { "gandi" } - async fn update_a(&self, domain: &str, subdomain: &str, targets: &[Ipv4Addr]) -> Result<()> { + async fn update_a( + &self, + domain: &str, + subdomain: Option<&str>, + targets: &[Ipv4Addr], + ) -> Result<()> { let url = format!( "https://api.gandi.net/v5/livedns/domains/{}/records/{}/A", - domain, subdomain + domain, + subdomain.unwrap_or("@") ); let rrset = GandiRrset { @@ -70,10 +76,16 @@ impl DnsProvider for GandiProvider { self.put_rrset(&url, &rrset).await } - async fn update_aaaa(&self, domain: &str, subdomain: &str, targets: &[Ipv6Addr]) -> Result<()> { + async fn update_aaaa( + &self, + domain: &str, + subdomain: Option<&str>, + targets: &[Ipv6Addr], + ) -> Result<()> { let url = format!( "https://api.gandi.net/v5/livedns/domains/{}/records/{}/AAAA", - domain, subdomain + domain, + subdomain.unwrap_or("@") ); let rrset = GandiRrset { @@ -84,10 +96,16 @@ impl DnsProvider for GandiProvider { self.put_rrset(&url, &rrset).await } - async fn update_cname(&self, domain: &str, subdomain: &str, target: &str) -> Result<()> { + async fn update_cname( + &self, + domain: &str, + subdomain: Option<&str>, + target: &str, + ) -> Result<()> { let url = format!( "https://api.gandi.net/v5/livedns/domains/{}/records/{}/CNAME", - domain, subdomain + domain, + subdomain.unwrap_or("@") ); let rrset = GandiRrset { diff --git a/src/provider/mod.rs b/src/provider/mod.rs index 6527631..1ef6b0f 100644 --- a/src/provider/mod.rs +++ b/src/provider/mod.rs @@ -8,9 +8,20 @@ use async_trait::async_trait; #[async_trait] pub trait DnsProvider: Send + Sync { fn provider(&self) -> &'static str; - async fn update_a(&self, domain: &str, subdomain: &str, targets: &[Ipv4Addr]) -> Result<()>; - async fn update_aaaa(&self, domain: &str, subdomain: &str, targets: &[Ipv6Addr]) -> Result<()>; - async fn update_cname(&self, domain: &str, subdomain: &str, target: &str) -> Result<()>; + async fn update_a( + &self, + domain: &str, + subdomain: Option<&str>, + targets: &[Ipv4Addr], + ) -> Result<()>; + async fn update_aaaa( + &self, + domain: &str, + subdomain: Option<&str>, + targets: &[Ipv6Addr], + ) -> Result<()>; + async fn update_cname(&self, domain: &str, subdomain: Option<&str>, target: &str) + -> Result<()>; } impl std::fmt::Debug for dyn DnsProvider {