DNSControl 5.7 常用 CLI 命令详解
DNSControl v5.7.0 全子命令实测:preview/push(--expect-no-changes、--report、--full、-i)、check、print-ir、get-zones 五种导出格式、check-creds、fmt、write-types、shell-completion 与废弃命令说明,回显逐行照抄。
DNSControl 5.7 常用 CLI 命令详解
目标:逐个讲清 DNSControl v5.7.0 全部子命令的用途、参数与真实回显——main 组(init/preview/push)、debug 组(check/print-ir/version)、utility 组(get-zones/check-creds/fmt/write-types/shell-completion/create-domains)及全局参数。全部命令已在 Ubuntu 22.04 + DNSControl v5.7.0 + BIND 9.18.39 环境实测(2026-10-25),回显逐行照抄。
一、环境信息
- 操作系统:Ubuntu 22.04.5 LTS,x86_64
- 软件版本:DNSControl v5.7.0;配套权威 DNS:BIND 9.18.39-0ubuntu0.22.04.7
- 工作目录
/etc/dnscontrol/:dnsconfig.js(管理example.io,NS 为ns1.example.io.,www A 记录 192.168.1.72)与creds.json(BIND provider,directory/srv/zones/primary),均已在 BIND9 上跑通 - 安装与首次配置见 《Ubuntu 22.04 安装 DNSControl 5.7 指南》;DSL 参数详解见 《DNSControl 5.7 配置参数详解》
二、工具概览
dnscontrol --help 实测输出(子命令全景):
NAME:
dnscontrol - DNSControl is a compiler and DSL for managing dns zones
USAGE:
dnscontrol [global options] [command [command options]]
VERSION:
DNSControl version v5.7.0
COMMANDS:
help, h Shows a list of commands or help for one command
main:
init Interactively create a creds.json and starter dnsconfig.js
preview read live configuration and identify changes to be made, without applying them
push identify changes to be made, and perform them
debug:
check Check and validate dnsconfig.js. Output to stdout. Do not access providers.
print-ir Output intermediate representation (IR) after running validation and normalization logic.
version Print version information
utility:
check-creds Do a small operation to verify credentials (stand-alone)
create-domains DEPRECATED: Ensures that all domains in your configuration are activated at their Domain Service Provider (This does not purchase the domain or otherwise interact with Registrars.)
fmt [BETA] Format and prettify a given file
get-zones, get-zone gets a zone from a provider (stand-alone)
shell-completion generate shell completion scripts
write-types [BETA] Write a TypeScript declaration file in the current directory
GLOBAL OPTIONS:
--debug Enable debug logging
--allow-fetch Enable JS fetch(), dangerous on untrusted code!
--disableordering Disables update reordering
--no-colors Disable colors
--help, -h show help
--version, -V print the version
分组解读:日常只有 preview/push 两个动词;check/print-ir/version 用于排障与调试;utility 组是围绕 provider 的独立小工具(不读 dnsconfig.js 也能用)。全局参数中排障最常用 --debug,CI 环境建议加 --no-colors。
三、前置条件
cd /etc/dnscontrol # 以下命令默认读当前目录的 dnsconfig.js / creds.json
dnscontrol version
v5.7.0
四、main 组命令
4.1 version / -V:版本确认
dnscontrol -V
dnscontrol version
实测回显(两行分别对应两个写法,-V 带前缀):
dnscontrol version DNSControl version v5.7.0
v5.7.0
4.2 init:交互式生成初始配置
dnscontrol init --help 实测:
NAME:
dnscontrol init - Interactively create a creds.json and starter dnsconfig.js
USAGE:
dnscontrol init [options]
CATEGORY:
main
DESCRIPTION:
Walks you through picking a registrar and DNS provider, entering their credentials, and writing a creds.json plus a minimal dnsconfig.js so a fresh setup can run `dnscontrol preview` immediately.
OPTIONS:
--creds string Output path for the credentials file (default: "creds.json")
--config string Output path for the starter DNSControl config (default: "dnsconfig.js")
--no-config Do not write a starter dnsconfig.js
--help, -h show help
逐选项说明:--creds/--config 改输出路径;--no-config 只生成凭证不生成配置。init 为交互式向导(逐项提问),适合首次接入云厂商 provider;自建 BIND 场景手工写两个文件更直接(见安装篇第六节)。
4.3 preview:比对差异、不落地
核心参数(preview --help 实测节选):
--config string File containing dns config in javascript DSL (default: "dnsconfig.js")
--creds string Provider credentials JSON file (or !program to execute program that outputs json) (default: "creds.json")
--providers string Providers to enable (comma separated list); default is all.
--domains string Comma separated list of domain names to include
--notify set to true to send notifications to configured destinations
--expect-no-changes set to true for non-zero return code if there are changes
--cmode string Which providers to run concurrently: concurrent, none, all (default: "concurrent")
--cmax int Maximum number of concurrent connections (default: 100)
--no-populate Do not auto-create zones at the provider
--populate-on-preview Auto-create zones on preview
--full Add headings, providers names, notifications of no changes, etc
--bindserial int Force BIND serial numbers to this value (for reproducibility) (default: 0)
--report string Generate a machine-parseable report of corrections.
(1) 无变更基准(配置与线上一致时):
dnscontrol preview
CONCURRENTLY checking for 1 zone(s)
Waiting for concurrent checking(s) to complete...DONE
CONCURRENTLY gathering records of 1 zone(s)
Waiting for concurrent gathering(s) to complete...DONE
******************** Domain: example.io
Done. 0 corrections.
(2) --expect-no-changes(CI 漂移检测):无变更时退出码 0;人为改动配置后出现待变更时退出码 1:
dnscontrol preview --expect-no-changes; echo "rc=$?"
无变更实测:
...
Done. 0 corrections.
rc=0
把 www 的 A 记录从 192.168.1.72 改成 192.168.1.73 后再跑:
******************** Domain: example.io
1 correction (bind)
#1: ± MODIFY www.example.io A (192.168.1.72 ttl=300) -> (192.168.1.73 ttl=300)
Done. 1 corrections.
there are pending changes
rc=1
(3) --report:机器可解析报告:
dnscontrol preview --report=/tmp/report.json
cat /tmp/report.json
实测回显:
[
{
"domain": "example.io",
"corrections": 1,
"correction_details": [
"± MODIFY www.example.io A (192.168.1.72 ttl=300) -> (192.168.1.73 ttl=300)"
],
"provider": "bind"
},
{
"domain": "example.io",
"corrections": 0,
"registrar": "none"
}
]
(4) --domains / --providers 过滤范围(多域多 provider 时缩小执行面):
dnscontrol preview --domains example.io
dnscontrol preview --providers bind
两者实测均正常完成比对并输出 Done. 0 corrections.。
(5) --full:打印各 provider 分组汇总与统计(含零变更项,便于审计留档):
----- DNS Provider: bind...
0 corrections (bind)
----- Registrar: none...
0 corrections (none)
Inaccurate statistics: {"memory_in_use":18155800,"memory_in_use_str":"18 MB","num_records":12,"num_zones":1,"rc_size":200,"benchmark1":1512983,"benchmark1str":"1.4 MiB bytes"}
Done. 0 corrections.
(6) --debug:看三段式执行过程(preview --debug 实测节选):
Reading dnsconfig.js or equiv.
Reading creds: "creds.json"
Creating an in-memory model of 'desired'...
Normalizing and validating 'desired'..
PHASE 1: CHECKING for missing zones
...
PHASE 2: GATHERING data
...
PHASE 3: CORRECTIONS
4.4 push:应用变更
参数与 preview 相同,另多一个 -i(Interactive,逐条确认/排除变更后再执行)。
(1) 首次 push(zone 不存在时自动建 zone,再写入全部记录):
dnscontrol push
实测回显(节选首尾):
******************** Domain: example.com
1 correction (bind)
#1: Ensuring zone "example.com" exists in "bind"
SUCCESS!
...
#1: + CREATE example.com SOA ns1.example.com. hostmaster.example.com. X 3600 600 604800 3600 ttl=300
+ CREATE example.com A 192.168.1.31 ttl=300
...
+ CREATE blog.example.com CNAME www.example.com. ttl=300
WRITING ZONEFILE: "/srv/zones/primary/example.com.zone" (serial 2026102500)
SUCCESS!
Done. 14 corrections.
(2) 增量 push(只应用差异;serial 自动 +1):
#1: ± MODIFY www.example.com A (192.168.1.31 ttl=300) -> (192.168.1.32 ttl=300)
WRITING ZONEFILE: "/srv/zones/primary/example.com.zone" (serial 2026102501)
SUCCESS!
Done. 1 corrections.
⚠️ 注意:BIND provider 下 push 只写 zone 文件,要让 BIND9 生效需再执行
rndc reload(实测:reload 前 dig 返回旧值 192.168.1.32,reload 后为新值 192.168.1.33)。--no-populate可禁止 push 自动建 zone(报 zone 不存在而非自动创建)。
五、debug 组命令
5.1 check:离线校验
dnscontrol check
No errors.
只解析+校验 dnsconfig.js,不访问任何 provider,适合作为提交前钩子。支持 --config、--variable、-v。语法错误实测:
executing bad.js: (anonymous): Line 4:2 Unexpected token ;
(退出码 1,行号定位到出错位置。)
5.2 print-ir:查看中间表示
dnscontrol print-ir --pretty | head -20
实测回显(节选):
{
"registrars": [
{
"name": "none",
"type": "-"
}
],
"dns_providers": [
{
"name": "bind",
"type": "-",
"meta": {
"default_soa": {
"expire": 604800,
"master": "ns1.example.io.",
"mbox": "hostmaster.example.io.",
"minttl": 300,
"refresh": 3600,
"retry": 600
}
}
}
],
参数(print-ir --help 实测):--pretty 格式化;--raw 跳过校验与规范化直接输出 JS 执行结果;--out 写文件;--ir 直接读 IR JSON 而不跑 DSL;--variable/-v 注入变量。用途:确认 DSL 渲染结果、排查 TTL/修饰符是否生效。
六、utility 组命令
6.1 get-zones:从 provider 反向导出 zone
不依赖 dnsconfig.js,直接按 creds.json 里的实例名拉取。格式参数 --format:js / djs / zone / tsv / nameonly(默认 zone)。
(1) zone 格式(BIND zone file 文本):
dnscontrol get-zones --format=zone bind example.com
实测回显:
$ORIGIN example.com.
$TTL 300
@ IN SOA ns1.example.com. hostmaster.example.com. 2026102501 3600 600 604800 3600
IN NS ns1.example.com.
IN A 192.168.1.31
IN MX 10 mail.example.com.
IN TXT "v=spf1 ip4:192.168.1.31 -all"
IN CAA 0 issue "letsencrypt.org"
_dmarc IN TXT "v=DMARC1; p=none; rua=mailto:dmarc@example.com"
_sip._tcp IN SRV 10 60 5060 sip.example.com.
blog IN CNAME www.example.com.
mail IN A 192.168.1.31
ns1 IN A 192.168.1.31
www IN A 192.168.1.32
IN AAAA 2001:db8::31
(2) tsv 格式(便于脚本处理,节选 5 行):
example.com @ 300 IN SOA ns1.example.com. hostmaster.example.com. 2026102501 3600 600 604800 3600
example.com @ 300 IN NS ns1.example.com.
example.com @ 300 IN A 192.168.1.31
example.com @ 300 IN MX 10 mail.example.com.
example.com @ 300 IN TXT v=spf1 ip4:192.168.1.31 -all
(3) nameonly 与 all(列出该 provider 全部 zone 名):
dnscontrol get-zones --format=nameonly bind all
example.com
(4) js 格式:生成 dnsconfig.js 草稿(存量域名纳入管理的起点):
dnscontrol get-zones --format=js bind example.com
实测回显:
// generated by get-zones. This is 'a decent first draft' and requires editing.
var DSP_BIND = NewDnsProvider("bind", "");
var REG_CHANGEME = NewRegistrar("none");
D("example.com", REG_CHANGEME,
{no_ns: "true"},
DnsProvider(DSP_BIND),
//SOA("@", "ns1.example.com.", "hostmaster.example.com.", 3600, 600, 604800, 3600),
//NAMESERVER("ns1.example.com."),
A("@", "192.168.1.31"),
MX("@", 10, "mail.example.com."),
TXT("@", "v=spf1 ip4:192.168.1.31 -all"),
CAA("@", "issue", "letsencrypt.org"),
TXT("_dmarc", "v=DMARC1; p=none; rua=mailto:dmarc@example.com"),
SRV("_sip._tcp", 10, 60, 5060, "sip.example.com."),
CNAME("blog", "www.example.com."),
A("mail", "192.168.1.31"),
A("ns1", "192.168.1.31"),
A("www", "192.168.1.32"),
AAAA("www", "2001:db8::31"),
);
(5) djs 格式 + --out 落盘:
dnscontrol get-zones --format=djs --out=draft.js bind example.com
生成的 draft.js 与 js 格式内容一致,仅逗号前置风格不同(djs 方言)。另有 --ttl int 参数:导出时给无 TTL 记录指定默认 TTL,0(默认)表示取 zone 内最常见 TTL。
6.2 check-creds:凭证连通性自检
dnscontrol check-creds bind
实测回显(成功时列出该 provider 可见的 zone 清单):
example.com
退出码 0。也兼容旧式两参数写法 dnscontrol check-creds bind BIND(第二参数为 provider 类型)。失败案例实测(creds 条目缺 TYPE 字段):
failed GetZone CDP: creds.json entry missing TYPE field
退出码 1。--creds 指定的文件不存在时:
INFO: Config file "/etc/dnscontrol/nope.json" does not exist. Skipping.
failed GetZone LZ: directory "zones" does not exist
6.3 fmt [BETA]:格式化 dnsconfig.js
dnscontrol fmt --input=/tmp/messy.js --output=/tmp/messy_fmt.js --verbose
实测回显:
/tmp/messy_fmt.js (formatted)
--verbose 打印处理结果;diff 前后文件可见缩进被统一(实测差异节选):
< "default_soa": {
---
> "default_soa": {
对已规范文件再跑 fmt 幂等(diff 无实质差异)。默认输入输出都是当前目录 dnsconfig.js(原地格式化),生产使用前建议先 --output 到临时文件比对。
6.4 write-types [BETA]:生成 TypeScript 类型声明
dnscontrol write-types
实测回显:
Successfully wrote types-dnscontrol.d.ts
-rw-r--r-- 1 root root 205187 Oct 25 14:04 types-dnscontrol.d.ts
生成的 types-dnscontrol.d.ts(约 200KB)导入 VS Code 等 IDE 后,编辑 dnsconfig.js 可获得 DSL 函数的自动补全与签名提示;--dts-file/-o 改输出路径。
6.5 shell-completion:生成 shell 补全脚本
dnscontrol shell-completion bash | head -6
实测回显(节选):
#!/bin/bash
: "dnscontrol"
# Macs have bash3 for which the bash-completion package doesn't include
# _init_completion. This is a minimal version of that function.
支持 bash | zsh,把完整输出重定向到 /etc/bash_completion.d/dnscontrol 即可启用 Tab 补全。
6.6 create-domains:已废弃
v5.7.0 实测输出:
DEPRECATED: This command is deprecated. The domain is automatically created at the Domain Service Provider during the push command.
DEPRECATED: To prevent disable auto-creating, use --no-populate with the push command.
*** example.io
- bind
zone 的自动创建已并入 push,该命令仅为兼容保留,新流程不要再用。
七、注意事项
- 退出码约定:preview/push 正常完成为 0;
--expect-no-changes检测到待变更时为 1;语法错误/凭证失败为 1。但 push 中个别 provider 写文件失败(如目录不存在)会输出completed with errors而退出码仍为 0,自动化脚本须同时检查输出文本。 - 并发参数:
--cmode concurrent(默认)并发检查/拉取多 zone,--cmax 100限制最大并发连接;zone 数量大或 provider 限流时调低。 - 颜色输出:TTY 下 corrections 带 ANSI 颜色,写日志/CI 加全局
--no-colors。 - 生效链路:BIND provider 的 push 终点是 zone 文件,BIND9 需
rndc reload后才对外生效;云厂商 provider 的 push 直接调 API 即时生效。 - serial 生成:BIND zone 的 SOA serial 自动取
YYYYMMDDHH日期序号,同日内多次 push 递增;需要可复现构建时用--bindserial钉死。
八、常见问题
8.1 子命令拼错
Unknown command: nosuchcmd
退出码 1。用 dnscontrol help 或 dnscontrol <子命令> --help 查正确拼写。
8.2 preview 正常但 push 报 could not create zonefile
creds.json 里 BIND provider 的 directory 不存在。mkdir -p 后重试(详见安装篇常见问题 9.2 的完整排障过程)。
8.3 check 报 ReferenceError
配置引用了未注入的变量,补 --variable 名=值(见配置参数详解第八节)。
8.4 想让 preview 在 CI 里有变更即失败
加 --expect-no-changes,并用 --report=report.json 留机器可解析证据(4.3 节实测)。
九、参考链接
- 官方命令文档:
https://docs.dnscontrol.org/commands - 《DNSControl 5.7 介绍与选型指南》
- 《Ubuntu 22.04 安装 DNSControl 5.7 指南》
- 《DNSControl 5.7 配置参数详解》