PowerDNS 5.1.4 常用 CLI 命令与工具详解

PowerDNS Authoritative 5.1.4 全套命令行实测:pdns_control 状态统计与缓存管理、pdnsutil 区域/DNSSEC/TSIG 管理、zone2sql 迁移、guardian 模式命令差异与全限定名等实测陷阱。

PowerDNSDNS 服务2026/10/20

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建区删区、增改查记录、签名与密钥管理
zone2sqlBIND 格式区域文件转 SQL 语句(gmysql/gpgsql/gsqlite 等)从 BIND 迁移数据到 SQL 后端
zone2json区域文件转 JSON数据迁移或外部系统集成
pdns_server服务本体;命令行模式用于版本/配置诊断版本查询、配置校验、全量配置打印
pdns.service / pdns@.servicesystemd 单元启停、自启、日志

重要差异: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 flushOk清空全部查询/包缓存(5.1.4 新增名,等价旧 purge)
pdns_control purge13按记录名精确失效缓存(无参则清全量,回显为失效条数)
pdns_control reloadOk重载后端模块与配置
pdns_control rediscoverOk重新发现区域(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

八、注意事项

  1. pdns_control 与 pdnsutil 的作用对象不同:前者操作运行中的服务,后者直接读写数据库;pdnsutil 改库后必须 pdns_control rediscover,否则运行中的服务看不到变更。
  2. guardian 模式差异:发行包 systemd 单元固定 --guardian=no,因此 ping/cycle/status 三个命令不可用(实测 Unknown command),存活探测用 rping,进程管理交给 systemd。
  3. 记录名一律写全限定名:add-record 传相对名(如 www)实测报 not part of zone,写 www.example.com 成功。
  4. 静默成功约定:pdnsutil zone delete、rrset delete、tsigkey generate 部分操作成功时无输出或仅一行回显,操作后用 zone list-all / list-zone 确认状态。
  5. 验证回显以本机为准:man 页与实际行为的差异(如 ping 在 4.5.3 man 页存在但实测不可用、5.1.4 新增 flush 等)在版本间常见,升级后先跑一遍 4.1 节命令总表摸底。
  6. 缓存影响:改记录后若查询仍返回旧值,是 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 节)。

十、参考链接