前言
通常,我們會將服務與特定域名關聯,發生IP地址變化,就必須到Cloudflare網站上更新域名指向。最麻煩是在使用浮動IP的情況下,變更IP會相當頻繁,如果不及時處理,可能會導致服務中斷。為了避免這情況,必須採取一個優化方案,這樣一來,無論IP地址變動,都能確保服務持續穩定運行,不再受到IP變更的干擾。
思路
我們可以透過Cloudflare的API自動更新DNS記錄,確保域名總是指向我的服務最新的IP地址。
步驟: 檢查目前IP->改變時更新域名指向IP
申請Cloudflare API
首先我們需要先申請Cloudflare的API,申請方式也相對簡單,再登入Cloudflare後前往 https://dash.cloudflare.com/profile/api-tokens ,點擊「建立Token」。
在「編輯區域 DNS」選項中,按下「使用範本」就能快速建立。
權限設置「區域, DNS, 編輯」,區域資源設置「包含, 特定區快, 域名」,完成後點擊「繼續至摘要」。
檢查Token要申請權限是不是正確,確定後點擊「建立 Token」。
這時候可以先記錄下API權杖(後續CF_API_KEY變數),也可以將下面CURL命令複製到終端機命令介面進行測試,只要有回傳This API Token is valid and active就代表成功。
透過 Cloudflare API 取得 ZoneID 與 RecordID
將下面curl指令中的「API權杖」替換剛取得的API權杖,並到終端機命令介面執行。
curl -X GET "https://api.cloudflare.com/client/v4/zones" \
-H "Authorization: Bearer API權杖" \
-H "Content-Type:application/json" | python -m json.tool
會得到類似下面資訊請找出你想要能控制域名的id,這個id就是ZoneID(後續ZONE_ID變數)。
將下面curl指令中的「API權杖」替換剛取得的API權杖,ZoneID替換為上面步驟記錄id,並到終端機命令介面執行。
curl -X GET "https://api.cloudflare.com/client/v4/zones/ZoneID/dns_records" \
-H "Authorization: Bearer API權杖" \
-H "Content-Type:application/json" | python3 -m json.tool
會得到類似下面資訊,請找出你想要能控制子域名的id,這個id就是RecordID(後續RECORD_ID變數)。
實作
BASH腳本如下,請將CF_EMAIL替換Cloudflare帳號使用信箱,CF_API_KEY、ZONE_ID和RECORD_ID替換前面所記錄資訊,RECORD_NAME修改為子域名前綴,比如在前面案例是cftest.ipv4.site,請填cftest,後續只要將下面BASH腳本寫入排程,就能輕鬆達成定期更新域名IP。
#!/bin/bash
# Cloudflare API credentials
CF_EMAIL="[email protected]"
CF_API_KEY="your_api_key"
ZONE_ID="your_zone_id"
RECORD_ID="your_record_id"
RECORD_NAME="your_record_name"
# Get current public IP address
CURRENT_IP=$(curl -s https://ipv4.icanhazip.com)
# Get previous public IP address from a file
if [ -f "previous_ip.txt" ]; then
PREVIOUS_IP=$(cat previous_ip.txt)
else
PREVIOUS_IP=""
fi
# Compare current and previous IP addresses
if [ "$CURRENT_IP" != "$PREVIOUS_IP" ]; then
# Update Cloudflare DNS record
curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \
-H "Authorization: Bearer $CF_API_KEY" \
-H "Content-Type: application/json" \
--data "{\"type\":\"A\",\"name\":\"$RECORD_NAME\",\"content\":\"$CURRENT_IP\",\"ttl\":120,\"proxied\":true}"
# Save current IP address to a file
echo "$CURRENT_IP" > previous_ip.txt
fi