本文提供一套面向开发者的实操方案,说明如何在位于香港的 VPS 上通过简单脚本定期检测外网地址变更并调用 DNS 服务商 API 自动更新解析。文章包含检测方法、常见服务商选择、示例脚本、调度建议与安全注意点,便于快速部署可用的 脚本自动追踪 与 更新 DNS 记录 流程。
检测频率取决于运营需求与供应商变更频率。对多数家庭/共享宽带模式的 VPS 动态 IP,建议检测间隔为 5–15 分钟;对企业或不常变动的环境,可设为 30 分钟或更长以减少 API 请求与流量。若担心 DNS 更改延迟,可在更新时把 TTL 设低(例如 60–300 秒),方便快速生效。
常用的公网 IP 服务有 https://ipv4.icanhazip.com、https://ifconfig.me、https://api.ipify.org 和 https://ipinfo.io/ip。选择时优先考虑响应稳定、延迟低的服务,或直接使用云提供商的元数据接口(如果可用)。建议在脚本中加入备选接口,当主接口失败时回退到次选。
脚本基本逻辑为:获取当前外网 IP → 读取上次记录的 IP → 对比差异 → 若不同则调用 DNS 服务商 API 更新并保存新 IP。下面给出基于 Cloudflare 的 Bash 示例(可改为 DNSPod、阿里云、GoDaddy 等):
#!/bin/bash
# 配置
ZONE_ID="你的ZoneID"
RECORD_ID="你的RecordID"
API_TOKEN="你的APIToken"
RECORD_NAME="sub.example.com"
LAST_FILE="/tmp/last_ip_${RECORD_NAME//./_}"
# 获取当前 IPv4
IP=$(curl -s --max-time 5 https://ipv4.icanhazip.com | tr -d '\n')
[ -z "$IP" ] && exit 1
# 读取上次 IP
[ -f "$LAST_FILE" ] && LAST_IP=$(cat "$LAST_FILE") || LAST_IP=""
if [ "$IP" != "$LAST_IP" ]; then
echo "IP changed: $LAST_IP -> $IP"
RESPONSE=$(curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \
-H "Authorization: Bearer $API_TOKEN" -H "Content-Type: application/json" \
--data "{\"type\":\"A\",\"name\":\"$RECORD_NAME\",\"content\":\"$IP\",\"ttl\":300}")
echo "$RESPONSE"
if echo "$RESPONSE" | grep -q '"success":true'; then
echo "$IP" > "$LAST_FILE"
fi
fi
API 凭证应保存到受限访问的配置文件或系统密钥管理中,避免硬编码到脚本。示例做法:将凭证放在 /etc/yourapp/credentials.conf,并限制权限为 600;或使用操作系统的 secret store(如 HashiCorp Vault、AWS Secrets Manager)。另外,使用最小权限的 API token(仅允许修改指定域名/记录)可降低风险。
香港的 VPS 可能同时有 IPv4 和 IPv6 地址,若域名需支持双栈访问,应分别检测并更新 A 与 AAAA 记录。TTL 设置影响解析生效速度:短 TTL 有利于快速切换但会增加解析请求,长 TTL 可减少 DNS 流量但变更传播慢。针对频繁变更的环境,临时降低 TTL 是常用策略。
推荐使用 cron 或 systemd timer 定时执行脚本,例如每 5 分钟运行一次:*/5 * * * * /usr/local/bin/update_ddns.sh。为便于排查与监控,脚本应写入日志(带时间戳),并在更新失败或检测接口异常时通过邮件、Webhook 或推送服务(Telegram、企业微信)发送告警。
在中国/香港用户中常用的有 Cloudflare(全球性能好)、DNSPod、阿里云 DNS 与腾讯云 DNS。若解析需要在大陆有更好表现,可优先考虑 DNSPod/阿里云;若要全球访问速度和简单权限管理,Cloudflare 是不错的选择。选择时查看 API 文档与限速策略,确保脚本能稳定工作。