Add REJECT_CLOUDFLARE_IPS flag to filter out Cloudflare-owned IPs from

DNS updates

  IP detection providers can sometimes return a Cloudflare anycast IP
  instead
  of the user's real public IP, causing incorrect DNS updates. When
  REJECT_CLOUDFLARE_IPS=true, detected IPs are checked against
  Cloudflare's
  published IP ranges (ips-v4/ips-v6) and rejected if they match.
This commit is contained in:
Timothy Miller
2026-03-18 19:44:06 -04:00
parent 54ca4a5eae
commit 4b1875b0cd
6 changed files with 460 additions and 11 deletions

View File

@@ -89,6 +89,7 @@ pub struct AppConfig {
pub managed_waf_comment_regex: Option<regex::Regex>,
pub detection_timeout: Duration,
pub update_timeout: Duration,
pub reject_cloudflare_ips: bool,
pub dry_run: bool,
pub emoji: bool,
pub quiet: bool,
@@ -439,6 +440,7 @@ fn legacy_to_app_config(legacy: LegacyConfig, dry_run: bool, repeat: bool) -> Ap
managed_waf_comment_regex: None,
detection_timeout: Duration::from_secs(5),
update_timeout: Duration::from_secs(30),
reject_cloudflare_ips: false,
dry_run,
emoji: false,
quiet: false,
@@ -509,6 +511,7 @@ pub fn load_env_config(ppfmt: &PP) -> Result<AppConfig, String> {
let emoji = getenv_bool("EMOJI", true);
let quiet = getenv_bool("QUIET", false);
let reject_cloudflare_ips = getenv_bool("REJECT_CLOUDFLARE_IPS", false);
// Validate: must have at least one update target
if domains.is_empty() && waf_lists.is_empty() {
@@ -559,6 +562,7 @@ pub fn load_env_config(ppfmt: &PP) -> Result<AppConfig, String> {
managed_waf_comment_regex,
detection_timeout,
update_timeout,
reject_cloudflare_ips,
dry_run: false, // Set later from CLI args
emoji,
quiet,
@@ -659,6 +663,10 @@ pub fn print_config_summary(config: &AppConfig, ppfmt: &PP) {
inner.infof("", "Delete on stop: enabled");
}
if config.reject_cloudflare_ips {
inner.infof("", "Reject Cloudflare IPs: enabled");
}
if let Some(ref comment) = config.record_comment {
inner.infof("", &format!("Record comment: {comment}"));
}
@@ -1190,6 +1198,7 @@ mod tests {
managed_waf_comment_regex: None,
detection_timeout: Duration::from_secs(5),
update_timeout: Duration::from_secs(30),
reject_cloudflare_ips: false,
dry_run: false,
emoji: false,
quiet: false,
@@ -1223,6 +1232,7 @@ mod tests {
managed_waf_comment_regex: None,
detection_timeout: Duration::from_secs(5),
update_timeout: Duration::from_secs(30),
reject_cloudflare_ips: false,
dry_run: false,
emoji: false,
quiet: false,
@@ -1881,6 +1891,7 @@ mod tests {
managed_waf_comment_regex: None,
detection_timeout: Duration::from_secs(5),
update_timeout: Duration::from_secs(30),
reject_cloudflare_ips: false,
dry_run: false,
emoji: false,
quiet: false,
@@ -1916,6 +1927,7 @@ mod tests {
managed_waf_comment_regex: None,
detection_timeout: Duration::from_secs(5),
update_timeout: Duration::from_secs(30),
reject_cloudflare_ips: false,
dry_run: false,
emoji: false,
quiet: true,
@@ -1948,6 +1960,7 @@ mod tests {
managed_waf_comment_regex: None,
detection_timeout: Duration::from_secs(5),
update_timeout: Duration::from_secs(30),
reject_cloudflare_ips: false,
dry_run: false,
emoji: false,
quiet: false,