docu: Step-A-NAT präzisiert, watchtower-Fix + mailcow-Update-Status

- 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 <noreply@anthropic.com>
This commit is contained in:
root
2026-06-28 16:09:05 +02:00
parent 9c0b7e597c
commit eb3ecbe682
2 changed files with 39 additions and 61 deletions
@@ -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.24.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.