From eb3ecbe682f7b561d9692f7d93b44adcbbbddea0 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 28 Jun 2026 16:09:05 +0200 Subject: [PATCH] =?UTF-8?q?docu:=20Step-A-NAT=20pr=C3=A4zisiert,=20watchto?= =?UTF-8?q?wer-Fix=20+=20mailcow-Update-Status?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - opnsense-step-a-nat.md: genaue GUI-Schritte (warum SNAT auf 10.1.1.22 nötig, Aliase, Outbound-NAT, Firewall, Test) - horus/README.md: watchtower-Crashloop behoben (DOCKER_API_VERSION=1.40), mailcow ohne Auto-Update dokumentiert Co-Authored-By: Claude Opus 4.8 --- horus/README.md | 9 +- .../opnsense-step-a-nat.md | 91 +++++++------------ 2 files changed, 39 insertions(+), 61 deletions(-) diff --git a/horus/README.md b/horus/README.md index 25b88a1..b953577 100644 --- a/horus/README.md +++ b/horus/README.md @@ -49,6 +49,11 @@ Web-Apps liegen i.d.R. hinter **nginx-proxy-manager** (Ports 80/443). | `wg-quick@wg0.service` | WireGuard-Hub | | `chrony`, `uptimed`, `docker`, `containerd` | Standard | -## Bekannte Probleme +## Updates / Wartung -- ⚠️ **`infrastructure-watchtower-1` crash-loopt** (`Restarting`). Log: *„client version 1.25 is too old. Minimum supported API version is 1.40"* — watchtowers Docker-API-Client ist zu alt für den Docker-Daemon. **Auto-Updates der Container laufen dadurch nicht.** Fix: watchtower-Image aktualisieren (`docker compose pull && up -d` in `/opt/infrastructure`) oder entfernen. +- **watchtower** (`/opt/infrastructure`): aktualisiert per `WATCHTOWER_LABEL_ENABLE=true` **nur** Container mit Label `com.centurylinklabs.watchtower.enable=true` (aktuell faktisch nur sich selbst). mailcow & Stacks sind bewusst ausgenommen. +- **mailcow**: hat **keine** Auto-Update-Automatik (kein cron/Timer). Updates **manuell/kontrolliert** via `cd /opt/mailcow && ./update.sh` (Multi-Container-Stack mit Migrationen — watchtower darf das nicht, würde nur Images blind tauschen). + +## Bekannte Probleme / Historie + +- ✅ **2026-06-28: watchtower crash-loop behoben** — `containrrr/watchtower:latest` pinnt intern Docker-API `1.25` (Daemon verlangt min `1.40`). Fix: `DOCKER_API_VERSION=1.40` in der watchtower-`environment` (in `/opt/infrastructure/docker-compose.yml`). Läuft seitdem sauber als „Watchtower 1.7.1". diff --git a/shared/horus-opnsense-wireguard/opnsense-step-a-nat.md b/shared/horus-opnsense-wireguard/opnsense-step-a-nat.md index 93f5d0e..86811fc 100644 --- a/shared/horus-opnsense-wireguard/opnsense-step-a-nat.md +++ b/shared/horus-opnsense-wireguard/opnsense-step-a-nat.md @@ -1,33 +1,35 @@ -# Schritt A — VLANs → Horus per NAT (OPNsense) +# Schritt A — LAN/VLAN → Horus per NAT (OPNsense) -**Ziel:** LAN/VLANs erreichen Horus, aber Horus kennt **keine** `192.168.x`-Subnetze (kein Routing zurück ins Heimnetz). +**Ziel:** Interne Hosts (LAN/VLANs) erreichen Horus (`10.1.1.1` + dort gehostete Dienste) über den OPNsense↔Horus-WireGuard-Tunnel. Horus kennt **keine** `192.168.x`-Netze → Rückrouting ins Heimnetz ist nicht möglich (gewollt). | Richtung | Verhalten | |----------|-----------| -| VLAN → Horus | ✅ NAT (Quelle wird `10.1.1.22`) | -| Horus → VLAN | ❌ nicht möglich (Horus kennt VLANs nicht) | +| LAN/VLAN → Horus | ✅ via NAT (Quelle wird `10.1.1.22`) | +| Horus → LAN/VLAN | ❌ nicht möglich (Horus kennt die Netze nicht) | | Horus ↔ `10.100.2.0/24` | ✅ bidirektional (Services, OPNsense-Peer) | -| Horus ↔ `10.2.2.0/24` | ✅ über **VM-Peer** (`10.1.1.5`), nicht OPNsense | +| Horus ↔ `10.2.2.0/24` | ✅ über **VM-101-Peer** (`10.1.1.5`), nicht OPNsense | -**Horus-Seite:** erledigt — OPNsense-Peer `AllowedIPs` = `10.1.1.22/32`, `10.100.2.0/24` only. +## Warum NAT zwingend ist + +Horus' Peer-Eintrag für OPNsense hat `AllowedIPs = 10.1.1.22/32, 10.100.2.0/24`. WireGuard verwirft jedes Antwortpaket an eine Quelle, die **nicht** in diesen AllowedIPs steht. LAN-Traffic (`192.168.x`) muss daher **vor** dem Tunnel auf `10.1.1.22` ge-SNAT-et werden — sonst kommt von Horus nie eine Antwort zurück. --- -## OPNsense — Checkliste +## 0. Voraussetzung -### 1. WireGuard Peer „horus“ (unverändert sinnvoll) +WireGuard-Instanz „horus" als **Interface zuweisen** (*Interfaces → Assignments*), Tunnel-Adresse `10.1.1.22/32`, z. B. Name `horusopnsense`. Nötig für NAT-Interface + Firewallregeln. -Peer **Allowed IPs** (Horus-Netze, outbound vom Router): +## 1. Aliase (*Firewall → Aliases*) -`10.1.1.0/24, 10.1.2.0/24, 10.1.3.0/24, 10.1.4.0/24, 10.8.0.0/24` +- **`HORUS_WG`** (Network): `10.1.1.0/24` *(optional zusätzlich `10.1.2.0/24, 10.1.3.0/24, 10.1.4.0/24, 10.8.0.0/24`)* +- **`LAN_VLANS`** (Network): `192.168.10.0/24, 192.168.20.0/24, 192.168.30.0/24, 192.168.40.0/24, 192.168.50.0/24, 192.168.60.0/24` -Local Instance: Tunnel `10.1.1.22/32`, Keys aus [opnsense-client.conf](opnsense-client.conf). +## 2. Falsche Static Route löschen (*System → Routes → Configuration*) -### 2. Outbound NAT +- **Löschen:** jede Route `10.1.1.0/24` (bzw. `10.1.2–4.0/24`, `10.8.0.0/24`) **→ Gateway `192.168.178.1`** — die kapert den Traffic am Tunnel vorbei. +- **Behalten:** `10.2.2.0/24 → 192.168.10.10` (VM) und `10.100.2.0/24` (Services). -**Firewall → NAT → Outbound** - -Modus: **Hybrid** (oder Manual), damit eine explizite Regel greift. +## 3. Outbound NAT (*Firewall → NAT → Outbound*, Modus **Hybrid**) Neue Regel (oben): @@ -35,57 +37,28 @@ Neue Regel (oben): |------|------| | Interface | `horusopnsense` (WG) | | TCP/IP Version | IPv4 | -| Source | Alias z. B. `RFC1918` oder einzeln: `192.168.10.0/24`, `.20`, `.30`, `.40`, `.50`, `.60` | -| Destination | `10.1.1.0/24`, `10.1.2.0/24`, `10.1.3.0/24`, `10.1.4.0/24`, `10.8.0.0/24` (Alias `HORUS_WG`) | -| Translation / Target | **Interface address** (`10.1.1.22`) | +| Protocol | any | +| Source | `LAN_VLANS` | +| Destination | `HORUS_WG` | +| Translation / target | **Interface address** (= `10.1.1.22`); falls Interface nicht zuweisbar: *Single host* `10.1.1.22` | -Nicht NATen: Traffic zu `10.2.2.0/24`, `10.100.2.0/24` (bleiben intern geroutet, kein Horus-WG). +Nicht NATen: Ziele `10.2.2.0/24`, `10.100.2.0/24` (bleiben geroutet). -### 3. Firewall +## 4. Firewall-Pass (*Firewall → Rules → LAN bzw. je VLAN*) -**LAN / VLAN10 / VLAN20 / … → Horus** +| Action | Source | Destination | +|--------|--------|-------------| +| Pass | LAN-/VLAN-net | `HORUS_WG` | -| Source | Destination | Action | -|--------|-------------|--------| -| VLAN-Subnetz | Alias `HORUS_WG` | Pass | +Optional (defense in depth, eingehend auf `horusopnsense`): Source `HORUS_WG` → Dest `LAN_VLANS` = **Block**. -**WG `horusopnsense` → LAN** +## 5. Test -| Source | Destination | Action | -|--------|-------------|--------| -| `10.1.1.0/24` (Horus) | RFC1918 / VLANs | **Block** (Defense in depth; Horus routet dorthin ohnehin nicht) | - -Ausnahme Services: Horus → `10.100.2.0/24` läuft über OPNsense-Routing (kein NAT nötig für initiierte Verbindungen von Horus, wenn gewünscht — ggf. separate Pass-Regel WG → `10.100.2.0/24`). - -### 4. Static Routes prüfen - -**System → Routes** - -- Kein Eintrag `10.1.1.0/24` via `192.168.178.1` o. ä. -- `10.2.2.0/24` → `192.168.10.10` (VM) — **bleibt** -- `10.100.2.0/24` → opt7 — **bleibt** - -### 5. Test - -Vom PC (VLAN20): - -```powershell -tracert 10.1.1.1 # Hop 1 OPNsense, danach Horus (kein 192.168.178.x) -ping 10.1.1.1 -ssh root@10.1.1.1 -``` - -Auf Horus (via VM): - -```bash -ssh jean@192.168.10.10 'ssh root@10.1.1.1 wg show wg0 | grep -A5 walbWTYX' -# allowed ips: nur 10.1.1.22/32, 10.100.2.0/24 -``` - -Horus sollte eingehende SSH/Ping von **`10.1.1.22`** sehen (NAT), nicht von `192.168.20.x`. +- LAN-PC: `tracert 10.1.1.1` → Hop 1 OPNsense, dann Horus (**kein** `192.168.178.x`); dann `ping 10.1.1.1`. +- Auf Horus: `tcpdump -ni wg0 icmp` muss als Quelle **`10.1.1.22`** zeigen (NAT greift), nicht `192.168.x`. --- -## Referenz Horus +## ⚠️ Falls es trotz korrekter Config nicht geht -[horus-server-peer-opnsense.conf](horus-server-peer-opnsense.conf) · [wg0-opnsense-routes.sh](wg0-opnsense-routes.sh) +Denk an OPNsenses fragilen CARP/State-Zustand (war Ursache des VM-101-Tunnel-Problems, siehe [../../issues/2026-06-28-vm101-horus-wireguard-nat.md](../../issues/2026-06-28-vm101-horus-wireguard-nat.md)). Auf beiden OPNsense-Knoten Sync prüfen, ggf. State-Tabelle zurücksetzen.