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 Templates
findEdit Zone DNS
and clickUse this template
- Locate
Zone Resources
, select your domain from theselect
dropdown, 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 asexample.com
orsub.example.com
。IP
:The method for obtaining the current external IP address.
ObtainZONE ID
andRECORD 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 ID
into the cloudflare-ddns.sh
script."
⏳Set up a scheduled task for cloudflare-ddns.sh
to update automatically
Installcron
Use the following command to install cron
:
1sudo apt update
2sudo apt install cron
Start and enable the cron
service
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