Bump to dns-update 0.5.0
This commit is contained in:
@@ -267,17 +267,22 @@ impl AcmeRequestBuilder {
|
||||
.or_else(|| psl::domain_str(domain))
|
||||
.unwrap_or(domain);
|
||||
|
||||
let proof = self.dns_proof(challenge)?;
|
||||
let challenge_name = format!("_acme-challenge.{}", domain);
|
||||
dns_parameters
|
||||
.updater
|
||||
.create(
|
||||
.set_rrset(
|
||||
zone,
|
||||
&format!("_acme-challenge.{}", domain),
|
||||
DnsRecord::TXT(self.dns_proof(challenge)?),
|
||||
true,
|
||||
true,
|
||||
&challenge_name,
|
||||
dns_update::DnsRecordType::TXT,
|
||||
vec![DnsRecord::TXT(proof.clone())],
|
||||
)
|
||||
.await
|
||||
.map_err(AcmeError::Dns)?;
|
||||
dns_parameters
|
||||
.updater
|
||||
.wait_for_txt_propagation(&challenge_name, zone, &proof)
|
||||
.await;
|
||||
}
|
||||
ChallengeType::DnsPersist01 => {}
|
||||
ChallengeType::Unknown => unreachable!(),
|
||||
|
||||
@@ -133,7 +133,7 @@ impl Server {
|
||||
}
|
||||
}
|
||||
DnsRecordType::AutoConfig => {
|
||||
let pacc_digest = Sha256::digest(&self.get_pacc_for_fomain(domain_name).await?);
|
||||
let pacc_digest = Sha256::digest(&self.get_pacc_for_domain(domain_name).await?);
|
||||
let pacc_digest_encoded = general_purpose::STANDARD.encode(pacc_digest);
|
||||
|
||||
records.push(NamedDnsRecord {
|
||||
@@ -379,7 +379,7 @@ impl Server {
|
||||
.map(|records| BindSerializer::serialize(&records))
|
||||
}
|
||||
|
||||
pub async fn get_pacc_for_fomain(&self, domain_name: &str) -> trc::Result<String> {
|
||||
pub async fn get_pacc_for_domain(&self, domain_name: &str) -> trc::Result<String> {
|
||||
self.get_directory_for_domain(domain_name)
|
||||
.await
|
||||
.caused_by(trc::location!())
|
||||
|
||||
@@ -1114,125 +1114,95 @@ impl DnsUpdater {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn create(
|
||||
pub async fn set_rrset(
|
||||
&self,
|
||||
origin: &str,
|
||||
name: &str,
|
||||
record: DnsRecord,
|
||||
verify: bool,
|
||||
delete_before_create: bool,
|
||||
) -> Result<bool, String> {
|
||||
// First try deleting the record
|
||||
if delete_before_create
|
||||
&& let Err(err) = self.updater.delete(name, origin, record.as_type()).await
|
||||
{
|
||||
// Errors are expected if the record does not exist
|
||||
trc::event!(
|
||||
Dns(DnsEvent::RecordDeletionFailed),
|
||||
Hostname = name.to_string(),
|
||||
Reason = err.to_string(),
|
||||
Details = origin.to_string(),
|
||||
Type = record.as_type().as_str(),
|
||||
);
|
||||
}
|
||||
record_type: DnsRecordType,
|
||||
records: Vec<DnsRecord>,
|
||||
) -> Result<(), String> {
|
||||
let record_values = records
|
||||
.iter()
|
||||
.map(|r| trc::Value::String(r.to_string().into()))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// Create the record
|
||||
if let Err(err) = self
|
||||
.updater
|
||||
.create(name, record.clone(), self.ttl.as_secs() as u32, origin)
|
||||
.set_rrset(
|
||||
name,
|
||||
record_type,
|
||||
self.ttl.as_secs() as u32,
|
||||
records,
|
||||
origin,
|
||||
)
|
||||
.await
|
||||
{
|
||||
return Err(format!("Failed to create DNS record: {}", err));
|
||||
return Err(format!("Failed to set DNS RRSet: {}", err));
|
||||
}
|
||||
|
||||
trc::event!(
|
||||
Dns(DnsEvent::RecordCreated),
|
||||
Hostname = name.to_string(),
|
||||
Details = origin.to_string(),
|
||||
Type = record.as_type().as_str(),
|
||||
Value = record.to_string(),
|
||||
Type = record_type.as_str(),
|
||||
Value = record_values,
|
||||
);
|
||||
|
||||
if verify && let DnsRecord::TXT(txt_record) = &record {
|
||||
#[cfg(feature = "test_mode")]
|
||||
if matches!(
|
||||
self.updater,
|
||||
dns_update::DnsUpdater::Pebble(_) | dns_update::DnsUpdater::InMemory(_)
|
||||
) {
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
// Wait for changes to propagate
|
||||
if let Some(initial_wait) = self.propagation_delay {
|
||||
tokio::time::sleep(initial_wait).await;
|
||||
}
|
||||
let wait_until = Instant::now() + self.propagation_timeout;
|
||||
let mut did_propagate = false;
|
||||
while Instant::now() < wait_until {
|
||||
match self.core.smtp.resolvers.dns.txt_raw_lookup(&name).await {
|
||||
Ok(result) => {
|
||||
let result = std::str::from_utf8(&result).unwrap_or_default();
|
||||
if result.contains(txt_record) {
|
||||
did_propagate = true;
|
||||
break;
|
||||
} else {
|
||||
trc::event!(
|
||||
Dns(DnsEvent::RecordNotPropagated),
|
||||
Hostname = name.to_string(),
|
||||
Details = origin.to_string(),
|
||||
Result = result.to_string(),
|
||||
Type = record.as_type().as_str(),
|
||||
Value = record.to_string(),
|
||||
);
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
trc::event!(
|
||||
Dns(DnsEvent::RecordLookupFailed),
|
||||
Hostname = name.to_string(),
|
||||
Details = origin.to_string(),
|
||||
Reason = err.to_string(),
|
||||
Type = record.as_type().as_str(),
|
||||
Value = record.to_string(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
tokio::time::sleep(self.polling_interval).await;
|
||||
}
|
||||
|
||||
if did_propagate {
|
||||
trc::event!(
|
||||
Dns(DnsEvent::RecordPropagated),
|
||||
Hostname = name.to_string(),
|
||||
Details = origin.to_string(),
|
||||
Type = record.as_type().as_str(),
|
||||
Value = record.to_string(),
|
||||
);
|
||||
} else {
|
||||
trc::event!(
|
||||
Dns(DnsEvent::RecordPropagationTimeout),
|
||||
Hostname = name.to_string(),
|
||||
Details = origin.to_string(),
|
||||
Type = record.as_type().as_str(),
|
||||
Value = record.to_string(),
|
||||
);
|
||||
}
|
||||
|
||||
Ok(did_propagate)
|
||||
} else {
|
||||
Ok(true)
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn delete(
|
||||
pub async fn add_to_rrset(
|
||||
&self,
|
||||
origin: &str,
|
||||
name: &str,
|
||||
record_type: DnsRecordType,
|
||||
records: Vec<DnsRecord>,
|
||||
) -> Result<(), String> {
|
||||
// First try deleting the record
|
||||
match self.updater.delete(name, origin, record_type).await {
|
||||
let record_values = records
|
||||
.iter()
|
||||
.map(|r| trc::Value::String(r.to_string().into()))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
if let Err(err) = self
|
||||
.updater
|
||||
.add_to_rrset(
|
||||
name,
|
||||
record_type,
|
||||
self.ttl.as_secs() as u32,
|
||||
records,
|
||||
origin,
|
||||
)
|
||||
.await
|
||||
{
|
||||
return Err(format!("Failed to add to DNS RRSet: {}", err));
|
||||
}
|
||||
|
||||
trc::event!(
|
||||
Dns(DnsEvent::RecordCreated),
|
||||
Hostname = name.to_string(),
|
||||
Details = origin.to_string(),
|
||||
Type = record_type.as_str(),
|
||||
Value = record_values,
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn remove_from_rrset(
|
||||
&self,
|
||||
origin: &str,
|
||||
name: &str,
|
||||
record_type: DnsRecordType,
|
||||
records: Vec<DnsRecord>,
|
||||
) -> Result<(), String> {
|
||||
let record_values = records
|
||||
.iter()
|
||||
.map(|r| trc::Value::String(r.to_string().into()))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
match self
|
||||
.updater
|
||||
.remove_from_rrset(name, record_type, records, origin)
|
||||
.await
|
||||
{
|
||||
Ok(_) => Ok(()),
|
||||
Err(err) => {
|
||||
trc::event!(
|
||||
@@ -1241,11 +1211,79 @@ impl DnsUpdater {
|
||||
Reason = err.to_string(),
|
||||
Details = origin.to_string(),
|
||||
Type = record_type.as_str(),
|
||||
Value = record_values,
|
||||
);
|
||||
Err(err.to_string())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn wait_for_txt_propagation(&self, name: &str, origin: &str, expected: &str) -> bool {
|
||||
#[cfg(feature = "test_mode")]
|
||||
if matches!(
|
||||
self.updater,
|
||||
dns_update::DnsUpdater::Pebble(_) | dns_update::DnsUpdater::InMemory(_)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if let Some(initial_wait) = self.propagation_delay {
|
||||
tokio::time::sleep(initial_wait).await;
|
||||
}
|
||||
let wait_until = Instant::now() + self.propagation_timeout;
|
||||
let mut did_propagate = false;
|
||||
while Instant::now() < wait_until {
|
||||
match self.core.smtp.resolvers.dns.txt_raw_lookup(&name).await {
|
||||
Ok(result) => {
|
||||
let result = std::str::from_utf8(&result).unwrap_or_default();
|
||||
if result.contains(expected) {
|
||||
did_propagate = true;
|
||||
break;
|
||||
} else {
|
||||
trc::event!(
|
||||
Dns(DnsEvent::RecordNotPropagated),
|
||||
Hostname = name.to_string(),
|
||||
Details = origin.to_string(),
|
||||
Result = result.to_string(),
|
||||
Type = DnsRecordType::TXT.as_str(),
|
||||
Value = expected.to_string(),
|
||||
);
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
trc::event!(
|
||||
Dns(DnsEvent::RecordLookupFailed),
|
||||
Hostname = name.to_string(),
|
||||
Details = origin.to_string(),
|
||||
Reason = err.to_string(),
|
||||
Type = DnsRecordType::TXT.as_str(),
|
||||
Value = expected.to_string(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
tokio::time::sleep(self.polling_interval).await;
|
||||
}
|
||||
|
||||
if did_propagate {
|
||||
trc::event!(
|
||||
Dns(DnsEvent::RecordPropagated),
|
||||
Hostname = name.to_string(),
|
||||
Details = origin.to_string(),
|
||||
Type = DnsRecordType::TXT.as_str(),
|
||||
Value = expected.to_string(),
|
||||
);
|
||||
} else {
|
||||
trc::event!(
|
||||
Dns(DnsEvent::RecordPropagationTimeout),
|
||||
Hostname = name.to_string(),
|
||||
Details = origin.to_string(),
|
||||
Type = DnsRecordType::TXT.as_str(),
|
||||
Value = expected.to_string(),
|
||||
);
|
||||
}
|
||||
did_propagate
|
||||
}
|
||||
}
|
||||
|
||||
impl Server {
|
||||
|
||||
Reference in New Issue
Block a user