145 lines
5.5 KiB
Markdown
145 lines
5.5 KiB
Markdown
# hk2.chans.xyz
|
|
|
|
| Item | Value |
|
|
|------|--------|
|
|
| Role | PowerDNS Authoritative (ns1) + Poweradmin / Traefik |
|
|
| SSH | `ssh -4 windy@hk2.chans.xyz` (prefer IPv4 from WSL) |
|
|
| IPv4 | `154.36.174.161` |
|
|
| Hostname (OS) | `C20210714091792` (Debian 13 trixie) |
|
|
| Also DNS | `ns1.wsvc.info` → this host |
|
|
| Secondary NS | `ns2.wsvc.info` → `202.91.35.141` (`us1.wsvc.info`, PowerDNS Auth **5.0.5**) |
|
|
| Install path | `/opt/pdns` |
|
|
| Compose | `/opt/pdns/compose.yml` |
|
|
| Env file | `/opt/pdns/.env` (secrets — **never commit**) |
|
|
| TZ | `Asia/Shanghai` |
|
|
|
|
Upstream docs / config checklist: [docs/pdns-upstream.md](../docs/pdns-upstream.md)
|
|
|
|
## PowerDNS Authoritative
|
|
|
|
**Status: operational** (auth + db healthy, API **5.0.6**, DNS on :53 — last config audit 2026-08-01 21:40 CST).
|
|
|
|
| Item | Value |
|
|
|------|--------|
|
|
| Image | `powerdns/pdns-auth-50:5.0.6` (pinned) |
|
|
| Container | `pdns-auth` |
|
|
| Config | `/opt/pdns/auth/pdns.conf` + `auth/templates.d/secrets.j2` → `pdns.d/secrets.conf` |
|
|
| Backend | PostgreSQL 16 (`launch=gpgsql`, DB name `pdns`) |
|
|
| DNS ports | host `53/tcp` + `53/udp` |
|
|
| API | host `127.0.0.1:8081` only; `webserver-allow-from` private ranges |
|
|
| Mode | `primary=yes`; `also-notify` / AXFR ACL → `202.91.35.141`; `only-notify=` empty |
|
|
| DNSSEC | `gpgsql-dnssec=yes`; CSK ECDSAP256SHA256 |
|
|
| SOA-EDIT | `default-soa-edit(-signed)=INCEPTION-INCREMENT` |
|
|
| Poweradmin | `PDNS_VERSION=50`; Traefik Host(`pdns.wsvc.info`) |
|
|
| Advisories | 2026-06 + 2026-07 cleared by 5.0.6 |
|
|
|
|
### Zones (authoritative)
|
|
|
|
| Zone | Kind | DNSSEC | Zone metadata |
|
|
|------|------|--------|---------------|
|
|
| `windy.me` | Master | yes | `ALLOW-AXFR-FROM` + `TSIG-ALLOW-AXFR=mykey.` |
|
|
| `wsvc.info` | Master | yes | same |
|
|
| `chans.xyz` | Master | yes | same |
|
|
|
|
NS set: `ns1.wsvc.info` / `ns2.wsvc.info`. Dig SOA may differ from backend serial (SOA-EDIT) — expected.
|
|
|
|
### Intended auth config (sanitized)
|
|
|
|
See full shape in [docs/pdns-upstream.md](../docs/pdns-upstream.md). Live secrets only in `.env` / generated drop-in on the server.
|
|
|
|
### Stack
|
|
|
|
| Container | Service | Status | Image |
|
|
|-----------|---------|--------|-------|
|
|
| `pdns-auth` | auth | Up (healthy) | `powerdns/pdns-auth-50:5.0.6` |
|
|
| `pdns-db` | db | Up (healthy) | `postgres:16` |
|
|
| `poweradmin` | poweradmin | Up (healthy) | `poweradmin/poweradmin:stable` |
|
|
| `pdns_pgweb` | pgweb | Up | `sosedoff/pgweb:0.16.2` |
|
|
| `pdns-backup` | backup | Up | `postgres:16` (scheduler) |
|
|
| `powerdns-admin` | *(orphan)* | Exited | legacy PDA UI — not in active compose |
|
|
|
|
### Network model
|
|
|
|
| Network | Purpose |
|
|
|---------|---------|
|
|
| `backend` | Internal (`internal: true`) — DB + service API |
|
|
| `edge` | Host-published DNS `:53` and loopback API `:8081` |
|
|
| `frontend` (`traefik`) | External Traefik network for web UIs |
|
|
|
|
### Public / management URLs
|
|
|
|
| URL | Backend | Notes |
|
|
|-----|---------|-------|
|
|
| https://pdns.wsvc.info | `poweradmin` via Traefik | DNS admin UI |
|
|
| https://pgweb.wsvc.info | `pgweb` via Traefik | DB browser (HTTP basic) |
|
|
| DNS `ns1.wsvc.info:53` | `pdns-auth` | Public authoritative |
|
|
|
|
## Config audit (vs official docs)
|
|
|
|
**Functional primary/secondary config: OK** after 5.0.6 upgrade + `only-notify=` / `domains.master` cleanup.
|
|
|
|
| Item | Verdict |
|
|
|------|---------|
|
|
| `primary` + MASTER zones + gpgsql DNSSEC | OK |
|
|
| `also-notify` + empty `only-notify` | OK (docs-recommended pattern) |
|
|
| API bind / host port publish | OK |
|
|
| SOA-EDIT with PowerDNS secondary | OK |
|
|
| API key / DB password hygiene | **Deferred** — weak, plaintext, reused |
|
|
| TSIG `mykey` | **Deferred** — any holder can AXFR (bypasses IP ACL) |
|
|
|
|
## Backup
|
|
|
|
| Item | Value |
|
|
|------|--------|
|
|
| Service | `pdns-backup` |
|
|
| Schedule | `CRON_SCHEDULE=0 3 * * *` (03:00 Asia/Shanghai) |
|
|
| Retention | `RETENTION_DAYS=7`, `MAX_BACKUPS=3` |
|
|
| Output | `/opt/pdns/backup/pdns_*.sql.gz` (+ optional `roles_*.sql`) |
|
|
| Scheduler | `scripts/backup-scheduler.sh` (daily `M H * * *` only) |
|
|
| Manual | `cd /opt/pdns && ./scripts/manual-backup.sh` |
|
|
|
|
**Quirk:** `backend` is internal — backup must not use Alpine + runtime `apk`/`crond`. Uses `postgres:16` + `backup-scheduler.sh` (fixed 2026-08-01).
|
|
|
|
## Other software on this host (stubs)
|
|
|
|
`/opt/traefik`, `/opt/adguard`, `/opt/remark42`, `/opt/rustdesk`, `/opt/nginx-manager`, …
|
|
|
|
## Ops / runbooks
|
|
|
|
- [pdns-health](../runbooks/pdns-health.md)
|
|
- [pdns-upstream docs](../docs/pdns-upstream.md)
|
|
|
|
```bash
|
|
cd ansible
|
|
ansible-playbook playbooks/health-report.yml --limit powerdns
|
|
# after reviewed auth config / secret-template / environment changes:
|
|
ansible-playbook playbooks/compose-reconcile.yml --limit powerdns \
|
|
-e '{"service_reconcile_confirm": true, "service_reconcile_targets": ["auth"]}'
|
|
```
|
|
|
|
Direct SSH remains appropriate for streaming incident logs or running the
|
|
on-server, intentionally imperative manual backup command:
|
|
|
|
```bash
|
|
ssh -4 windy@hk2.chans.xyz 'cd /opt/pdns && ./scripts/manual-backup.sh'
|
|
```
|
|
|
|
```bash
|
|
dig @154.36.174.161 NS windy.me +short
|
|
dig @154.36.174.161 SOA wsvc.info +short
|
|
# compare secondary:
|
|
dig @202.91.35.141 SOA wsvc.info +short
|
|
```
|
|
|
|
On-server docs: `/opt/pdns/README.md`, `CHANGELOG.md`.
|
|
|
|
## Verified
|
|
|
|
Last checked: **2026-08-01 21:40 CST** — operational; docs audit recorded.
|
|
|
|
- Auth **5.0.6** healthy; no Mandatory security banner
|
|
- Zones Master + DNSSEC; SOA in sync with ns2 (served serial)
|
|
- `only-notify=` + `also-notify=202.91.35.141`; MASTER `domains.master` cleared
|
|
- https://pdns.wsvc.info → **302**; https://pgweb.wsvc.info → **401**
|
|
- Hardening backlog: API/DB credential rotation + TSIG rotate (see upstream doc)
|