Introduction

Some hosting providers offer small VPS instances behind dynamic NAT without providing a DDNS service. In such cases, we need to set one up ourselves.

This is a beginner-friendly tutorial that utilizes Cloudflare. Before you begin, please ensure your domain is already managed by Cloudflare.

This script only implements DDNS for IPv4. On a side note, I’ve yet to encounter dynamic IPv6 addresses anyway.


Configure a Cloudflare API Token

Find Your Zone ID

Navigate to your domain’s dashboard on Cloudflare. On the right-hand side, scroll down to the API section and find your Zone ID. Make a note of it.

JcpcubWpWyZTNL8YtiUXFKq42x2YuRLm

Create an API Token

Go to My Profile -> API Tokens.

dzGitifDNwTLcgxD2IXNZRdzEsNaLx9c

Create a new API token with the following permissions:

STsWwkIp35p9mgFUt0BRApauBFfzIsEZ

Once created, make a note of your API Token.

Add an A Record

In your Cloudflare DNS panel, add a new A record. You can set its initial value to a placeholder like 1.1.1.1. The script will update it later.


Update the DNS Record and Configure Cron

The DDNS Script

Create a new script file and name it cf-ddns.sh (or any other name you prefer).

#!/bin/bash

# --- CONFIGURATION ---
# The Zone ID for your domain
ZONE_ID="your_zone_id_here"
# Your Cloudflare API Token
API_TOKEN="your_api_token_here"
# The full DNS record you want to update (e.g., home.example.com)
RECORD_NAME="home.example.com"
# --- END CONFIGURATION ---

# Get current public IP
IP=$(curl -s https://ipv4.icanhazip.com)

# Get the Record ID for the DNS record
RECORD_ID=$(curl -s -X GET \
  "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records?type=A&name=$RECORD_NAME" \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" | jq -r '.result[0].id')

# Update the DNS record with the new IP
RESPONSE=$(curl -s -X PATCH \
  "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  --data "{\"type\":\"A\",\"name\":\"$RECORD_NAME\",\"content\":\"$IP\",\"ttl\":120,\"proxied\":false}")

# Log the response
echo "$(date): $RESPONSE"

Note: The script uses jq to parse JSON. If you don’t have it installed, run: apt install jq -y.

Make the script executable: chmod +x /root/cf-ddns.sh

Run the script once to test it: ./cf-ddns.sh. If it’s successful, you should see a response containing "success":true.

Add a Cron Job

To run the script automatically, edit your crontab file: crontab -e

Add the following line to run the script every five minutes and log the output: */5 * * * * /root/cf-ddns.sh >> /var/log/cf-ddns.log 2>&1

This example uses a 5-minute interval, but you can change it to every 2 minutes (*/2 * * * *) or another value if you wish.

After the script runs, you’ll see that the A record in your Cloudflare dashboard has been updated to your server’s current IP address.

Build DDNS via Cloudflare

Author

Shayne Wong

Publish Date

10 - 08 - 2025

License

Shayne Wong

Avatar
Shayne Wong

All time is no time when it is past.