306 lines
6.8 KiB
Markdown
306 lines
6.8 KiB
Markdown
|
||||
|
|
# 🌀 从 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
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
sudo pdnsutil zone list-all
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2️⃣ 导出 zone 文件(PowerDNS 5.0 无 dump-zone)
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
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 密钥
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
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
|
|||
|
|
|
|||
|
|
```yaml
|
|||
|
|
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`:
|
|||
|
|
|
|||
|
|
```sql
|
|||
|
|
CREATE USER pdns WITH PASSWORD 'windyboy2006';
|
|||
|
|
CREATE DATABASE pdns OWNER pdns ENCODING 'UTF8';
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
启动数据库:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
docker compose up -d pdns-db
|
|||
|
|
sleep 10
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 四、主节点配置(pdns.conf)
|
|||
|
|
|
|||
|
|
```ini
|
|||
|
|
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
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
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 文件
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
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
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
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
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
docker compose exec auth pdnsutil tsigkey import "mykey." hmac-sha512 "4es15ROFVNZh76mqbn7sVu1kodAdULYKp8I/jGAWvmH/uyxeyDwqoBiYYBKPro5M+TRkKYn7ulxZKskfKIBKNg=="
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2️⃣ 授权从节点(202.91.35.141)
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
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。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 七、在从节点配置新的主节点
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
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
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
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
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 从节点主动获取
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
sudo pdns_control retrieve windy.me
|
|||
|
|
sudo pdns_control retrieve wsvc.info
|
|||
|
|
sudo pdns_control retrieve chans.xyz
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 九、验证结果
|
|||
|
|
|
|||
|
|
### 检查 zone 状态
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
docker compose exec auth pdnsutil zone list-all
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 对比 SOA 序列号
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
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️⃣ 数据库备份
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
docker compose exec pdns-db pg_dump -U pdns pdns > /backup/pdns-$(date +%F).dump
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2️⃣ 导出所有 zone 文件
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
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
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|