TP31: LXC 130 caddy-bf1 gebaut, Caddyfile im Repo, Altlasten geloescht

Aufgeraeumt (User-Freigabe): LXC 120/121/128/129/130/131 zerstoert --
alle stopped, onboot=0, alle konfigurativ noch auf totem VLAN1
(10.40.41.116/.117, GW .41.254). pct destroy --purge hat 120 und 128
zugleich aus dem Backup-Job entfernt. 65 von 72 PBS-Snapshots geloescht;
sieben sind PROTECTED und stehen noch -- bewusst nicht ueberschrieben.

Neu nach TP32-Systematik:
- LXC 130 caddy-bf1, VLAN20 tag=20, 10.40.20.40/24, GW/DNS .20.1,
  onboot=1, startup order=10 (Core), Debian 13, 4 GB / 512 MB
- Caddy v2.11.4 mit dns.providers.cloudflare (Custom-Build)
- caddy/Caddyfile im Repo, 17 Sites: 4 oeffentlich (vw/hass/n8n/gitea),
  13 intern inkl. der vier MCP-Endpunkte und drei HTTPS-Backends
- caddy/deploy.sh liest CF_DNS_API_TOKEN aus ~/.secrets und schreibt es
  in die Container-Env -- nie auf stdout, nie in einer Kommandozeile
- 130 in denselben Backup-Job aufgenommen

Caddy laeuft noch NICHT: das eng geschnittene Zone:DNS:Edit-Token fehlt.
Ein Token anzulegen und im Klartext zu handhaben ist nichts, was ich
selbst tue -- der Weg ist ~/.secrets plus deploy.sh.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-25 01:11:08 +02:00
parent c9a413858b
commit a99dd06fdd
3 changed files with 134 additions and 0 deletions

1
.gitignore vendored
View File

@@ -14,3 +14,4 @@ routeros/state-backups/
routeros/ap1-wg-hub.privkey
routeros/tp15-core-cutover-intended.rsc
docs/tp6-marker/.current-run
caddy/caddy.env

100
caddy/Caddyfile Normal file
View File

@@ -0,0 +1,100 @@
# TP31 — Reverse Proxy BF (Caddy), LXC 130 / 10.40.20.40
# SSoT: docs/teilprojekte.md → TP31. Deploy: pct push 130 caddy/Caddyfile /etc/caddy/Caddyfile
#
# Zertifikate ausschliesslich per DNS-01, damit auch rein INTERNE Namen gueltige
# Zertifikate bekommen, ohne dass von aussen irgendetwas erreichbar sein muss.
# Token: /etc/caddy/caddy.env (chmod 600, NICHT im Repo) — eng geschnitten auf
# Zone:DNS:Edit fuer emsenhuber.net. NICHT das account-weite CF_API_TOKEN.
{
email christoph@emsenhuber.com
acme_dns cloudflare {env.CF_DNS_API_TOKEN}
}
# --- Backends mit Selbstsignat: Caddy prueft deren Zertifikat nicht ---------
(selfsigned) {
transport http {
tls_insecure_skip_verify
}
}
# =========================================================================
# OEFFENTLICH (via Cloudflare Tunnel + Access; Clients ohne WARP)
# =========================================================================
vw.emsenhuber.net {
reverse_proxy http://10.40.20.127
}
hass.emsenhuber.net {
reverse_proxy http://10.40.20.105:8123
}
n8n.emsenhuber.net {
reverse_proxy http://10.40.20.167:5678
}
gitea.emsenhuber.net {
reverse_proxy http://10.40.20.157:3000
}
# =========================================================================
# INTERN (Mesh/LAN; Split-Horizon zeigt diese Namen auf 10.40.20.40)
# =========================================================================
nautobot.emsenhuber.net {
reverse_proxy http://10.40.20.30:8080
}
grafana.emsenhuber.net {
reverse_proxy http://10.40.20.109:3000
}
ds-bf.emsenhuber.net {
reverse_proxy http://10.40.20.10:8080
}
ccu.emsenhuber.net {
reverse_proxy http://10.40.20.232
}
iobroker.emsenhuber.net {
reverse_proxy http://10.40.20.107:8081
}
z2m25.emsenhuber.net {
reverse_proxy http://10.40.20.106:8080
}
# --- MCP-Endpunkte: heute spricht ~/.claude.json diese IPs roh --------------
pve-mcp.emsenhuber.net {
reverse_proxy http://10.40.20.173:3000
}
ha-mcp.emsenhuber.net {
reverse_proxy http://10.40.20.105:9583
}
n8n-mcp.emsenhuber.net {
reverse_proxy http://10.40.20.167:3001
}
gitea-mcp.emsenhuber.net {
reverse_proxy http://10.40.20.167:3000
}
# --- HTTPS-Backends (Selbstsignat) -----------------------------------------
pve.emsenhuber.net {
reverse_proxy https://10.40.20.100:8006 {
import selfsigned
}
}
portainer.emsenhuber.net {
reverse_proxy https://10.40.20.126:9443 {
import selfsigned
}
}
pbs.emsenhuber.net {
reverse_proxy https://10.40.20.135:8007 {
import selfsigned
}
}

33
caddy/deploy.sh Executable file
View File

@@ -0,0 +1,33 @@
#!/usr/bin/env bash
# TP31 — Caddyfile + DNS-Token in LXC 130 ausrollen.
#
# Das Token wird aus ~/.secrets/credentials.env gelesen und direkt in die
# Container-Env-Datei geschrieben. Es erscheint dabei NIE auf stdout und nie in
# einer Kommandozeile — dieselbe Regel wie bei `sshpass -e` (s. CLAUDE.md).
set -euo pipefail
PVE=${PVE:-root@10.40.20.100}
CTID=${CTID:-130}
HERE=$(cd "$(dirname "$0")" && pwd)
TOKEN=$(grep -m1 '^CF_DNS_API_TOKEN=' ~/.secrets/credentials.env 2>/dev/null | cut -d= -f2- || true)
if [ -z "${TOKEN}" ]; then
echo "FEHLER: CF_DNS_API_TOKEN fehlt in ~/.secrets/credentials.env" >&2
echo " Anlegen in Cloudflare: My Profile -> API Tokens -> Create Token," >&2
echo " Permission 'Zone : DNS : Edit', Zone Resources auf emsenhuber.net begrenzen." >&2
echo " NICHT das account-weite CF_API_TOKEN wiederverwenden." >&2
exit 1
fi
echo "-> Caddyfile"
scp -q "${HERE}/Caddyfile" "${PVE}:/tmp/.caddyfile.$$"
ssh "${PVE}" "pct push ${CTID} /tmp/.caddyfile.\$\$ /etc/caddy/Caddyfile --perms 644 2>/dev/null || pct push ${CTID} /tmp/.caddyfile.$$ /etc/caddy/Caddyfile --perms 644; rm -f /tmp/.caddyfile.$$"
echo "-> Token (maskiert: Laenge ${#TOKEN})"
printf 'CF_DNS_API_TOKEN=%s\n' "${TOKEN}" | ssh "${PVE}" "cat > /tmp/.cenv.$$ && chmod 600 /tmp/.cenv.$$ && pct push ${CTID} /tmp/.cenv.$$ /etc/caddy/caddy.env --perms 600 && rm -f /tmp/.cenv.$$"
echo "-> validate"
ssh "${PVE}" "pct exec ${CTID} -- sh -c 'set -a; . /etc/caddy/caddy.env; set +a; /usr/local/bin/caddy validate --config /etc/caddy/Caddyfile' 2>&1 | tail -3"
echo "-> reload/start"
ssh "${PVE}" "pct exec ${CTID} -- systemctl reload-or-restart caddy && sleep 3 && pct exec ${CTID} -- systemctl is-active caddy"