•
Cloudflare DDNS 完整教學:自動更新浮動 IP 的 DNS 記錄
11 分鐘閱讀 •
DDNS 運作原理
在開始設定之前,先來理解 DDNS 的運作流程。整個過程可以拆解成兩個核心步驟:首先是取得伺服器目前的對外 IP 位址,接著是透過 Cloudflare API 將這個 IP 寫入對應的 DNS 記錄。
sequenceDiagram
participant Server as 你的伺服器
participant IPService as IP 偵測服務
participant Cloudflare as Cloudflare API
participant DNS as DNS 記錄
Server->>IPService: 1. 查詢目前對外 IP
IPService-->>Server: 返回 203.0.113.42
Server->>Cloudflare: 2. 更新 DNS A Record
Note over Server,Cloudflare: Authorization: Bearer API_TOKEN
{"type": "A", "content": "203.0.113.42"}
Cloudflare->>DNS: 寫入新 IP
Cloudflare-->>Server: 更新成功
Note over Server,DNS: 現在 home.example.com 指向 203.0.113.42
當你家的 IP 位址改變時(例如路由器重新撥號),只要 DDNS 腳本再次執行,就會自動偵測到新的 IP 並更新 DNS 記錄。透過定時執行這個腳本,你的網域就能始終指向正確的位址。
前置需求
在開始之前,請先確認以下條件:
- 你的網域已經託管在 Cloudflare(DNS 由 Cloudflare 管理)
- 你已經在 Cloudflare 建立了要用於 DDNS 的 DNS 記錄(A 記錄或 AAAA 記錄)
- 你有辦法執行容器(Podman 或 Docker)
如果還沒建立 DNS 記錄,先到 Cloudflare Dashboard 的 DNS 頁面新增一筆 A 記錄,IP 可以先填任意值,之後 DDNS 會自動更新。
建立 Cloudflare API Token
Cloudflare API 使用 Token 進行身份驗證。為了遵循最小權限原則,我們要建立一個只有 DNS 編輯權限的專用 Token。
前往 Cloudflare Dashboard 的 API Tokens 頁面,依照以下步驟建立 Token:
- 點擊 Create Token
- 選擇 Custom token 範本
- 設定 Token 名稱,例如
DNS Update Script - 在 Permissions 區塊設定:Zone → DNS → Edit
- 在 Zone Resources 區塊設定:Include → All zones(或選擇特定網域)
- 點擊 Continue to summary,確認權限後點擊 Create Token
- 複製產生的 Token 並妥善保存
API Token 只會顯示一次,離開頁面後就無法再次查看。請立即複製並存放在安全的地方。
取得 Zone ID
Zone ID 是 Cloudflare 用來識別你網域的唯一識別碼。取得方式十分簡單:
- 登入 Cloudflare Dashboard
- 選擇你要設定 DDNS 的網域
- 在 Overview 頁面的右側欄位,找到 Zone ID
- 複製這串 32 字元的十六進位識別碼
取得 DNS Record ID
每筆 DNS 記錄都有一個獨立的 Record ID。這個 ID 無法在 Dashboard 上直接看到,需要透過 API 查詢。開啟終端機或 Postman,執行以下指令:
curl -X GET "https://api.cloudflare.com/client/v4/zones/YOUR_ZONE_ID/dns_records/" \
-H "Authorization: Bearer YOUR_API_TOKEN"
將 YOUR_ZONE_ID 和 YOUR_API_TOKEN 替換成剛才取得的值。執行後會列出該網域下所有 DNS 記錄的詳細資訊。找到你要用於 DDNS 的記錄,記下它的 id 值。
選擇 IP 偵測服務
DDNS 的第一步是取得目前的對外 IP。這需要透過一個外部服務來查詢,因為你的伺服器只能看到內網 IP,無法直接得知 NAT 後面的公開 IP 位址。
預設服務
simple-cloudflare-ddns 預設使用 ipify 服務:
- IPv4:
https://api.ipify.org - IPv6:
https://api6.ipify.org
這是一個運作多年的開源服務,直接返回你的 IP 位址純文字。
部署自己的 IP 偵測服務
依賴第三方服務有一定風險:服務可能停機、可能有速率限制,甚至有可能未來被惡意控制,回傳了駭客指定的其它內容。若你追求更高的可靠性,我建議部署自己的 IP 偵測服務。
我做了另一個開源專案 worker-your-ip,這是一個跑在 Cloudflare Workers 上的 IP 偵測服務。除了回傳 IP 位址,還能提供地理位置、時區、ASN 等額外資訊。
點擊上面的按鈕可以一鍵部署到你的 Cloudflare 帳號。部署完成後,你的 IP 偵測服務就會有以下端點:
/ip:返回 IPv4 或 IPv6 位址/ipv4:返回 IPv4 位址(如果沒有 IPv4 則回傳 400 錯誤)/ipv6:返回 IPv6 位址(如果沒有 IPv6 則回傳 400 錯誤)/json:以 JSON 格式返回完整資訊
執行 DDNS 更新
準備好所有資訊後,就可以執行 simple-cloudflare-ddns 了。
僅更新 IPv4
podman run --rm \
-e API_TOKEN=your_cloudflare_api_token \
-e ZONE_ID=your_zone_id \
-e A_RECORD_ID=your_a_record_id \
-e A_RECORD_NAME=home.example.com \
ghcr.io/jim60105/simple-cloudflare-ddns
僅更新 IPv6
podman run --rm \
-e API_TOKEN=your_cloudflare_api_token \
-e ZONE_ID=your_zone_id \
-e AAAA_RECORD_ID=your_aaaa_record_id \
-e AAAA_RECORD_NAME=home.example.com \
ghcr.io/jim60105/simple-cloudflare-ddns
同時更新 IPv4 和 IPv6
podman run --rm \
-e API_TOKEN=your_cloudflare_api_token \
-e ZONE_ID=your_zone_id \
-e A_RECORD_ID=your_a_record_id \
-e A_RECORD_NAME=home.example.com \
-e AAAA_RECORD_ID=your_aaaa_record_id \
-e AAAA_RECORD_NAME=home.example.com \
ghcr.io/jim60105/simple-cloudflare-ddns
使用自訂 IP 偵測服務
podman run --rm \
-e API_TOKEN=your_cloudflare_api_token \
-e ZONE_ID=your_zone_id \
-e A_RECORD_ID=your_a_record_id \
-e A_RECORD_NAME=home.example.com \
-e IPV4_API_URL=https://your-worker.workers.dev/ipv4 \
-e IPV6_API_URL=https://your-worker.workers.dev/ipv6 \
ghcr.io/jim60105/simple-cloudflare-ddns
設定定時執行
手動執行一次只能更新當下的 IP,但 DDNS 的重點在於持續監控。你需要設定排程讓腳本定期執行。
使用 Cron
在 Linux 系統上,cron 是最簡單的排程方式:
# 編輯 crontab
crontab -e
# 新增這行,每 30 分鐘執行一次
*/30 * * * * podman run --rm -e API_TOKEN=... -e ZONE_ID=... -e A_RECORD_ID=... -e A_RECORD_NAME=... ghcr.io/jim60105/simple-cloudflare-ddns
使用 Kubernetes CronJob
如果你的伺服器跑 Kubernetes,可以用 CronJob 來排程。按照最佳實踐,請將敏感資訊存在 Secret 裡:
apiVersion: v1
kind: Secret
metadata:
name: cloudflare-ddns
type: Opaque
stringData:
API_TOKEN: "your_cloudflare_api_token"
ZONE_ID: "your_zone_id"
A_RECORD_ID: "your_a_record_id"
A_RECORD_NAME: "home.example.com"
apiVersion: batch/v1
kind: CronJob
metadata:
name: simple-cloudflare-ddns
spec:
schedule: "*/5 * * * *"
concurrencyPolicy: Forbid
successfulJobsHistoryLimit: 1
failedJobsHistoryLimit: 3
jobTemplate:
spec:
template:
spec:
restartPolicy: Never
containers:
- name: ddns
image: ghcr.io/jim60105/simple-cloudflare-ddns:latest
imagePullPolicy: IfNotPresent
envFrom:
- secretRef:
name: cloudflare-ddns
執行 kubectl apply -f secret.yaml 和 kubectl apply -f cronjob.yaml 套用設定。
環境變數參考
完整的環境變數說明如下:
| 變數名稱 | 必要性 | 說明 | 預設值 |
|---|---|---|---|
API_TOKEN | 必要 | Cloudflare API Token | - |
ZONE_ID | 必要 | Cloudflare Zone ID | - |
A_RECORD_ID | 選填 | IPv4 A 記錄的 Record ID | - |
A_RECORD_NAME | 選填 | A 記錄的網域名稱 | - |
AAAA_RECORD_ID | 選填 | IPv6 AAAA 記錄的 Record ID | - |
AAAA_RECORD_NAME | 選填 | AAAA 記錄的網域名稱 | - |
IPV4_API_URL | 選填 | 取得 IPv4 位址的 API 端點 | https://api.ipify.org |
IPV6_API_URL | 選填 | 取得 IPv6 位址的 API 端點 | https://api6.ipify.org |
A_RECORD_ID 和 AAAA_RECORD_ID 至少要設定其中一個,否則腳本沒有目標可更新。
結語
DDNS 的原理和實作都不複雜,核心就是「偵測 IP」加上「呼叫 API 更新記錄」這兩件事。simple-cloudflare-ddns 把這些邏輯包裝成一個輕量的容器,只需要設定幾個環境變數就能使用。
專案原始碼在 GitHub 上開源,歡迎提出問題或參與貢獻:

回覆
你可以使用 Mastodon 或其他 ActivityPub/Fediverse 帳號來公開回覆此文章。現有的公開回覆顯示在下方。