58 lines
2.4 KiB
Bash
Executable File
58 lines
2.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# ==============================================================================
|
|
# cloudflare-ddns.sh
|
|
# 用途:定时检测家庭宽带真实公网 IPv4 并自动同步至 Cloudflare (home.961504.xyz & *.home.961504.xyz)
|
|
# 运行频率:通过 macOS LaunchAgent 每 5 分钟自动执行一次
|
|
# ==============================================================================
|
|
set -euo pipefail
|
|
|
|
# 从环境变量或 .env 读取 Token
|
|
if [ -f "$HOME/homelab/.env" ]; then
|
|
# shellcheck disable=SC1091
|
|
source "$HOME/homelab/.env"
|
|
fi
|
|
|
|
ZONE_ID="${CF_ZONE_ID:-8cf327569373837f075fa7f9e5bb7edd}"
|
|
TOKEN="${CF_API_TOKEN}"
|
|
|
|
# 获取国内真实出口公网 IP(绕过国外代理分流)
|
|
WAN_IP=$(curl -4 -s --max-time 5 https://myip.ipip.net | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' | head -n 1 || true)
|
|
if [ -z "$WAN_IP" ]; then
|
|
WAN_IP=$(curl -4 -s --max-time 5 http://members.3322.org/dyndns/getip | tr -d '[:space:]' || true)
|
|
fi
|
|
|
|
if [ -z "$WAN_IP" ]; then
|
|
echo "[$(date '+%Y-%m-%d %H:%M:%S')] ERROR: 无法获取当前家庭宽带公网 IP"
|
|
exit 1
|
|
fi
|
|
|
|
CACHE_FILE="$HOME/homelab/backups/last_wan_ip.txt"
|
|
LAST_IP=$(cat "$CACHE_FILE" 2>/dev/null || true)
|
|
|
|
if [ "$WAN_IP" = "$LAST_IP" ]; then
|
|
echo "[$(date '+%Y-%m-%d %H:%M:%S')] OK: 公网 IP 未变化 ($WAN_IP)"
|
|
exit 0
|
|
fi
|
|
|
|
echo "[$(date '+%Y-%m-%d %H:%M:%S')] INFO: 检测到公网 IP 更新 ($LAST_IP -> $WAN_IP),正在同步至 Cloudflare..."
|
|
|
|
for NAME in "home.961504.xyz" "*.home.961504.xyz"; do
|
|
REC_ID=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records?type=A&name=$NAME" \
|
|
-H "Authorization: Bearer $TOKEN" \
|
|
-H "Content-Type: application/json" | /opt/homebrew/bin/jq -r '.result[0].id // empty')
|
|
if [ -n "$REC_ID" ]; then
|
|
curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$REC_ID" \
|
|
-H "Authorization: Bearer $TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
--data "{\"type\":\"A\",\"name\":\"$NAME\",\"content\":\"$WAN_IP\",\"ttl\":60,\"proxied\":false}" >/dev/null
|
|
else
|
|
curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records" \
|
|
-H "Authorization: Bearer $TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
--data "{\"type\":\"A\",\"name\":\"$NAME\",\"content\":\"$WAN_IP\",\"ttl\":60,\"proxied\":false}" >/dev/null
|
|
fi
|
|
done
|
|
|
|
echo "$WAN_IP" > "$CACHE_FILE"
|
|
echo "[$(date '+%Y-%m-%d %H:%M:%S')] SUCCESS: 已将 home.961504.xyz 与 *.home.961504.xyz 更新为 $WAN_IP"
|