PowerDNS 5.1.4 常用 CLI 命令与工具详解
PowerDNS Authoritative 5.1.4 全套命令行实测:pdns_control 状态统计与缓存管理、pdnsutil 区域/DNSSEC/TSIG 管理、zone2sql 迁移、guardian 模式命令差异与全限定名等实测陷阱。
PowerDNS 5.1.4 常用 CLI 命令与工具详解
目标:覆盖 PowerDNS Authoritative Server 5.1.4 全套命令行工具——
pdns_control(运行时控制)、pdnsutil(区域与 DNSSEC 管理)、zone2sql/zone2json(区域文件转换)、pdns_server(服务进程与配置诊断)与 systemd 服务管理。全部命令逐条实测,输出逐行照抄(实测环境 Ubuntu 22.04.4,实测日期 2026-10-20)。
一、环境信息
- 操作系统:Ubuntu 22.04.4 LTS(x86_64),systemd 249
- PowerDNS Authoritative Server:5.1.4-1pdns.ubuntu22.04(官方 APT 源 jammy-auth-51)
- 数据库后端:gsqlite3(
/var/lib/powerdns/pdns.sqlite3),服务监听127.0.0.2:53 - 已创建区域:
example.com(A/MX/NS/TXT 记录,已启用 DNSSEC) - 客户端验证工具:dig 9.18.39-0ubuntu0.22.04.6-Ubuntu
- 工具所在路径(
dpkg -L pdns-server实测):
/usr/bin/pdns_control
/usr/bin/pdnsutil
/usr/bin/zone2json
/usr/bin/zone2sql
/usr/sbin/pdns_server
二、工具概览
| 工具 | 定位 | 典型场景 |
|---|---|---|
pdns_control | 通过 Unix 控制套接字(/run/pdns/pdns.controlsocket)与运行中的服务对话 | 状态巡检、统计观察、缓存清理、配置核查、停服 |
pdnsutil | 直接读写数据库(不经过服务),管理区域/记录/DNSSEC/TSIG | 建区删区、增改查记录、签名与密钥管理 |
zone2sql | BIND 格式区域文件转 SQL 语句(gmysql/gpgsql/gsqlite 等) | 从 BIND 迁移数据到 SQL 后端 |
zone2json | 区域文件转 JSON | 数据迁移或外部系统集成 |
pdns_server | 服务本体;命令行模式用于版本/配置诊断 | 版本查询、配置校验、全量配置打印 |
pdns.service / pdns@.service | systemd 单元 | 启停、自启、日志 |
重要差异:pdns_control 修改的是运行中的服务,pdnsutil 修改的是数据库。用 pdnsutil 建区删区后,运行中的服务需要 pdns_control rediscover 刷新区域缓存(create-zone 回显中官方明确提示此步)。
三、前置条件
确认服务在运行且控制套接字存在:
systemctl is-active pdns && pdns_control rping && ls /run/pdns/
实测回显:
active
PONG
pdns.controlsocket
服务未运行时 pdns_control 会报 Fatal error: Unable to connect to remote '/var/run/pdns/pdns.controlsocket': No such file or directory(RuntimeDirectory 随服务退出被回收)。
四、pdns_control 详解
4.1 命令总表与有效性实测
5.1.4 man 页(man pdns_control COMMANDS 节)列出的命令全集如下,本机逐条验证后标注实测结果:
| 命令 | 实测结果 | 说明 |
|---|---|---|
version / uptime / rping / list / show / qtypes / remotes / respsizes / ccounts / current-config / reload / rediscover / flush / purge / list-zones / quit(别名 stop)/ set / notify / notify-host / retrieve | ✅ 正常 | 正文逐个展开 |
bind-add-zone / bind-domain-status / bind-domain-extended-status / bind-list-rejects / bind-reload-now | 仅 bind 后端 | 本机用 gsqlite3,不适用 |
ping、cycle、status | ❌ Unknown command | 仅 guardian 模式可用;发行包 systemd 单元以 --guardian=no 运行(见 4.2) |
token-login | 加密令牌登录 | 特殊部署用,不展开 |
4.2 存活与版本
pdns_control version
pdns_control uptime
pdns_control rping
实测回显(逐行):
5.1.4
2 minutes
PONG
⚠️ 实测陷阱:
pdns_control ping与pdns_control status在本机均报Unknown command: 'PING'/Unknown command: 'STATUS'。官方 man 页写明:ping 只在 guardian 模式下可用,rping 用于非 guardian 模式;发行包的 systemd 单元ExecStart=/usr/sbin/pdns_server --guardian=no --daemon=no ...固定了非 guardian 形态,因此一律用rping。cycle(重启守护进程)同样仅在 guardian 模式下可用,实测报Unknown command: 'CYCLE'——以 systemctl restart 替代。
4.3 状态与统计
show <统计项> 查看单项指标,支持通配符:
pdns_control show udp-queries
pdns_control show 'udp-*'
实测回显:
7
udp-in-errors, udp-in-packets, udp-oversize-errors, udp-received-chunk, udp-received-timeout-chunk, udp-requests, udp-truncated, udp4-in-errors, udp4-in-packets, udp4-oversize-errors, udp4-received-chunk, udp4-received-timeout-chunk, udp4-requests, udp4-truncated, udp6-in-errors, udp6-in-packets, udp6-oversize-errors, udp6-received-chunk, udp6-received-timeout-chunk, udp6-requests, udp6-truncated
可用统计项名全集:pdns_control list(输出一个逗号分隔的长列表,含 cache-hit、cache-miss、packetcache-hit、packetcache-miss、query-cache-hit 等全部计数器)。
按查询类型计数(先制造两类查询再观察):
dig @127.0.0.2 www.example.com A +short > /dev/null
dig @127.0.0.2 example.com MX +short > /dev/null
pdns_control qtypes
实测回显:
A: 1
MX: 1
来源客户端与应答包长分布:
pdns_control remotes | head -1
pdns_control respsizes | head -2
实测回显:
127.0.0.1 4
0 1
8 1
(respsizes 输出格式为「包长 计数」,按包长升序。)
ccounts 汇总缓存情况(清缓存后归零验证):
pdns_control purge
pdns_control ccounts
实测回显:
13
negative queries: 0, queries: 0, packets: 0
4.4 缓存与配置管理
| 命令 | 实测回显 | 说明 |
|---|---|---|
pdns_control flush | Ok | 清空全部查询/包缓存(5.1.4 新增名,等价旧 purge) |
pdns_control purge | 13 | 按记录名精确失效缓存(无参则清全量,回显为失效条数) |
pdns_control reload | Ok | 重载后端模块与配置 |
pdns_control rediscover | Ok | 重新发现区域(pdnsutil 改库后必做) |
pdns_control current-config | 全量生效配置 | 见 4.4.1 |
pdns_control current-config diff | 非默认项 | 见 4.4.1 |
pdns_control set <参数> <值> | This setting cannot be changed at runtime, or no such setting | 实测 loglevel、local-port 均拒绝;绝大多数参数不支持热更 |
4.4.1 current-config:配置漂移核查第一入口
pdns_control current-config diff
实测回显:
# Autogenerated configuration file based on running instance (2026-10-20 16:39:21 +0800)
disable-syslog=
domain-metadata-cache-ttl=60
gsqlite3-database=/var/lib/powerdns/pdns.sqlite3
gsqlite3-dnssec=yes
include-dir=/etc/powerdns/pdns.d
launch=gsqlite3
local-address=127.0.0.2
log-timestamp=no
server-id=ops
write-pid=no
其中 disable-syslog=、log-timestamp=no、write-pid=no 来自 systemd 单元 ExecStart 命令行参数,优先级高于 pdns.conf——排查"配置改了不生效"时以本命令输出为准(参数体系详见《PowerDNS 5.1.4 配置参数详解》第三章)。
4.5 区域与主从
pdns_control list-zones
实测回显:
example.com. Native
All zonecount: 1
通知与拉取类命令(主从场景):notify <区域> 主动发 NOTIFY,实测未配置主从时的回显为:
PowerDNS not configured as primary (primary), or secondary (secondary) with re-notifications
notify-host <区域> <IP> 可指定目标;retrieve <区域> 触发从主服务器拉取 AXFR(仅 secondary=yes 时有效)。
4.6 停服:quit / stop
pdns_control quit
实测回显与结果:
Fatal error: Unable to connect to remote '/var/run/pdns/pdns.controlsocket': No such file or directory
systemctl is-active pdns
inactive
💡 说明:
quit(别名stop)把停服指令送达服务进程后连接即中断,工具端可能回显上述连接错误;以systemctl is-active pdns的inactive为准。服务停止后 RuntimeDirectory 被回收,再执行 pdns_control 命令都会报同样的连接错误。日常运维建议直接systemctl stop pdns(systemd 形态下的标准停法)。
五、pdnsutil 详解
5.1 命令命名空间与 help
5.1.x 的 pdnsutil help 给出按命名空间分组的命令树(完整 245 行可本机 pdnsutil help 查看),主干结构:
Zone Commands:
zone create <zone> [nsname]
zone delete <zone>
zone list
zone list-all
zone check <zone>
zone check-all
zone show <zone>
zone rectify <zone>
zone clear <zone>
zone load <zone> <filename>
zone edit <zone>
zone copy <zone> <newzone>
zone copy-from <zone> <newzone>
zone export <zone>
zone export-json <zone>
zone increase-serial <zone>
zone [disable-dnssec|secure] <zone>
zone list-keys <zone>
zone add-zone-key <zone> ...
zone remove-zone-key <zone> <keyid>
zone set-nsec3 <zone> ...
zone unset-nsec3 <zone>
zone ds <zone> ...
zone export-ds <zone>
zone apply-dnssec <zone> ...
zone publish-cdnskey <zone> ...
zone delete-cdnskey <zone> ...
zone publish-cds <zone> ...
zone delete-cds <zone> ...
Zone Record Commands:
rrset add <zone> <name> <type> [ttl] "<content>"...
rrset replace <zone> <name> <type> [ttl] "<content>"...
rrset delete <zone> <name> <type>
rrset hash <name> [hash algorithm] ...
rrset add-record <zone> <name> <type> [ttl] "<content>"...
rrset delete-record <zone> <name> <type> <hash>
rrset list <zone>
TSIG Commands:
tsigkey generate <name> <algorithm> [<key>]
tsigkey list
tsigkey delete <name>
...
💡 说明:5.x 同时兼容旧式扁平命令——
pdnsutil create-zone、add-record、check-zone、enable-dnssec、show-zone等实测均可用(本文沿用实测的旧式调用给出回显,新式命名空间等价)。
5.2 区域生命周期
创建区域:
pdnsutil create-zone example.com ns1.example.com
实测回显:
Creating empty zone 'example.com'
Also adding one NS record
If the authoritative server is running, be sure to refresh its zone cache
with 'pdns_control rediscover'
全量清单与校验:
pdnsutil zone list-all
pdnsutil zone check example.com
pdnsutil zone check-all
实测回显:
example.com.
Checked 6 records of 'example.com.', 0 errors, 0 warnings. Validated: 5. Signed: 6. 0 seconds.
Checked 1 zones, 0 errors, 0 warnings.
💡 说明:
check会顺带完成 rectify(维护 NSEC 附加链),"Validated: 5" 是 RRSIG 覆盖的记录集数。删除区域用pdnsutil zone delete <区域>,成功时无输出,用zone list-all确认(本机实测删除test.internal后清单只剩example.com.)。
5.3 记录操作(rrset / add-record)
加记录(新式 rrset add 与旧式 add-record 等价,TTL 缺省 3600):
pdnsutil add-record example.com www.example.com A 192.0.2.10
pdnsutil add-record example.com ns1.example.com A 192.0.2.53
pdnsutil add-record example.com example.com MX "10 mail.example.com"
pdnsutil add-record example.com example.com TXT "\"v=spf1 mx -all\""
实测回显(逐条,含 TXT 的引号转义形式):
New rrset:
www.example.com. 3600 IN A 192.0.2.10
New rrset:
ns1.example.com. 3600 IN A 192.0.2.53
New rrset:
example.com. 3600 IN MX 10 mail.example.com.
New rrset:
example.com. 3600 IN TXT "v=spf1 mx -all"
⚠️ 实测陷阱:记录名必须写全限定名。写相对名会失败——
pdnsutil add-record example.com www A 192.0.2.10实测报Error: Name "www." to add is not part of zone "example.com.".,改写www.example.com即成功。
替换与删除(rrset replace 原子替换同名同类型的整组记录):
pdnsutil rrset replace test.internal www.test.internal A 3600 192.0.2.100
pdnsutil rrset delete test.internal www.test.internal A
实测回显:
Replaced recordset www.test.internal IN A: 1 to 1 records
(rrset delete 成功时无输出。)查看区域全部记录:
pdnsutil list-zone example.com
实测回显:
Zone IN example.com
example.com. IN NS ns1.example.com.
example.com. IN MX 10 mail.example.com.
example.com. IN SOA a.misconfigured.dns.server.invalid. hostmaster.example.com. 0 10800 3600 604800 3600
example.com. IN TXT "v=spf1 mx -all"
ns1.example.com. IN A 192.0.2.53
www.example.com. IN A 192.0.2.10
用 pdnsutil 改完数据库后,运行中的服务需刷新缓存并逐类型解析验证:
pdns_control rediscover
dig @127.0.0.2 www.example.com A +noall +answer
dig @127.0.0.2 example.com MX +noall +answer
dig @127.0.0.2 example.com TXT +noall +answer
实测回显:
Ok
www.example.com. 3600 IN A 192.0.2.10
example.com. 3600 IN MX 10 mail.example.com.
example.com. 3600 IN TXT "v=spf1 mx -all"
5.4 DNSSEC 管理
一键签名(默认按 default-ksk-algorithm=ecdsa256 生成 CSK):
pdnsutil zone secure example.com
实测回显(节选):
Zone example.com. now signed
Add a DS record to the parent zone (or wherever the delegation is) using the
DS record(s) in:
pdnsutil zone export-ds example.com
密钥与信任链信息:
pdnsutil zone show example.com
实测回显(节选):
This zone has 1 key: (CSK) ecdsa256 (ECDSAP256SHA256) KSK+ZSK active-id=1 (all keys similar)
Zone is not actively configured to be presigned
Zone is not presigned
CSK DNSKEY = example.com. IN DNSKEY 257 3 13 0pE8... ; ( ECDSAP256SHA256 )
DS = example.com. IN DS 19008 13 1 1f5a... ; ( SHA1 digest )
DS = example.com. IN DS 19008 13 2 36cf... ; ( SHA256 digest )
DS = example.com. IN DS 19008 13 4 0620... ; ( SHA384 digest )
pdnsutil zone list-keys example.com
实测回显:
Zone Type Size Algorithm ID Location Flags Status
example.com. CSK ECDSAP256SHA256 1 CryptoEngine 257 active
导出 DS 与序列号递增:
pdnsutil zone export-ds example.com
pdnsutil zone increase-serial example.com
实测回显:
example.com IN DS 19008 13 1 1f5a... ; ( SHA1 digest )
example.com IN DS 19008 13 2 36cf... ; ( SHA256 digest )
example.com IN DS 19008 13 4 0620... ; ( SHA384 digest )
SOA serial for example.com seems to be 0
Increasing it to 1
解析层验证签名(RRSIG/DNSKEY 齐备,ad 缺省因本机非信任锚,属正常):
dig @127.0.0.2 example.com DNSKEY +noall +answer
dig @127.0.0.2 www.example.com A +dnssec +noall +answer
实测回显:
example.com. 3600 IN DNSKEY 257 3 13 0pE8... ; ( CSK )
www.example.com. 3600 IN A 192.0.2.10
www.example.com. 3600 IN RRSIG A 13 3 3600 20261116164142 20261020161042 19008 example.com. 1YcD...
其他密钥运维命令:zone add-zone-key/zone remove-zone-key(分 KSK/ZSK 双钥体系)、zone set-nsec3/unset-nsec3(NSEC↔NSEC3 切换,参数如 iterations=0 salt-length=8)、zone rectify、disable-dnssec。
5.5 TSIG、密码哈希与元数据
pdnsutil tsigkey generate demo-key hmac-sha256
pdnsutil tsigkey list
实测回显(密钥内容截断展示):
Created key with algorithm hmac-sha256
demo-key hmac-sha256 9mQ4...
demo-key hmac-sha256 9mQ4...
echo q1w2e3r4 | pdnsutil hash-password
实测回显(scrypt 哈希,用于 webserver-password 的哈希形态):
$scrypt$ln=16384,r=8,p=1$salt$hash
元数据查看(区域级配置如 SOA-EDIT-API 存放在 domainmetadata 表):
pdnsutil metadata get example.com
六、zone2sql 与 zone2json
准备一个标准 BIND 格式区域文件:
cat > /tmp/test.example.zone <<'EOF'
$ORIGIN test.example.
$TTL 3600
@ IN SOA ns1.test.example. hostmaster.test.example. 2026010101 10800 3600 604800 3600
@ IN NS ns1.test.example.
ns1 IN A 192.0.2.53
www IN A 192.0.2.20
EOF
zone2sql 按 --gmysql/--gpgsql/--gsqlite 等选项输出对应方言的 SQL 语句:
zone2sql --gsqlite --zone=/tmp/test.example.zone | head -6
实测回显:
delete from records;
insert into domains (id,name,type) values (1,'test.example.','NATIVE');
insert into records (domain_id, name, content, type, ttl, disabled, ordername, auth) values (1,'test.example.','ns1.test.example. hostmaster.test.example. 2026010101 10800 3600 604800 3600','SOA',3600,0,NULL,1);
insert into records (domain_id, name, content, type, ttl, disabled, ordername, auth) values (1,'test.example.','ns1.test.example.','NS',3600,0,NULL,1);
insert into records (domain_id, name, content, type, ttl, disabled, ordername, auth) values (1,'ns1.test.example.','192.0.2.53','A',3600,0,NULL,1);
insert into records (domain_id, name, content, type, ttl, disabled, ordername, auth) values (1,'www.test.example.','192.0.2.20','A',3600,0,NULL,1);
zone2json 输出 JSON 结构(便于外部系统消费):
zone2json --zone=/tmp/test.example.zone
实测回显:
[{"name":"test.example.","type":"SOA","ttl":3600,"content":"ns1.test.example. hostmaster.test.example. 2026010101 10800 3600 604800 3600"},{"name":"test.example.","type":"NS","ttl":3600,"content":"ns1.test.example."},{"name":"ns1.test.example.","type":"A","ttl":3600,"content":"192.0.2.53"},{"name":"www.test.example.","type":"A","ttl":3600,"content":"192.0.2.20"}]
七、pdns_server 与 systemd
7.1 pdns_server 命令行诊断
pdns_server --version 2>/dev/null | head -3
实测回显:
PowerDNS Authoritative Server 5.1.4 (C) PowerDNS.COM BV
Using 64-bits mode. Built using gcc 11.4.0 on Wed Aug 5 13:11:38 UTC 2026 by root@localhost.
PowerDNS comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it according to the terms of the GPL version 2.
配置校验与全量打印(都不需要服务在运行):
sudo pdns_server --config=check # 语法校验,无输出即通过
sudo pdns_server --config=print | wc -l # 打印全部 170 个参数
实测回显:
1177
完整参数体系与默认值分析见《PowerDNS 5.1.4 配置参数详解》。
7.2 systemd 服务管理
sudo systemctl start|stop|restart|status pdns
sudo systemctl enable pdns # 开机自启(安装时已默认启用)
journalctl -u pdns -n 50 --no-pager # 服务日志
systemctl status pdns 实测回显(节选):
● pdns.service - PowerDNS Authoritative Server
Loaded: loaded (/lib/systemd/system/pdns.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2026-10-20 16:37:05 CST; 2min ago
Main PID: 1396584 (pdns_server)
单元关键定义(systemctl cat pdns.service 节选):
ExecStart=/usr/sbin/pdns_server --guardian=no --daemon=no --disable-syslog --log-timestamp=no --write-pid=no
User=pdns
Group=pdns
Type=notify
RuntimeDirectory=pdns
八、注意事项
- pdns_control 与 pdnsutil 的作用对象不同:前者操作运行中的服务,后者直接读写数据库;pdnsutil 改库后必须
pdns_control rediscover,否则运行中的服务看不到变更。 - guardian 模式差异:发行包 systemd 单元固定
--guardian=no,因此ping/cycle/status三个命令不可用(实测Unknown command),存活探测用rping,进程管理交给 systemd。 - 记录名一律写全限定名:
add-record传相对名(如www)实测报not part of zone,写www.example.com成功。 - 静默成功约定:
pdnsutil zone delete、rrset delete、tsigkey generate部分操作成功时无输出或仅一行回显,操作后用zone list-all/list-zone确认状态。 - 验证回显以本机为准:man 页与实际行为的差异(如
ping在 4.5.3 man 页存在但实测不可用、5.1.4 新增flush等)在版本间常见,升级后先跑一遍 4.1 节命令总表摸底。 - 缓存影响:改记录后若查询仍返回旧值,是 PacketCache 在 TTL(默认
cache-ttl=20秒)内正常命中;急用pdns_control purge example.com.立即失效。
九、常见问题
Q1:pdns_control 报 Fatal error: Unable to connect to remote '/var/run/pdns/pdns.controlsocket'?
服务没在运行(RuntimeDirectory=pdns 随服务退出回收)。systemctl start pdns 后重试;确认状态用 systemctl is-active pdns。
Q2:pdns_control ping 明明写在 man 页里,为什么 Unknown command?
man 页同时写了 ping, rping:ping 仅 guardian 模式、rping 仅非 guardian 模式。发行包以 --guardian=no 运行,用 rping(实测返回 PONG)。
Q3:pdnsutil 命令改了数据库,dig 查询却还是旧值?
两步检查:先 pdns_control rediscover 刷新区域缓存;再 pdns_control purge 清应答缓存(默认缓存 20 秒,正常等待亦可)。
Q4:add-record 报 Name "www." to add is not part of zone?
用全限定名:pdnsutil add-record example.com www.example.com A 192.0.2.10(实测成功回显见 5.3 节)。
十、参考链接
- pdns_control 官方文档:https://doc.powerdns.com/authoritative/manpages/pdns_control.1.html
- pdnsutil 官方文档:https://doc.powerdns.com/authoritative/manpages/pdnsutil.1.html
- zone2sql 官方文档:https://doc.powerdns.com/authoritative/manpages/zone2sql.1.html
- HTTP API(CLI 之外的编程接口):https://doc.powerdns.com/authoritative/http-api/README.html
- 同系列文档:《Ubuntu 22.04 安装 PowerDNS 5.1.4 指南》(安装与卸载实录)、《PowerDNS 5.1.4 配置参数详解》(参数逐项解读)、《PowerDNS 5.1.4 介绍与选型指南》(架构与同类对比)