2026-08-03 12:26:42 +08:00
|
|
|
# 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) |
|
2026-08-12 16:35:40 +08:00
|
|
|
|
|
|
|
|
> Legacy PDA UI container `powerdns-admin` (orphan, Exited) was removed 2026-08-12 (W1N-59).
|
2026-08-03 12:26:42 +08:00
|
|
|
|
|
|
|
|
### 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).
|
|
|
|
|
|
2026-08-12 16:35:40 +08:00
|
|
|
## RustDesk Server
|
2026-08-03 12:26:42 +08:00
|
|
|
|
2026-08-12 16:35:40 +08:00
|
|
|
**Status: operational** (hbbs + hbbr Up; image pinned `1.1.14`; relay address fixed 2026-08-12, W1N-59).
|
|
|
|
|
|
|
|
|
|
| Item | Value |
|
|
|
|
|
|------|--------|
|
|
|
|
|
| Install path | `/opt/rustdesk` |
|
|
|
|
|
| Compose | `/opt/rustdesk/compose.yml` |
|
|
|
|
|
| Containers | `hbbs` (rendezvous), `hbbr` (relay) |
|
|
|
|
|
| Image | `rustdesk/rustdesk-server:1.1.14` (pinned) |
|
|
|
|
|
| Relay (hbbr) | `hk2.chans.xyz:21117` — advertised to clients via `hbbs -r` |
|
|
|
|
|
| Rendezvous (hbbs) | `21115/tcp` (NAT test), `21116/tcp+udp`, `21118/tcp` (ws) |
|
|
|
|
|
| Relay (hbbr) | `21117/tcp`, `21119/tcp` (ws) |
|
|
|
|
|
| Public IP | `154.36.174.161` |
|
|
|
|
|
| Health | [runbooks/rustdesk-health.md](../runbooks/rustdesk-health.md) |
|
|
|
|
|
|
|
|
|
|
**Note:** the relay hostname in `hbbs -r` must resolve to this host's public IP
|
|
|
|
|
(`154.36.174.161`). `hk2.chans.xyz` resolves correctly; the previously used
|
|
|
|
|
`hk2.wsvc.info` had **no DNS record** and broke relay connectivity for clients
|
|
|
|
|
(fixed 2026-08-12, W1N-59).
|
|
|
|
|
|
|
|
|
|
## Other software on this host (confirmed 2026-08-12)
|
|
|
|
|
|
|
|
|
|
Verified live via `docker ps` / port scan. Each runs as a separate compose
|
|
|
|
|
project under `/opt/<name>` and is fronted by Traefik where noted.
|
|
|
|
|
|
|
|
|
|
| Service | Path | Container(s) | Image | Ports / notes |
|
|
|
|
|
|---------|------|--------------|-------|---------------|
|
|
|
|
|
| Traefik | `/opt/traefik` | `traefik` | `traefik:v3.6.2` | `80`, `443` (TLS entry), `8080` (dashboard) |
|
|
|
|
|
| AdGuard Home | `/opt/adguard` | `adguardhome` | `adguard/adguardhome:latest` | DoH `5443`, DoT `853` (bridge; no LAN `:53`) |
|
|
|
|
|
| Remark42 | `/opt/remark42` | `remark42` | `ghcr.io/umputun/remark42:latest` | no host ports; via Traefik (in-container `8080`) |
|
|
|
|
|
|
|
|
|
|
### Traefik dashboard auth
|
|
|
|
|
|
|
|
|
|
| Item | Value |
|
|
|
|
|
|------|-------|
|
|
|
|
|
| Dashboard URL | `https://npm.chans.xyz` (Traefik `api@internal` router), also host `:8080` |
|
|
|
|
|
| Auth | HTTP Basic via Traefik `basicauth` middleware (label `dashboard-auth`) |
|
|
|
|
|
| User | `windy` — stored as a **bcrypt** hash (plaintext never stored) |
|
|
|
|
|
| Hash generator | `/opt/traefik/generate-dashboard-auth.sh` (bcrypt; auto `$`→`$$` compose escaping) |
|
|
|
|
|
| Config | `/opt/traefik/compose.yml` (label `traefik.http.middlewares.dashboard-auth.basicauth.users`) |
|
|
|
|
|
|
|
|
|
|
**Password rotated 2026-08-12** from apr1/MD5 to bcrypt via the generator script; the
|
|
|
|
|
plaintext lives only in the operator's password manager, never in this repo.
|
|
|
|
|
To rotate again: `cd /opt/traefik && ./generate-dashboard-auth.sh windy`, paste the
|
|
|
|
|
printed label into `compose.yml`, then `docker compose up -d --force-recreate traefik`.
|
|
|
|
|
|
|
|
|
|
`/opt/nginx-manager` was a leftover (compose + `data/` + `letsencrypt/`, no running
|
|
|
|
|
container) and was **removed 2026-08-12**; pre-deletion backup:
|
|
|
|
|
`/opt/backups/nginx-manager-20260812.tar.gz`.
|
|
|
|
|
|
|
|
|
|
Health coverage: these auxiliary services are checked by the `hk2aux`
|
|
|
|
|
health-check profile (`ansible/roles/healthcheck`). Run:
|
|
|
|
|
`cd ansible && ansible-playbook playbooks/health-report.yml --limit powerdns`.
|
2026-08-03 12:26:42 +08:00
|
|
|
|
|
|
|
|
## Ops / runbooks
|
|
|
|
|
|
|
|
|
|
- [pdns-health](../runbooks/pdns-health.md)
|
|
|
|
|
- [pdns-upstream docs](../docs/pdns-upstream.md)
|
|
|
|
|
|
|
|
|
|
```bash
|
2026-08-03 16:01:35 +08:00
|
|
|
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'
|
2026-08-03 12:26:42 +08:00
|
|
|
```
|
|
|
|
|
|
|
|
|
|
```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)
|