mirror of
https://github.com/timothymiller/cloudflare-ddns.git
synced 2026-03-21 22:48:57 -03:00
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:
@@ -1,3 +1,4 @@
|
||||
use crate::cf_ip_filter::CloudflareIpFilter;
|
||||
use crate::cloudflare::{CloudflareHandle, SetResult};
|
||||
use crate::config::{AppConfig, LegacyCloudflareEntry, LegacySubdomainEntry};
|
||||
use crate::domain::make_fqdn;
|
||||
@@ -65,6 +66,49 @@ pub async fn update_once(
|
||||
}
|
||||
}
|
||||
|
||||
// Filter out Cloudflare IPs if enabled
|
||||
if config.reject_cloudflare_ips {
|
||||
if let Some(cf_filter) =
|
||||
CloudflareIpFilter::fetch(&detection_client, config.detection_timeout, ppfmt).await
|
||||
{
|
||||
for (ip_type, ips) in detected_ips.iter_mut() {
|
||||
let before_count = ips.len();
|
||||
ips.retain(|ip| {
|
||||
if cf_filter.contains(ip) {
|
||||
ppfmt.warningf(
|
||||
pp::EMOJI_WARNING,
|
||||
&format!(
|
||||
"Rejected {ip}: matches Cloudflare IP range ({})",
|
||||
ip_type.describe()
|
||||
),
|
||||
);
|
||||
false
|
||||
} else {
|
||||
true
|
||||
}
|
||||
});
|
||||
if ips.is_empty() && before_count > 0 {
|
||||
ppfmt.warningf(
|
||||
pp::EMOJI_WARNING,
|
||||
&format!(
|
||||
"All detected {} addresses were Cloudflare IPs; skipping updates for this type",
|
||||
ip_type.describe()
|
||||
),
|
||||
);
|
||||
messages.push(Message::new_fail(&format!(
|
||||
"All {} addresses rejected (Cloudflare IPs)",
|
||||
ip_type.describe()
|
||||
)));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ppfmt.warningf(
|
||||
pp::EMOJI_WARNING,
|
||||
"Could not fetch Cloudflare IP ranges; skipping filter",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Update DNS records (env var mode - domain-based)
|
||||
for (ip_type, domains) in &config.domains {
|
||||
let ips = detected_ips.get(ip_type).cloned().unwrap_or_default();
|
||||
@@ -693,6 +737,7 @@ mod tests {
|
||||
managed_waf_comment_regex: None,
|
||||
detection_timeout: Duration::from_secs(5),
|
||||
update_timeout: Duration::from_secs(5),
|
||||
reject_cloudflare_ips: false,
|
||||
dry_run,
|
||||
emoji: false,
|
||||
quiet: true,
|
||||
|
||||
Reference in New Issue
Block a user