Deploying Cloudflare DDNS Service on a NAT VPS

Preface

Yesterday, I got a VPS on Taiwan’s HiNet NAT from Lamhosting. Seeing that it’s HiNet residential broadband and only ¥9.9 per month, I was tempted to buy it, especially after using the Mid-Autumn Festival discount code, which gave me 20% off, bringing it down to around $1 per month. This is also my first time using a NAT VPS. Since this VPS has a dynamic IP, the IP changes frequently, making it inconvenient to connect to the VPS and set up nodes. Therefore, I’m using DDNS to bind the device to a domain name for easier use.

🗃️Setup Environment and Dependencies

  • ✅ Debian 12.6
  • curl
  • cron

🔩Configure DDNS Service

Obtain Cloudflare’s API Token

  • Log in to Cloudflare
  • Click on the profile icon in the upper right corner and select My Profile
  • Under { } API Tokens,clickCreate Token -In theAPI Token TemplatesfindEdit Zone DNS and click Use this template
  • Locate Zone Resources, select your domain from the selectdropdown, then clickContinue to review->Create Token to save
  • Record the API token and test the token command, then try running the test command
1#test the token command
2curl -X GET "https://api.cloudflare.com/client/v4/user/tokens/verify" \
3-H "Authorization: Bearer API Tokens" \
4-H "Content-Type:application/json"

Install the necessary dependencies on the VPS

Ensure that the curl tool is installed on the VPS. If not, install it using the following command:

1sudo apt update
2sudo apt install curl

Write a DDNS Update Script

Create a new script (e.g., cloudflare-ddns.sh) with the following content:

 1#!/bin/bash
 2
 3# Cloudflare API Information
 4CF_API_TOKEN="Your Cloudflare API Token"
 5ZONE_ID="Your Cloudflare Domain Zone ID"
 6RECORD_ID="Your DNS Record ID"
 7RECORD_NAME="Your bound subdomain"
 8IP=$(curl -s http://checkip.amazonaws.com)
 9
10# Update DNS Record
11curl -X PUT "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records/${RECORD_ID}" \
12     -H "Authorization: Bearer ${CF_API_TOKEN}" \
13     -H "Content-Type: application/json" \
14     --data "{\"type\":\"A\",\"name\":\"${RECORD_NAME}\",\"content\":\"${IP}\",\"ttl\":120,\"proxied\":false}"
  • CF_API_TOKEN:The API Token you created in Cloudflare.
  • ZONE_ID:The Zone ID found in Cloudflare.
  • RECORD_ID:The ID of the DNS record you want to update.
  • RECORD_NAME:The domain to update, such as example.com or sub.example.com
  • IP:The method for obtaining the current external IP address.

ObtainZONE IDandRECORD ID

1# obtain Zone ID
2curl -X GET "https://api.cloudflare.com/client/v4/zones?name=Your primary domain" \
3     -H "Authorization: Bearer ${CF_API_TOKEN}" \
4     -H "Content-Type: application/json"
5
6# obtain DNS Record ID
7curl -X GET "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records?name=${RECORD_NAME}" \
8     -H "Authorization: Bearer ${CF_API_TOKEN}" \
9     -H "Content-Type: application/json"

Enter the obtained ZONE ID and RECORD IDinto the cloudflare-ddns.shscript."

Set up a scheduled task for cloudflare-ddns.shto update automatically

Installcron

Use the following command to install cron

1sudo apt update
2sudo apt install cron

Start and enable the cronservice

After installation, start the cron service and ensure it runs automatically at system startup

1sudo systemctl start cron
2sudo systemctl enable cron

Edit the crontab to set up a scheduled task:

1crontab -e

Add the following line to update the DNS record every 5 minutes:

1*/5 * * * * /path/to/cloudflare-ddns.sh >/dev/null 2>&1

Replace /path/to/cloudflare-ddns.sh with the actual path to your script

With this, the DDNS service is configured. You can run the script from the directory where cloudflare-ddns.sh is located

1{"result":{"id":"XXXX","zone_id":"XXXX","zone_name":"Primary domain","name":"the bound subdomains","type":"A","content":"ip address","proxiable":true,"proxied":false,"ttl":120,"settings":{},"meta":{"auto_added":false,"managed_by_apps":false,"managed_by_argo_tunnel":false},"comment":null,"tags":[],"created_on":"2024-08-27T06:06:31.022794Z","modified_on":"2024-09-17T15:28:34.627094Z"},"success":true,"errors":[],"messages":[]}

If the prompt above appears, the update script is configured correctly

Built with Hugo
Theme Stack designed by Jimmy