net.LookupIP仅能静态查询域名IP,无法实现DDNS动态更新;真正DDNS需调用Cloudflare等服务商API主动推送新IP,且必须通过外部接口(如api.ipify.org)获取真实公网IP而非本地网卡地址。

为什么 net.LookupIP 不能直接替代 DNS 动态更新
很多人一上来就用 net.LookupIP 查域名,以为拿到 IP 就算“实现了动态解析”——其实这只是静态查询。真正的动态域名解析(DDNS)核心在于:当本地 IP 变化时,主动把新 IP 推送到 DNS 服务商(如 Cloudflare、阿里云 DNS)。net.LookupIP 不发任何更新请求,只读不写。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
- 若目标是“自动更新某域名指向本机公网 IP”,必须调用服务商提供的 API(如 Cloudflare 的
/zones/{zone_id}/dns_records/{id}) -
net.LookupIP可用于验证更新是否生效,但绝不能当作更新手段 - 注意区分:内网环境(如路由器拨号)下获取的是私有 IP,需先通过 STUN 或服务商接口获取真实公网 IP
如何用 Go 调用 Cloudflare API 实现 IP 自动更新
Cloudflare 是最常用也最友好的 DDNS 后端,Go 调用的关键是构造带认证的 PATCH 请求。它不接受简单 GET,必须用 PUT 或 PATCH 修改 DNS 记录。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
- 提前在 Cloudflare 控制台开启 API Token 权限(至少含
DNS:Edit),不要用全局 API Key - 用
http.Client设置超时(DNS 更新失败不能卡住主流程),推荐Timeout: 10 * time.Second - 记录 ID 必须提前查出并缓存(首次运行时用
GET /zones/{zone_id}/dns_records?type=A&name=example.com获取),避免每次重复查 - 响应状态码不是 200 就要记日志,常见错误:
400 Bad Request(IP 格式错)、403 Forbidden(Token 权限不足)、404 Not Found(zone_id 或 record_id 错)
怎样可靠获取本机当前公网 IPv4 地址
用 net.InterfaceAddrs() 拿到的全是局域网地址(192.168.x.x、10.x.x.x),对 DDNS 完全无效。必须向外发起一次 HTTP 查询,依赖外部服务返回真实出口 IP。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
- 推荐用
https://api.ipify.org(轻量、无认证、返回纯文本),Go 中用http.Get即可,注意 trim 换行符 - 别用
ifconfig.me或icanhazip.com,它们偶尔返回 HTML 或带空格,容易导致后续 API 调用失败 - 加一层本地缓存(比如 5 分钟内不重复查),避免频繁请求被限流;同时设 fallback 机制——如果获取失败,保留上次成功 IP 继续尝试更新(比用错 IP 更安全)
- IPv6 场景下需单独处理,Cloudflare API 的
content字段必须严格匹配类型(A记录填 IPv4,AAAA填 IPv6)
定时检查与更新逻辑怎么写才不容易丢更新
用 time.Ticker 做轮询看似简单,但网络波动、API 限频、DNS 生效延迟都会导致“看起来没更新”。关键不是频率多高,而是状态可追溯、失败可重试。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
- 每次运行先读取本地缓存文件(如
last_ip.txt),和当前公网 IP 对比;只有不一致才触发更新流程 - 更新成功后立刻写入新 IP 到缓存,并记录时间戳(避免重启后重复提交相同 IP)
- 失败时不要立即重试,用指数退避(
time.After(2 ),最多试 3 次 - 日志必须包含:当前 IP、目标域名、HTTP 状态码、响应体片段(截取前 100 字符),否则排查时只能猜
真正麻烦的不是写几行 http.Do,而是处理“刚更新完,ISP 就换 IP,而下一轮检查还没来得及跑”的窗口期。留个本地 PID 文件 + 信号捕获(os.Interrupt)比加个 Web UI 实用得多。



















