DDNS 解决固定域名绑定家庭网络动态IP
DDNS
DDNS(动态域名系统,Dynamic DNS)是一种扩展传统 DNS 功能的技术,用于在 IP 地址经常变化的环境中,自动将域名解析到最新的 IP 地址。它通过客户端软件或路由器与 DDNS 服务商保持通信,实现 DNS 记录的实时更新,从而保证即使在动态 IP 环境下,用户也能通过固定的域名访问设备或服务。
什么是 DDNS
DDNS(Dynamic DNS)是一种自动更新域名系统(DNS)记录的方法,能够在主机 IP 地址变化时,实时修改 DNS 服务器上的对应记录,免去人工手动修改的繁琐步骤 。
动态更新机制
TSIG标准更新:利用 RFC 2136 所定义的动态更新协议,配合 TSIG(Transaction SIGnature)进行安全验证,由 DHCP 或客户端主动向 DNS 服务器发送更新请求。
专有 Web API 更新:多数面向家庭或小型企业的 DDNS 服务商提供 HTTP/HTTPS 接口,客户端通过带有帐号凭证的简单请求(如 DynDNS2 协议)触发 DNS 记录更新 。
应用场景
家庭和小型网络
家庭宽带 ISP 通常分配动态公网 IP,若想远程访问家中 NAS、摄像头或私人服务器,就需要 DDNS 服务提供一个固定的域名
企业分支与移动设备
企业分支机构或移动办公设备通过 DHCP 获得 IP,借助标准化的 DDNS 更新,可以让企业内网服务(如打印机、文件服务器)在 Active Directory 等环境中保持可用性
IoT 设备与安全设备
IP 摄像头、DVR、安全网关等会通过内置客户端自动更新 DDNS,确保管理员随时能够通过域名访问设备界面
如何配置 DDNS
下面是如何在 Cloudflare 上注册 DDNS 服务,并利用 Web API 实现动态更新。
在 Cloudflare 仪表盘添加域名并获取 Zone ID。
创建具有“Edit zone DNS”权限的 API Token。
在 DNS 管理中新增目标 A 记录,并记录其 Record ID。
编写 Bash 脚本,通过 Cloudflare REST API 定期检测公网 IP,并对比后调用 API 更新记录。
使用 cron 或系统定时任务实现自动化执行。
以上流程可帮助你在动态 IP 环境下,通过固定域名访问家用或办公网络资源。
1. 添加域名与获取 Zone ID
首先,登录你的 Cloudflare 账号,进入“网站”列表,将你要动态更新的域名(例如 example.com)添加至 Cloudflare 并完成 DNS 托管设置
添加完成后,在仪表盘的“概览”页面可以看到该域名对应的 Zone ID,后续 API 调用时需用到此值。
2. 创建 API Token
在 Cloudflare 仪表盘右上角点击个人头像,选择“My Profile”→“API Tokens”→“Create Token”
在模板列表中选择“Edit zone DNS”预设,此模板默认包含:对指定 Zone 的 DNS 编辑权限( Zone.Zone、Zone.DNS)
指定 Token 作用域:在“Zone Resources”里选择“Include”→“Specific Zone”→填入上一步的 Zone ID。
完成后记下生成的 API Token(格式类似 v1.xxxxx),后续脚本中通过 Authorization: Bearer
3. 在仪表盘新增 A 记录
进入“DNS”→“Records”,点击“Add record”→类型选“A”,Name 填入子域(如 home),Content 留空或填入当前 IP(可随脚本更新),TTL 设置为“Auto”或自定义 。
新增完成后,点击该记录可查看其 Record ID,或通过 API 列表接口检索:
curl -X GET "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records?name=home.example.com" \
-H "Authorization: Bearer ${API_TOKEN}" \
-H "Content-Type: application/json"
从返回的 JSON 中提取 .result[0].id 即为 RECORD_ID 。
4. 编写动态更新脚本
以下示例使用 Bash + jq 实现:
#!/usr/bin/env bash
# 配置项
API_TOKEN="你的_API_Token"
ZONE_ID="你的_Zone_ID"
RECORD_NAME="home.example.com"
RECORD_TYPE="A"
# 获取当前公网 IP
CURRENT_IP=$(curl -s https://ipv4.icanhazip.com)
# 获取 Record ID
RECORD_ID=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records?name=${RECORD_NAME}" \
-H "Authorization: Bearer ${API_TOKEN}" \
-H "Content-Type: application/json" | jq -r .result[0].id)
# 获取 DNS 记录的当前 IP
RECORD_IP=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records/${RECORD_ID}" \
-H "Authorization: Bearer ${API_TOKEN}" \
-H "Content-Type: application/json" | jq -r .result.content)
if [ "$CURRENT_IP" != "$RECORD_IP" ]; then
# 更新 DNS 记录
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\":\"${RECORD_TYPE}\",\"name\":\"${RECORD_NAME}\",\"content\":\"${CURRENT_IP}\",\"ttl\":1}")
echo "$(date) 更新 IP 为 ${CURRENT_IP},响应:${RESPONSE}"
else
echo "$(date) IP 无变化,当前仍为 ${CURRENT_IP}"
fi
该脚本先通过公开服务获得当前公网 IP,然后对比 DNS 记录中保存的 IP,若不同则发起 PUT 请求覆盖更新。
ttl:1 表示自动 TTL;如需自定义请调整为秒级数值。
5. 部署与自动化
将脚本保存为 cf-ddns.sh 并赋予执行权限:
chmod +x cf-ddns.sh
使用 cron 定时执行(每 5 分钟检测一次):
*/5 * * * * /path/to/cf-ddns.sh >> /var/log/cf-ddns.log 2>&1
此后脚本会自动监测 IP 变动并更新 Cloudflare 上的 A 记录