From c1b6d982ef1d0ff85d23932e7016df211d4d256a Mon Sep 17 00:00:00 2001 From: Brian Picciano Date: Mon, 15 May 2023 18:23:53 +0200 Subject: [PATCH] Switch to AAAA records --- .env.dev | 2 +- src/domain/checker.rs | 28 +++++++++++++-------------- src/domain/manager.rs | 6 +++--- src/main.rs | 10 +++++----- src/service.rs | 15 +++++++------- src/service/http_tpl/domain_init.html | 8 ++++---- 6 files changed, 33 insertions(+), 36 deletions(-) diff --git a/.env.dev b/.env.dev index 0a63c1f..baaa036 100644 --- a/.env.dev +++ b/.env.dev @@ -1,4 +1,4 @@ export DOMIPLY_PASSPHRASE=foobar export DOMIPLY_ORIGIN_STORE_GIT_DIR_PATH=/tmp/domiply_dev_env/origin/git -export DOMIPLY_DOMAIN_CHECKER_TARGET_CNAME=domiply.example.com +export DOMIPLY_DOMAIN_CHECKER_TARGET_AAAA=::1 export DOMIPLY_DOMAIN_CONFIG_STORE_DIR_PATH=/tmp/domiply_dev_env/domain/config diff --git a/src/domain/checker.rs b/src/domain/checker.rs index 730e57d..c2ea6b3 100644 --- a/src/domain/checker.rs +++ b/src/domain/checker.rs @@ -1,4 +1,5 @@ use std::error::Error; +use std::net; use std::str::FromStr; use std::sync; @@ -13,17 +14,14 @@ pub enum NewDNSCheckerError { #[error("invalid resolver address")] InvalidResolverAddress, - #[error("invalid target CNAME")] - InvalidTargetCNAME, - #[error(transparent)] Unexpected(Box), } #[derive(thiserror::Error, Debug)] pub enum CheckDomainError { - #[error("target CNAME not set")] - TargetCNAMENotSet, + #[error("target AAAA not set")] + TargetAAAANotSet, #[error("challenge token not set")] ChallengeTokenNotSet, @@ -33,7 +31,7 @@ pub enum CheckDomainError { } pub struct DNSChecker { - target_cname: Name, + target_aaaa: net::Ipv6Addr, // TODO we should use some kind of connection pool here, I suppose client: tokio::sync::Mutex, @@ -41,7 +39,7 @@ pub struct DNSChecker { pub fn new( tokio_runtime: sync::Arc, - target_cname: domain::Name, + target_aaaa: net::Ipv6Addr, resolver_addr: &str, ) -> Result { let resolver_addr = resolver_addr @@ -57,7 +55,7 @@ pub fn new( tokio_runtime.spawn(bg); Ok(DNSChecker { - target_cname: target_cname.inner, + target_aaaa, client: tokio::sync::Mutex::new(client), }) } @@ -70,13 +68,13 @@ impl DNSChecker { ) -> Result<(), CheckDomainError> { let domain = &domain.inner; - // check that the CNAME is installed correctly on the domain + // check that the AAAA is installed correctly on the domain { let response = match self .client .lock() .await - .query(domain.clone(), DNSClass::IN, RecordType::CNAME) + .query(domain.clone(), DNSClass::IN, RecordType::AAAA) .await { Ok(res) => res, @@ -86,14 +84,14 @@ impl DNSChecker { let records = response.answers(); if records.len() != 1 { - return Err(CheckDomainError::TargetCNAMENotSet); + return Err(CheckDomainError::TargetAAAANotSet); } - // if the single record isn't a CNAME, or it's not the target CNAME, then return - // TargetCNAMENotSet + // if the single record isn't a AAAA, or it's not the target AAAA, then return + // TargetAAAANAMENotSet match records[0].data() { - Some(RData::CNAME(remote_cname)) if remote_cname == &self.target_cname => (), - _ => return Err(CheckDomainError::TargetCNAMENotSet), + Some(RData::AAAA(remote_aaaa)) if remote_aaaa == &self.target_aaaa => (), + _ => return Err(CheckDomainError::TargetAAAANotSet), } } diff --git a/src/domain/manager.rs b/src/domain/manager.rs index d0c9a80..c61ddb6 100644 --- a/src/domain/manager.rs +++ b/src/domain/manager.rs @@ -72,8 +72,8 @@ pub enum SyncWithConfigError { #[error("already in progress")] AlreadyInProgress, - #[error("target CNAME not set")] - TargetCNAMENotSet, + #[error("target AAAA not set")] + TargetAAAANotSet, #[error("challenge token not set")] ChallengeTokenNotSet, @@ -96,7 +96,7 @@ impl From for SyncWithConfigError { impl From for SyncWithConfigError { fn from(e: checker::CheckDomainError) -> SyncWithConfigError { match e { - checker::CheckDomainError::TargetCNAMENotSet => SyncWithConfigError::TargetCNAMENotSet, + checker::CheckDomainError::TargetAAAANotSet => SyncWithConfigError::TargetAAAANotSet, checker::CheckDomainError::ChallengeTokenNotSet => { SyncWithConfigError::ChallengeTokenNotSet } diff --git a/src/main.rs b/src/main.rs index 6a5f5f7..786ca1a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,7 +14,7 @@ use std::sync; #[command(version)] #[command(about = "A domiply to another dimension")] struct Cli { - #[arg(long, default_value_t = SocketAddr::from_str("127.0.0.1:3030").unwrap(), env = "DOMIPLY_HTTP_LISTEN_ADDR")] + #[arg(long, default_value_t = SocketAddr::from_str("[::]:3030").unwrap(), env = "DOMIPLY_HTTP_LISTEN_ADDR")] http_listen_addr: SocketAddr, #[arg(long, required = true, env = "DOMIPLY_PASSPHRASE")] @@ -23,8 +23,8 @@ struct Cli { #[arg(long, required = true, env = "DOMIPLY_ORIGIN_STORE_GIT_DIR_PATH")] origin_store_git_dir_path: path::PathBuf, - #[arg(long, required = true, env = "DOMIPLY_DOMAIN_CHECKER_TARGET_CNAME")] - domain_checker_target_cname: domiply::domain::Name, + #[arg(long, required = true, env = "DOMIPLY_DOMAIN_CHECKER_TARGET_AAAA")] + domain_checker_target_aaaa: std::net::Ipv6Addr, #[arg(long, default_value_t = String::from("1.1.1.1:53"), env = "DOMIPLY_DOMAIN_CHECKER_RESOLVER_ADDR")] domain_checker_resolver_addr: String, @@ -67,7 +67,7 @@ fn main() { let domain_checker = domiply::domain::checker::new( tokio_runtime.clone(), - config.domain_checker_target_cname.clone(), + config.domain_checker_target_aaaa, &config.domain_checker_resolver_addr, ) .expect("domain checker initialized"); @@ -80,7 +80,7 @@ fn main() { let service = domiply::service::new( manager, - config.domain_checker_target_cname, + config.domain_checker_target_aaaa, config.passphrase, ); diff --git a/src/service.rs b/src/service.rs index 27a5068..d04fb52 100644 --- a/src/service.rs +++ b/src/service.rs @@ -4,6 +4,7 @@ use serde::{Deserialize, Serialize}; use std::convert::Infallible; use std::future::Future; +use std::net; use std::sync; use crate::domain; @@ -16,19 +17,19 @@ type SvcResponse = Result, String>; #[derive(Clone)] pub struct Service<'svc> { domain_manager: sync::Arc, - target_cname: domain::Name, + target_aaaa: net::Ipv6Addr, passphrase: String, handlebars: handlebars::Handlebars<'svc>, } pub fn new<'svc, 'mgr>( domain_manager: sync::Arc, - target_cname: domain::Name, + target_aaaa: net::Ipv6Addr, passphrase: String, ) -> Service<'svc> { Service { domain_manager, - target_cname, + target_aaaa, passphrase, handlebars: self::http_tpl::get().expect("Retrieved Handlebars templates"), } @@ -161,7 +162,7 @@ impl<'svc> Service<'svc> { struct Response { domain: domain::Name, flat_config: util::FlatConfig, - target_cname: domain::Name, + target_aaaa: net::Ipv6Addr, challenge_token: String, } @@ -181,14 +182,12 @@ impl<'svc> Service<'svc> { } }; - let target_cname = self.target_cname.clone(); - return self.render_page( "/domain_init.html", &Response { domain: args.domain, flat_config: config.into(), - target_cname: target_cname, + target_aaaa: self.target_aaaa, challenge_token: config_hash, }, ); @@ -223,7 +222,7 @@ impl<'svc> Service<'svc> { Err(domain::manager::SyncWithConfigError::InvalidURL) => Some("Fetching the git repository failed, please double check that you input the correct URL.".to_string()), Err(domain::manager::SyncWithConfigError::InvalidBranchName) => Some("The git repository does not have a branch of the given name, please double check that you input the correct name.".to_string()), Err(domain::manager::SyncWithConfigError::AlreadyInProgress) => Some("The configuration of your domain is still in progress, please refresh in a few minutes.".to_string()), - Err(domain::manager::SyncWithConfigError::TargetCNAMENotSet) => Some("The CNAME record is not set correctly on the domain. Please double check that you put the correct value on the record. If the value is correct, then most likely the updated records have not yet propagated. In this case you can refresh in a few minutes to try again.".to_string()), + Err(domain::manager::SyncWithConfigError::TargetAAAANotSet) => Some("The AAAA record is not set correctly on the domain. Please double check that you put the correct value on the record. If the value is correct, then most likely the updated records have not yet propagated. In this case you can refresh in a few minutes to try again.".to_string()), Err(domain::manager::SyncWithConfigError::ChallengeTokenNotSet) => Some("The TXT record is not set correctly on the domain. Please double check that you put the correct value on the record. If the value is correct, then most likely the updated records have not yet propagated. In this case you can refresh in a few minutes to try again.".to_string()), Err(domain::manager::SyncWithConfigError::Unexpected(e)) => Some(format!("An unexpected error occurred: {e}")), }; diff --git a/src/service/http_tpl/domain_init.html b/src/service/http_tpl/domain_init.html index 734f412..56dc4e9 100644 --- a/src/service/http_tpl/domain_init.html +++ b/src/service/http_tpl/domain_init.html @@ -1,12 +1,12 @@

Configure DNS

-

Next you will need to configure your DNS server to point to Domiply. There are -two entries you will need to add:

+

Next you will need to configure your DNS server to point to Domiply. There +are two entries you will need to add:

  • - A CNAME {{ data.domain }} entry with the value - {{ data.target_cname }} + A AAAA {{ data.domain }} entry with the value + {{ data.target_aaaa }}
  • A TXT _domiply_challenge.{{ data.domain }} entry with the value