Files
my-vault/01_Projects/Infrastructure/Services/PowerDNS Auth/Rebuild-Master-Node.md
T

6.8 KiB
Raw Blame History

🌀 从 Slave 节点恢复 PowerDNS Authoritative 主节点(5.0.0 + PostgreSQL

本文记录如何从 PowerDNS 从节点完整恢复主节点,包括数据库重建、Zone 导入、TSIG 同步与 DNSSEC 校验。
适用于 PowerDNS Authoritative 5.0.0 + PostgreSQL gpgsql backend 环境。


一、系统角色

节点 地址 角色 说明
主节点 154.36.174.161 primary 新建
从节点 202.91.35.141 secondary 当前持有所有 zone
数据库 PostgreSQL 15 backend gpgsql
TSIG mykey (hmac-sha512) 用于 AXFR 验证

二、从 Slave 导出数据

1️⃣ 列出所有 zone

sudo pdnsutil zone list-all

2️⃣ 导出 zone 文件(PowerDNS 5.0 无 dump-zone

sudo pdnsutil zone list windy.me > /var/tmp/windy.me.zone
sudo pdnsutil zone list wsvc.info > /var/tmp/wsvc.info.zone
sudo pdnsutil zone list chans.xyz > /var/tmp/chans.xyz.zone

3️⃣ 导出 TSIG 密钥

sudo pdnsutil tsigkey list

示例:

mykey. hmac-sha512. 4es15ROFVNZh76mqbn7sVu1kodAdULYKp8I/jGAWvmH/uyxeyDwqoBiYYBKPro5M+TRkKYn7ulxZKskfKIBKNg==

三、部署主节点环境

1️⃣ 目录结构

/opt/pdns-primary/
├── docker-compose.yml
├── pdns.conf
└── db-init/
    └── 01-init.sql

2️⃣ docker-compose.yml

version: "3.8"
services:
  pdns-db:
    image: postgres:15
    environment:
      POSTGRES_USER: pdns
      POSTGRES_PASSWORD: windyboy2006
      POSTGRES_DB: pdns
    volumes:
      - ./db-init:/docker-entrypoint-initdb.d
      - pdns-db-data:/var/lib/postgresql/data
    restart: unless-stopped

  auth:
    image: powerdns/pdns-auth-50:latest
    depends_on:
      - pdns-db
    volumes:
      - ./pdns.conf:/etc/powerdns/pdns.conf:ro
      - ./import:/import:ro
    ports:
      - "53:53/tcp"
      - "53:53/udp"
      - "8081:8081"
    restart: unless-stopped

volumes:
  pdns-db-data:

3️⃣ 初始化数据库

db-init/01-init.sql

CREATE USER pdns WITH PASSWORD 'windyboy2006';
CREATE DATABASE pdns OWNER pdns ENCODING 'UTF8';

启动数据库:

docker compose up -d pdns-db
sleep 10

四、主节点配置(pdns.conf

primary=yes
secondary=no
launch=gpgsql
gpgsql-host=pdns-db
gpgsql-port=5432
gpgsql-dbname=pdns
gpgsql-user=pdns
gpgsql-password=windyboy2006
gpgsql-dnssec=yes

local-address=0.0.0.0
local-port=53
setuid=pdns
setgid=pdns
loglevel=4
version-string=anonymous

api=yes
api-key=SuperSecretKey
webserver=yes
webserver-address=0.0.0.0
webserver-port=8081

default-soa-edit=INCEPTION-INCREMENT
default-soa-edit-signed=INCEPTION-INCREMENT
disable-axfr=no

所有字段均为 5.0.0 有效选项,无 default-soa-edit-api


五、导入 Zone 数据

1️⃣ 创建空 zone 并设为 master

docker compose exec auth pdnsutil zone create windy.me
docker compose exec auth pdnsutil zone set-kind windy.me master

docker compose exec auth pdnsutil zone create wsvc.info
docker compose exec auth pdnsutil zone set-kind wsvc.info master

docker compose exec auth pdnsutil zone create chans.xyz
docker compose exec auth pdnsutil zone set-kind chans.xyz master

2️⃣ 导入 zone 文件

docker compose exec auth pdnsutil zone load windy.me /import/windy.me.zone
docker compose exec auth pdnsutil zone load wsvc.info /import/wsvc.info.zone
docker compose exec auth pdnsutil zone load chans.xyz /import/chans.xyz.zone

3️⃣ 如 zone 含有 RRSIG/DNSKEY,设为 presigned

docker compose exec auth pdnsutil zone set-presigned windy.me
docker compose exec auth pdnsutil zone set-presigned wsvc.info
docker compose exec auth pdnsutil zone set-presigned chans.xyz

六、导入 TSIG 密钥并授权从节点

1️⃣ 导入 TSIG key

docker compose exec auth pdnsutil tsigkey import "mykey." hmac-sha512 "4es15ROFVNZh76mqbn7sVu1kodAdULYKp8I/jGAWvmH/uyxeyDwqoBiYYBKPro5M+TRkKYn7ulxZKskfKIBKNg=="

2️⃣ 授权从节点(202.91.35.141

docker compose exec auth pdnsutil metadata set windy.me  TSIG-ALLOW-AXFR "mykey."
docker compose exec auth pdnsutil metadata set windy.me  ALLOW-AXFR-FROM "202.91.35.141"
docker compose exec auth pdnsutil metadata set windy.me  ALSO-NOTIFY "202.91.35.141"

docker compose exec auth pdnsutil metadata set wsvc.info TSIG-ALLOW-AXFR "mykey."
docker compose exec auth pdnsutil metadata set wsvc.info ALLOW-AXFR-FROM "202.91.35.141"
docker compose exec auth pdnsutil metadata set wsvc.info ALSO-NOTIFY "202.91.35.141"

docker compose exec auth pdnsutil metadata set chans.xyz TSIG-ALLOW-AXFR "mykey."
docker compose exec auth pdnsutil metadata set chans.xyz ALLOW-AXFR-FROM "202.91.35.141"
docker compose exec auth pdnsutil metadata set chans.xyz ALSO-NOTIFY "202.91.35.141"

⚠️ 不带 @mykey.,因为已全局指定 TSIG key。


七、在从节点配置新的主节点

sudo pdnsutil zone create-secondary windy.me 154.36.174.161
sudo pdnsutil metadata set windy.me AXFR-MASTER-TSIG "mykey."

sudo pdnsutil zone create-secondary wsvc.info 154.36.174.161
sudo pdnsutil metadata set wsvc.info AXFR-MASTER-TSIG "mykey."

sudo pdnsutil zone create-secondary chans.xyz 154.36.174.161
sudo pdnsutil metadata set chans.xyz AXFR-MASTER-TSIG "mykey."

八、触发 AXFR 同步

主节点发送 NOTIFY

docker compose exec auth pdns_control notify windy.me
docker compose exec auth pdns_control notify wsvc.info
docker compose exec auth pdns_control notify chans.xyz

从节点主动获取

sudo pdns_control retrieve windy.me
sudo pdns_control retrieve wsvc.info
sudo pdns_control retrieve chans.xyz

九、验证结果

检查 zone 状态

docker compose exec auth pdnsutil zone list-all

对比 SOA 序列号

dig @154.36.174.161 soa windy.me +short
dig @202.91.35.141 soa windy.me +short

应相同。

查看日志

主节点:

AXFR-out zone 'windy.me', client '202.91.35.141' transfer started/done

从节点:

AXFR done for 'windy.me'

十、常见错误与修复

日志 原因 修复
Signature with TSIG key failed 双方 TSIG secret 不一致 重新导入一致的 key
Server Not Authoritative / Not Authorized 主节点未授权从节点 执行 metadata set ALLOW-AXFR-FROM
AXFR-out denied: client has no permission 同上 增加 ALLOW-AXFR-FROM
Trying to set unknown setting 'default-soa-edit-api' 配置无效 删除该字段

十一、备份与维护

1️⃣ 数据库备份

docker compose exec pdns-db pg_dump -U pdns pdns > /backup/pdns-$(date +%F).dump

2️⃣ 导出所有 zone 文件

mkdir -p /backup/zones
for z in $(docker compose exec auth pdnsutil zone list-all | tr -d '\r'); do
  docker compose exec auth pdnsutil zone list "$z" > "/backup/zones/$z-$(date +%F).zone"
done