Files
my-vault/01_Projects/Infrastructure/VPS/hk2.chans.xyz.md
T

377 lines
9.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Install
## debian 13
### vps provider debian 10 install
default root:
```
8txlD7djkkKk
```
Good catch 👍 — youre right.
Debian 11 _Bullseye_ moved from the **main mirrors** to the **Debian archive repository** after its LTS phase ended in 2026. That means:
- You **can still upgrade** from Debian 10 → 11 → 12 → 13,
- But for Debian 11 youll need to point your `sources.list` to the **archive.debian.org** service, since the normal `deb.debian.org` no longer carries Bullseye.
---
## 🔧 How to Handle Missing Debian 11 (Bullseye) Repos
When upgrading **Debian 10 → 11**, change your `/etc/apt/sources.list` to use the archive:
```bash
sed -i 's|deb.debian.org|archive.debian.org|g' /etc/apt/sources.list
sed -i 's|security.debian.org|archive.debian.org|g' /etc/apt/sources.list
```
Then explicitly set it to Bullseye:
```
deb http://archive.debian.org/debian bullseye main contrib non-free
deb http://archive.debian.org/debian-security bullseye-security main contrib non-free
```
⚠️ Important: you also need to **disable `Valid-Until` checks** (since archive metadata is old). Add this to `/etc/apt/apt.conf.d/99no-check-valid-until`:
```
Acquire::Check-Valid-Until "false";
```
After that, `apt update` will work again for Debian 11 packages.
---
## 🔄 Recommended Path
- **Debian 10 → Debian 11 (Bullseye)**
using `archive.debian.org`
- **Debian 11 → Debian 12 (Bookworm)**
switch back to `deb.debian.org`
- **Debian 12 → Debian 13 (Trixie)**
upgrade normally from main repos
---
## ⚠️ Alternative Approach (Skip Hop?)
Some admins **reinstall instead of multi-hop upgrades** when theyre more than 2 releases behind.
Its often faster and cleaner to install Debian 13 fresh and migrate configs/data.
---
👉 Do you want me to prepare the **exact `sources.list` entries** for each step (10 → 11, 11 → 12, 12 → 13), so you can just copy-paste them before each upgrade?
## traefik
```compose.yml
services: 10:47:35 [24/1240]
traefik:
image: traefik:v3.4
container_name: traefik
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks: [traefik]
ports:
- "80:80"
- "443:443"
- "8080:8080" # dashboard
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./letsencrypt:/letsencrypt
- ./dynamic:/dynamic:ro
command:
# Entrypoints
- "--entrypoints.web.address=:80"
- "--entrypoints.web.http.redirections.entrypoint.to=websecure"
- "--entrypoints.web.http.redirections.entrypoint.scheme=https"
- "--entrypoints.web.http.redirections.entrypoint.permanent=true"
- "--entrypoints.websecure.address=:443"
- "--entrypoints.websecure.http.tls=true"
# Providers
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.network=traefik"
- "--providers.file.directory=/dynamic"
- "--providers.file.watch=true"
# Let's Encrypt (ACME)
- "--certificatesresolvers.letsencrypt.acme.email=admin@windy.me"
- "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
- "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
# Dashboard
- "--api.dashboard=true"
- "--api.insecure=false"
# Logging
- "--log.level=INFO"
- "--accesslog=true"
# Metrics (optional)
- "--metrics.prometheus=true"
labels:
- "traefik.enable=true"
- "traefik.http.routers.dashboard.rule=Host(`npm.chans.xyz`)"
- "traefik.http.routers.dashboard.entrypoints=websecure"
- "traefik.http.routers.dashboard.service=api@internal"
- "traefik.http.routers.dashboard.tls.certresolver=letsencrypt"
- "traefik.http.routers.dashboard.middlewares=dashboard-auth@docker"
- "traefik.http.middlewares.dashboard-auth.basicauth.users=admin:$$apr1$$wrhTVUaG$$tcchNFj..."
networks:
traefik:
external: true
```
dashboard user and pass
```
Ahku+eRei_chu3ah
```
```
htpasswd -nb windy "Ahku+eRei_chu3ah"
```
```
windy:$apr1$wrhTVUaG$tcchNFj.yyA3OpK8f9XnA.
```
## 一步改成 MASTER
执行以下命令即可统一切换类型:
```
docker compose exec -T db psql -U pdns -d pdns -c "UPDATE domains SET type='MASTER';"
```
执行完,再确认:
```
docker compose exec -T db psql -U pdns -d pdns -c "SELECT id, name, type FROM domains ORDER BY name;"
```
应输出:
```
id | name | type ----+-----------+--------- 7 | chans.xyz | MASTER 9 | windy.me | MASTER 8 | wsvc.info | MASTER (3 rows)
```
---
## ✅ 一、明确两种元数据的作用
|kind|作用|主节点是否需要|
|---|---|---|
|`PRESIGNED`|表示该 zone 的 DNSSEC 已经签好,不需要 PowerDNS 重新签名|✅ 需要保留|
|`AXFR-MASTER-TSIG`|从节点用来验证上游 master(旧主)的 TSIG 密钥|❌ 主节点不需要|
---
## 🧹 二、删除无用的 `AXFR-MASTER-TSIG` 记录
执行:
```bash
docker compose exec -T db psql -U pdns -d pdns -c "DELETE FROM domainmetadata WHERE kind='AXFR-MASTER-TSIG';"
```
验证删除结果:
```bash
docker compose exec -T db psql -U pdns -d pdns -c "SELECT domain_id, kind, content FROM domainmetadata;"
```
应该只剩:
```
domain_id | kind | content
------------+------------+---------
7 | PRESIGNED | 1
8 | PRESIGNED | 1
9 | PRESIGNED | 1
(3 rows)
```
---
## 🧩 三、保留 `PRESIGNED`(不要删)
这三条 `PRESIGNED` 的存在说明你的 zone 已经是“预签名区”,
也就是在数据库里已经有 DNSKEY、RRSIG、NSEC/NSEC3 等签名记录,
PowerDNS 不会去重新签名,非常正确 ✅
---
## 🧰 四、确保 `supermasters` 已清空(如果还没执行)
```bash
docker compose exec -T db psql -U pdns -d pdns -c "TRUNCATE TABLE supermasters;"
```
---
## 🚀 五、重启 PDNS 并验证主节点状态
```bash
docker compose exec auth pdnsutil list-all-zones
docker compose exec auth pdnsutil check-all-zones
```
预期输出:
```
Zone "chans.xyz." (MASTER)
Zone "windy.me." (MASTER)
Zone "wsvc.info." (MASTER)
All zones OK
```
---
## ✅ 六、总结(当前应保留状态)
|表|应保留内容|已处理状态|
|---|---|---|
|domains|type=MASTER|✅|
|domainmetadata|仅 `PRESIGNED`|🧹 已清理|
|supermasters|空表|✅|
|records / cryptokeys / tsigkeys|原样保留|✅|
---
如果你愿意,我可以帮你生成一个命令脚本,一次性完成:
- 把所有域设为 MASTER
- 删除 AXFR/MASTER 相关 metadata
- 清空 supermasters
- 验证 zone 状态
你只需执行一条命令即可让任何副节点快照变主节点。是否要我生成?
```
docker compose exec auth pdnsutil metadata set wsvc.info ALLOW-AXFR-FROM "202.91.35.141"
docker compose exec auth pdnsutil metadata set windy.me ALLOW-AXFR-FROM "202.91.35.141"
docker compose exec auth pdnsutil metadata set chans.xyz ALLOW-AXFR-FROM "202.91.35.141"
docker compose exec auth pdnsutil metadata set wsvc.info TSIG-ALLOW-AXFR "mykey."
Set 'wsvc.info' meta TSIG-ALLOW-AXFR = mykey.
docker compose exec auth pdnsutil metadata set windy.me TSIG-ALLOW-AXFR "mykey."
Set 'windy.me' meta TSIG-ALLOW-AXFR = mykey.
docker compose exec auth pdnsutil metadata set chans.xyz TSIG-ALLOW-AXFR "mykey."
Set 'chans.xyz' meta TSIG-ALLOW-AXFR = mykey.
docker compose exec auth pdns_control notify windy.me
docker compose exec auth pdns_control notify chans.xyz
docker compose exec auth pdns_control notify wsvc.info
```
db-init/01-init.sh
```bash
#!/bin/bash
set -e
echo "🔧 Creating PowerDNS role and databases..."
psql -v ON_ERROR_STOP=1 --username "$PGUSER" <<-'EOSQL'
DO $$
BEGIN
IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = 'pdns') THEN
CREATE USER pdns WITH PASSWORD 'windyboy';
END IF;
END
$$;
EOSQL
for dbname in pdns pdnsadmin; do
if ! psql -tAc "SELECT 1 FROM pg_database WHERE datname='${dbname}'" | grep -q 1; then
echo "🆕 Creating database ${dbname} owned by pdns"
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" -c "CREATE DATABASE ${dbname} OWNER pdns;"
else
echo "✅ Database ${dbname} already exists"
fi
done
echo "✅ Initialization finished."
```
```
for z in windy.me chans.xyz wsvc.info; do
docker compose exec auth pdnsutil zone unset-presigned $z
docker compose exec auth pdnsutil zone secure $z
docker compose exec auth pdnsutil zone rectify $z
done
```
```
docker compose exec auth pdnsutil zone list-all | while read z; do
docker compose exec auth pdnsutil zone list "$z" > "auth/export/$z.zone"
done
```
```
labels:
- "traefik.enable=true"
- "traefik.http.routers.pgweb.rule=Host(`pgweb.wsvc.info`)"
- "traefik.http.routers.pgweb.entrypoints=websecure"
- "traefik.http.routers.pgweb.tls.certresolver=letsencrypt"
- "traefik.http.services.pgweb.loadbalancer.server.port=8081"
```
## AdGuard Home
```bash
htpasswd -B -C 10 -n -b zhiqiang 6kjmnGwseQ3jlsW1
```
```
zhiqiang:$2y$10$IMskdbhx33L.L1TVptYad.4AhV4eQUy121/UtzwjXTR/Qa6eUUpHa
```