Add support for REJECT_CLOUDFLARE_IPS in legacy config and fetch
Cloudflare
IP ranges to drop matching detected addresses. Improve IP detection in
legacy mode by using literal-IP primary trace URLs with hostname
fallbacks, binding dedicated IPv4/IPv6 HTTP clients, and setting a Host
override for literal-IP trace endpoints so TLS SNI works. Expose
build_split_client and update tests accordingly.
Remove the ipnet crate and implement a lightweight CidrRange struct
that handles IPv4/IPv6 CIDR parsing and containment checks using
bitwise masking. Adds tests for invalid prefixes and cross-family
non-matching.
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.
The fallback hostname-based URL and custom URLs resolve correctly
without a Host override, so restrict the header to the cases that
need it (direct IP connections to 1.1.1.1 / [2606:4700:4700::1111]).
Primary trace endpoints now use literal IPs per address family to
guarantee correct address family selection. Fallback uses
api.cloudflare.com to work around WARP/Zero Trust interception. Rename
constants and update tests accordingly.
Default IPv4 provider is now CloudflareTrace.
Primary uses api.cloudflare.com; fallbacks are literal IPs.
Build per-family HTTP clients by binding to 0.0.0.0/[::] so the trace
endpoint observes the requested address family. Add validate_detected_ip
to reject wrong-family or non-global addresses (loopback, link-local,
private, documentation ranges, etc). Update tests and legacy updater
URLs.
Default to Cloudflare trace and validate IPs
Use api.cloudflare.com as the primary trace endpoint (fallbacks
remain literal IPs) to avoid WARP/Zero Trust interception. Build
IP-family-specific HTTP clients by binding to the unspecified
address so the trace endpoint sees the correct family. Add
validate_detected_ip to reject non-global or wrong-family addresses
and expand tests. Bump crate version and tempfile dev-dependency.
Update README and tests to reflect new defaults
Bump actions/checkout to v6, replace linux/arm/v7 with
linux/ppc64le in the Docker build, and normalize tag quoting in the
GitHub workflow
Narrow tokio features to rt-multi-thread, macros, time and signal.
Add release profile to reduce binary size:
opt-level = s, lto = true, codegen-units = 1, strip = true, panic =
abort
Update Cargo.lock to remove unused deps and adjust Dockerfile to copy
CA certs from builder and set ENTRYPOINT for the release image
Use scratch base image and optimize release build
Add linux/ppc64le support in CI and build script
Switch Docker release stage to scratch, copy CA certificates from the
builder and use an explicit ENTRYPOINT for the binary
Tighten Cargo release profile (opt-level="s", lto, codegen-units=1,
strip, panic="abort") and reduce Tokio features to shrink the binary
Update README to reflect image size and supported platforms
Add Cargo.toml, Cargo.lock and a full src/ tree with modules and tests
Update Dockerfile to build a Rust release binary and simplify CI/publish
Remove legacy Python script, requirements.txt, and startup helper
Switch .gitignore to Rust artifacts; update Dependabot and workflows to
cargo
Add .env example, docker-compose env, and update README and VSCode
settings
Remove the old Python implementation and requirements; add a Rust
implementation with Cargo.toml/Cargo.lock and full src/ modules, tests,
and notifier/heartbeat support. Update Dockerfile, build/publish
scripts, dependabot and workflows, README, and provide env-based
docker-compose and .env examples.
Currently, the multi-stage Docker build makes the `release` stage
inherit from `dependencies`, which will include any files created by the
`pip install` process in the final image.
By using `pip install --user` to make dependencies be installed in
`~/.local`, we can only copy those files into the final image, reducing
the image size:
```
cloudflare-ddns-fix-applied latest 68427bd7c88d 3 minutes ago 54.6MB
cloudflare-ddns-master latest 2675320b651d 8 minutes ago 65.9MB
```
A good resource going deeper on how this approach works can be found at
https://pythonspeed.com/articles/multi-stage-docker-python/, solution 1.