Purpose
Production-ready, self-hosted **Cloudflare DDNS** agent written in Rust. The binary discovers your current public IPv4/IPv6 address, compares it with Cloudflare DNS records, and applies updates safely with retries, email notifications, and optional systemd automation.
Current state
Last touched: 2025-11-25. Functionality and completeness: Core DDNS sync, retries, and systemd deployment are documented.
Next step
Add baseline automated tests to cover critical flows; Add CI pipeline for build/test/lint; Document deployment/runtime environment (or add Dockerfile); Document interfaces (CLI flags, API endpoints, file formats); Add structured logging and basic health checks.
Interfaces
Inputs- config.toml, environment variables (CF_API_TOKEN, CF_ZONE_NAME, CF_RECORD_NAME), CLI flags
- Configuration files (TOML/YAML/JSON/INI/CONF)
Outputs- Updated Cloudflare A/AAAA records
- optional email notifications
Reality to Action trace
Reality IngestionContributes in this stage.
Canonical StorageNot in scope.
Automation EnginesNot in scope.
Human InterfacesContributes in this stage.
Operational AdoptionContributes in this stage.
Core workflow
TBD. Document the 5-10 steps that define the core workflow.
Artifacts
- Config supports single-zone CLI/env inputs or multi-zone `[[zones]]` tables
Operational notes
Constraints and scars
- Requires existing Cloudflare DNS records; the agent refuses to create missing records.
Reliability posture
Failure modes and safe behavior: Missing records or API errors abort; no record creation is attempted. Idempotency / retries / batching behavior: Idempotent updates; retries with jittered backoff for 429/5xx.
Observability
- Logs: Rust logging framework detected (log/tracing/env_logger). Control verbosity with RUST_LOG=info, debug, or trace.
- Metrics/health checks: None documented; rely on logs and exit codes
Security and privacy
Use scoped API tokens (Zone:Read + DNS:Edit only). Restrict /etc/cloudflare-ddns/cloudflare-ddns.env to 0600 when running under systemd. Avoid printing secrets in shell history; prefer env files or secret stores. Portable mode is fully read-only and never writes configs to disk.
Dependencies
Upstream- Cloudflare API, public IP detection services, optional SMTP relay
Ownership
OwnersJosh Barton
UsersJosh Barton (owner)
cloudflare-ddns-rs
Architecture & Major Components
High-level diagram (text):
- Entry/trigger -> core logic -> outputs (details per docs below)
Entry/trigger
→core logic
→outputs
Entry points: src/main.rs
Top-level folders: release, src, systemd
Key abstractions: Config loader (TOML/env/CLI), IP detection, Cloudflare API client, systemd installer
Setup / Build / Run
- Build system(s): Cargo.
- Rust 1.74+ (stable) with cargo for building from source.
- Linux host if you plan to use the bundled systemd units (systemctl + root required).
- Outbound HTTPS connectivity to Cloudflare and your chosen public IP detection services.
- Optional SMTP relay for email notifications.
- Portable mode uses CLI/env only; systemd install copies binary, writes config/env templates, and enables a timer.