A simple, efficient Dynamic DNS (DDNS) client written in Go. It automatically updates a specified Cloudflare DNS record (Type A) with the machine's current public IPv4 address.
Many Internet Service Providers (ISPs) assign dynamic public IP addresses to residential and some business connections. This makes it challenging to reliably connect to services hosted on these networks (e.g., home servers, NAS, cameras).
This DDNS client solves this problem by periodically checking the machine's public IP address and updating a corresponding DNS record in Cloudflare. This ensures that your domain or subdomain always points to your network's current IP address.
- Public IP Detection: Automatically determines the current public IPv4 address using an external service (
icanhazip.com). - Cloudflare Integration: Uses the official Cloudflare Go SDK to interact with the API securely via API Tokens.
- Targeted Updates: Updates a specific
Arecord within a specified Cloudflare zone. - Idempotent: Only performs an update if the detected public IP differs from the one currently set in the DNS record, minimizing unnecessary API calls.
- Preserves Settings: Keeps the existing Time-To-Live (TTL) and Proxied (Orange Cloud) status of the DNS record during updates.
- Configuration: Easily configured using environment variables.
- Cross-Platform: Compiles and runs on Linux, macOS, and Windows.
- Lightweight: Minimal dependencies and resource footprint.
- Docker Support: Ready to be containerized using Docker.
Before you begin, ensure you have the following:
- Go: Version 1.23.4 or later installed (required for building from source). (Download Go)
- Docker: Required if you plan to use the Docker instructions. (Install Docker)
- Cloudflare Account: An active Cloudflare account.
- Domain Managed by Cloudflare: The domain for which you want to update DNS records must be managed by Cloudflare.
- Cloudflare API Token:
- Generate a token with Edit zone DNS permissions.
- Go to Cloudflare Dashboard -> Manage Account -> Account API Tokens -> Create Token.
- Use the "Edit zone DNS" template.
- Permissions needed:
Zone:Zone:Read,Zone:DNS:Edit. - Zone Resources: Select the specific zone(s) this token should manage (e.g.,
Include -> Specific zone -> yourdomain.com). - Important: Securely store the generated token. You will only see it once.
- Existing DNS Record: An existing
Arecord in your Cloudflare zone that you wish to keep updated (e.g.,subdomain.yourdomain.comoryourdomain.com). This client currently updates existing records, it does not create them if missing.
- Clone the repository:
git clone https://github.com/kbhuyan/cf-ddns-client.git cd cf-ddns-client - Build the executable:
This will create the
go build -o cf-ddns-client .cf-ddns-client(orcf-ddns-client.exeon Windows) executable in the current directory.
Check the Releases page for pre-compiled binaries for your operating system and architecture. Download the appropriate binary and place it in a convenient location (e.g., /usr/local/bin on Linux/macOS).
The client is configured using environment variables:
CF_API_TOKEN(Required): Your Cloudflare API Token (see Prerequisites).- Security: Treat this token like a password. Do not commit it directly into your code or share it publicly.
CF_ZONE_NAME(Required): The name of the Cloudflare zone (your domain) that contains the DNS record you want to update.- Example:
example.com
- Example:
CF_RECORD_NAME(Required): The full DNS name of theArecord to update.- Example (Subdomain):
home.example.com - Example (Root Domain):
example.com
- Example (Subdomain):
-
Set Environment Variables:
- Linux/macOS:
export CF_API_TOKEN="YOUR_CLOUDFLARE_API_TOKEN" export CF_ZONE_NAME="yourdomain.com" export CF_RECORD_NAME="subdomain.yourdomain.com"
- Windows (Command Prompt):
set CF_API_TOKEN=YOUR_CLOUDFLARE_API_TOKEN set CF_ZONE_NAME=yourdomain.com set CF_RECORD_NAME=subdomain.yourdomain.com
- Windows (PowerShell):
$env:CF_API_TOKEN="YOUR_CLOUDFLARE_API_TOKEN" $env:CF_ZONE_NAME="yourdomain.com" $env:CF_RECORD_NAME="subdomain.yourdomain.com"
(Replace placeholder values with your actual configuration)
- Linux/macOS:
-
Run the client:
- If built from source:
./cf-ddns-client - If downloaded from releases:
/path/to/cf-ddns-client
- If built from source:
The client will output logs to standard output indicating the steps taken (fetching IP, checking DNS, updating if necessary).
You can easily build and run this client as a Docker container. This is useful for isolating the application and its dependencies, and for deploying in containerized environments.
-
Build the Docker Image: Navigate to the project root directory (where the
Dockerfileis located) and run:docker build -t your-dockerhub-username/cf-ddns-client:latest . # Or simply: # docker build -t cf-ddns-client .
(Replace
your-dockerhub-usernameif you plan to push the image to Docker Hub) -
Run the Docker Container: Use
docker runto execute the client within a container. Pass the required configuration as environment variables using the-eflag:docker run --rm \ -e CF_API_TOKEN="YOUR_CLOUDFLARE_API_TOKEN" \ -e CF_ZONE_NAME="yourdomain.com" \ -e CF_RECORD_NAME="subdomain.yourdomain.com" \ cf-ddns-client
--rm: Automatically removes the container when it exits.- Replace placeholder values with your actual configuration.
For persistent storage of logs (optional), you could mount a volume:
docker run --rm \ -e CF_API_TOKEN="YOUR_CLOUDFLARE_API_TOKEN" \ -e CF_ZONE_NAME="yourdomain.com" \ -e CF_RECORD_NAME="subdomain.yourdomain.com" \ -v /path/on/host/logs:/app/logs \ cf-ddns-client > /path/on/host/logs/cf-ddns-client.log 2>&1
(Note: The current application logs to stdout/stderr. Redirecting the container's output (
> ... 2>&1) is a common way to capture logs when running manually or via simple schedulers like cron).
For the DDNS client to be effective, it needs to run periodically (e.g., every 5-15 minutes). Choose the method that best suits your environment:
Edit your crontab: crontab -e
- For Direct Execution:
*/10 * * * * export CF_API_TOKEN='YOUR_TOKEN'; export CF_ZONE_NAME='yourdomain.com'; export CF_RECORD_NAME='subdomain.yourdomain.com'; /path/to/your/cf-ddns-client >> /var/log/cf-ddns-client.log 2>&1
- For Docker Execution:
*/10 * * * * /usr/bin/docker run --rm -e CF_API_TOKEN='YOUR_TOKEN' -e CF_ZONE_NAME='yourdomain.com' -e CF_RECORD_NAME='subdomain.yourdomain.com' cf-ddns-client >> /var/log/cf-ddns-client-docker.log 2>&1
- Note: Ensure the environment variables are correctly defined or passed. Make sure the
dockercommand is in the PATH for the cron user, or use the full path (e.g.,/usr/bin/docker).
- Note: Ensure the environment variables are correctly defined or passed. Make sure the
Create a systemd service unit file (e.g., /etc/systemd/system/cf-ddns.service) and a timer unit file (/etc/systemd/system/cf-ddns.timer). This provides more robust service management, especially for Docker containers. You can define environment variables directly within the service file using Environment= or EnvironmentFile=.
Use the built-in Task Scheduler application to create a task that runs the cf-ddns-client.exe executable or a docker run command at your desired interval. You can configure the task to load the necessary environment variables or pass them in the command arguments if running Docker.
- Uses the cloudflare-go library for interacting with the Cloudflare API.
- Relies on the public IP detection service provided by icanhazip.com.