linux中ddns自动更新需严格区分公网与内网场景:公网ddns(如duckdns)通过curl/lynx向服务商http推送ip,无需bind;内网ddns(isc dhcp+bind)则依赖dnssec-keygen密钥、dhcpd.conf与named.conf中ddns-update-style和allow-update严格匹配,且需校验密钥一致性、区域文件serial递增及客户端host-name选项。

Linux 中的 DDNS 自动更新不是“开箱即用”的功能,必须明确区分两种场景:一种是客户端向公网 DDNS 服务商(如 DuckDNS、No-IP)上报 IP;另一种是内网自建 DNS + DHCP,由 DHCP 服务器或客户端主动更新 BIND 区域记录。混淆这两者会导致配置完全失效。
区分公网 DDNS 和内网 DDNS 更新路径
公网 DDNS(如 DuckDNS、3322.net)靠 HTTP 请求推送 IP,不依赖 DNS 服务器权限或密钥;内网 DDNS(ISC DHCP + BIND)则必须通过 nsupdate 或 DHCP 服务端的 ddns-update-style interim 机制,且强依赖密钥认证和区域 allow-update 配置。
- 公网场景下,
named.conf、dhcpd.conf、dnssec-keygen全部无关,装了 BIND 反而可能干扰本地解析 - 内网场景下,缺任意一环——密钥未加载进
named、区域文件allow-update写错、DHCP 客户端没发host-name选项——更新都会静默失败 -
nsupdate -k成功 ≠ DHCP 自动更新成功:前者是手动测试通路,后者依赖 DHCP 服务端是否真正发起更新请求(看/var/log/syslog里有没有added update或update failed)
用 curl/lynx 向 DuckDNS 或 3322.net 推送 IP
这是最轻量、最不容易出错的公网 DDNS 方式,适合家庭路由器后 Ubuntu 主机、树莓派等设备。
Zynq‑7000 / Zynq UltraScale+ 硬件调试技能。适用于 Xilinx Zynq(Cortex‑A9/A53 + FPGA)Linux 环境,调试 I2C、I2S、UART、GPIO 等外设。包括设备树配置、内核驱动、用户空间调试工具、交叉编译和常见问题排查,支持 PetaLinux 开发。
- 脚本里必须用
curl -s或lynx -mime_header捕获返回状态,DuckDNS 成功返回OK,失败返回NOCHG或badagent,不能只看命令退出码 - URL 中的
ip=参数留空(即ip=)表示让服务商自动探测来源 IP;若填死 IP,需确保脚本运行环境能正确获取外网地址(curl ifconfig.me比ifconfig可靠) - 日志路径如
/var/log/duckdns.log必须提前touch并chown给运行用户(如systemd定时任务常用www-data或普通用户),否则 cron 会静默丢弃输出 - 示例命令:
curl -s "https://www.duckdns.org/update?domains=myhome&token=abc123&ip=" >> /var/log/duckdns.log
内网 BIND + ISC DHCP 实现自动正反向更新
关键不在“配得全”,而在“哪一步最先断”。BIND 的 allow-update 和 DHCP 的 ddns-update-style 必须严格匹配,且密钥文件路径、算法、secret 字符串三处必须完全一致。
- BIND 端:密钥定义必须在
named.conf.options或被include的文件中,且key块名(如dhcp-ddns-key)要与zone块里的allow-update { key "dhcp-ddns-key"; };完全一致(含引号) - DHCP 端:
ddns-update-style interim;是强制项,use-host-decl-names on;和update-static-leases on;根据是否用host声明决定;zone块里的primary地址必须是 BIND 监听的 IP(如127.0.0.1或实际内网 IP),不能写localhost - 区域文件(如
db.example.com)开头的$ORIGIN和$TTL必须存在,且 SOA 记录中的序列号(serial)每次修改后必须递增,否则 BIND 拒绝动态更新 - 调试时优先查
journalctl -u bind9 -n 50和journalctl -u isc-dhcp-server -n 50,而不是直接改配置;BIND 日志里出现update: 'example.com/IN' denied表示密钥或 ACL 拒绝,update: unexpected rcode (REFUSED)多因 zone 文件语法错误或 serial 未更新
真正卡住的地方往往不是“怎么配”,而是密钥字符串复制时多了空格、BIND 没 reload 而只是 restart、或者 DHCP 客户端根本没发送 host-name 选项(tcpdump -i eth0 port 53 可验证)。先确认通路,再谈自动化。










