惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

罗磊的独立博客
L
LangChain Blog
aimingoo的专栏
aimingoo的专栏
IT之家
IT之家
B
Blog
博客园_首页
博客园 - 司徒正美
有赞技术团队
有赞技术团队
博客园 - 聂微东
I
InfoQ
美团技术团队
GbyAI
GbyAI
阮一峰的网络日志
阮一峰的网络日志
H
Help Net Security
大猫的无限游戏
大猫的无限游戏
MyScale Blog
MyScale Blog
WordPress大学
WordPress大学
The GitHub Blog
The GitHub Blog
A
About on SuperTechFans
人人都是产品经理
人人都是产品经理
Microsoft Azure Blog
Microsoft Azure Blog
Engineering at Meta
Engineering at Meta
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
The Cloudflare Blog

涛叔

友链可能导致网站掉备案 基于 Nginx + GeoLite2 搭建简易 IP 查询工具 另一种轻量的 Linux VPS 共享方案 DMIT 主机自定义 IPv6 地址 自用 Claude Code 拼车中转服务 欢迎使用 @ZZ.AC 邮箱服务 我在用的 VPS 云主机 实现备份3-2-1原则 Go语言接口的空指针问题 玩转 ZZ.AC 域名 ZZ.NIC 公益 Linux 主机空间 使用 Nginx 构建计费 DoH 代理服务 通过 Let’s Encrypt 为 IP 地址签发免费 SSL 证书
使用 DDNS 动态更新 ZZ.AC 域名
2026-07-22 · via 涛叔

现在 ZZ.AC 域名支持 DDNS 功能了,本文跟大家分享 DDNS 功能的设计理念和使用方法。

设计理念

先说之前为什么不支持 DDNS 🤦‍♂️

第一是因为系统设计的比较简单,每个用户使用单独的 zone 文件保存自已的记录,如果要支持通过 API 更新,整个系统需要重新设计,工作量很大。

第二是为了预防滥用。因为开启了 DDNS,大家就可以把自己的动态 IP 映射到 ZZ.AC 域名,不好跟踪发布的内容,从而产生滥用的风险。

那为什么现在又要支持了呢?

首先,整个 zz.nic 项目已经完成重构,前后端代码都整合到同一个项目1,这就为使用 LLM 奠定了基础。有了大模型加持,引入 DDNS 带来的工作量就不成问题了。

其次,我自己本身也强依赖 DDNS 功能。我家里的设备需要将 ISP 的动态公网 IP 地址映射到域名上。此外,家里的公网 IP 地址被禁用了 80 和 443 端口,无法使用 ACME HTTP-01 和 ACME ALPN-01 两种 Challenge 来申请 SSL 证书,只能使用 ACME DNS-01,这就要求域名需要支持 API 更新,也就是 DDNS 功能。

ZZ.AC 域名不支持 DDNS,所以之前只能临时使用另外一个域名配合 Cloudflare 实现。考虑到要坚持「吃自己的狗粮」,有必要给 ZZ.AC 域名引入 API 更新功能。

但如果开了 DDNS 功能,怎样防止滥用呢?我的办法是仿照工信部,引入「备案」设计。

简单来说,就是默认不开启 DDNS 能力。比如我的域名是 tao.zz.ac,我想把 NAS 设备绑定到 nas.tao.zz.ac 域名,我就得到 DDNS 后台 https://nic.zz.ac/ddns 给 nas 子域名创建 DDNS 令牌。目前支持 DDNS 和 ACME DNS-01 两种类型,创建时需要登记用途。创建成功之后会展示 Token 和使用方法。

管理员在后台可以看到所有登记的 DDNS 域名及其用途。同时会运行程序自动检查该域名是否有滥用行为。如有发现,直接封禁用户。

使用方法

有了 Token 就可以通过 curl 来更新对应的 A/AAAA 记录。

curl -X PUT -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"a":"1.2.3.4","aaaa":"2001:db8::1","ttl":300}' \
  https://nic.zz.ac/api/ddns/records

JSON 数据中的 a 和 aaaa 可以单独指定,也可以同时指定,都可以。多次调用会覆盖前面的值。但我建议有调用之前先检查当前值,有更新再调。

curl -H "Authorization: Bearer <token>" \
  https://nic.zz.ac/api/ddns/records

如果确认不需要了,请调用接口删除:

curl -X DELETE -H "Authorization: Bearer <token>" \
  https://nic.zz.ac/api/ddns/records

ACME 证书

如果要自动申请 SSL 证书,则需要创建 ACME DNS-01 类型的 Token,使用方法跟 DDNS 型的类似。

ACME DNS-01 本质上是要更新域名的 TXT 记录,所以调用方法如下:

curl -X PUT -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"value":"dns-01-challenge-token","ttl":60}' \
  https://nic.zz.ac/api/ddns/records

注意 JSON 中的 value 字段。又因为同一域名下可能有多条 TXT 记录,所以删除的时候需要指定记录值,不然会误删其他记录:

curl -X DELETE -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"value":"dns-01-challenge-token"}' \
  https://nic.zz.ac/api/ddns/records

要想申请 ACME 证书,光有接口还不行,还得集成到 ACME 客户端上。最容易集成的就是 acme.sh 因为只需要写一个 shell 脚本就可以了。这个脚本的核心功能是提供dns_zz_adddns_zz_rm两个接口,分别对应创建和删除 TXT 记录。将代码保存一 .acme.sh/dnsapi/dns_zz.sh

然后在签发证书时指定用 dns_zz 就可以了:

acme.sh --issue --dns dns_zz -d example.zz.ac -d "*.example.zz.ac"
点击查看 dns_zz.sh 完整代码
Options:
 ZZ_DDNS_TOKEN API Token
'

dns_zz_add() {
  fulldomain="$1"
  txtvalue="$2"
  ZZ_TTL="${ZZ_TTL:-60}"

  _info "Adding TXT record for $fulldomain"

  _savedomainconf ZZ_DDNS_TOKEN "$ZZ_DDNS_TOKEN"

  _zz_api PUT "{\"value\":\"$(_zz_json_escape "$txtvalue")\",\"ttl\":$ZZ_TTL}"
}

dns_zz_rm() {
  fulldomain="$1"
  txtvalue="$2"

  _info "Removing TXT record for $fulldomain"

  _zz_api DELETE "{\"value\":\"$(_zz_json_escape "$txtvalue")\"}"
}

_zz_api() {
  method="$1"
  data="$2"

  ZZ_TTL="${ZZ_TTL:-60}"
  ZZ_DDNS_TOKEN="${ZZ_DDNS_TOKEN:-}"

  if [ -z "$ZZ_DDNS_TOKEN" ]; then
    _err "ZZ_DDNS_TOKEN is not set"
    return 1
  fi

  url="https://nic.zz.ac/api/ddns/records"

  export _H1="Authorization: Bearer $ZZ_DDNS_TOKEN"
  export _H2="Content-Type: application/json"

  response="$(_post "$data" "$url" "" "$method")"
  ret="$?"

  _debug2 response "$response"

  if [ "$ret" != "0" ]; then
    _err "zz.ac API request failed"
    return 1
  fi

  if _contains "$response" "\"ok\":true"; then
    return 0
  fi

  _err "zz.ac API error: $response"
  return 1
}

_zz_json_escape() {
  printf '%s' "$1" | sed 's/\\/\\\\/g; s/"/\\"/g'
}

关于 deSEC

ZZ.AC 域名支持使用 deSEC 来解析。而 deSEC 本身有完整的 API,可以实现 DDNS 功能。那为什么不直接用它呢?确实我还真用过,但它的最小 TTL 是一小时,对于 DDNS 功能来说就点太长了。想想我家里临时断电又恢复,ISP 下发了新的公网 IP 地址,但我的域名解析要到一个小时之后才能生效,完全不能接受😷

而 ZZ.AC 官方的 DDNS 基本可以做到两分钟之内生效,而且还有优化的空间。

有了 DDNS 功能,我就可以离摆脱 Cloudflare 又近了一步,离去中心化的互联网又近了一步。


  1. https://git.zz.ac/zz/zz↩︎