Compare commits
2 Commits
e5723d8772
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
| f586b7adad | |||
| 8a5da080ea |
@@ -50,6 +50,7 @@ docu/
|
|||||||
| [shared/mqtt-homeassistant.md](shared/mqtt-homeassistant.md) | MQTT-Broker, HA Discovery, Credentials |
|
| [shared/mqtt-homeassistant.md](shared/mqtt-homeassistant.md) | MQTT-Broker, HA Discovery, Credentials |
|
||||||
| [shared/git-und-repos.md](shared/git-und-repos.md) | Gitea, Tokens, Clone-Pfade |
|
| [shared/git-und-repos.md](shared/git-und-repos.md) | Gitea, Tokens, Clone-Pfade |
|
||||||
| [migration/nextcloud-optimierung-und-updates.md](migration/nextcloud-optimierung-und-updates.md) | Nextcloud VM 101: Updates, Tuning, notify_push |
|
| [migration/nextcloud-optimierung-und-updates.md](migration/nextcloud-optimierung-und-updates.md) | Nextcloud VM 101: Updates, Tuning, notify_push |
|
||||||
|
| [migration/services-vlan-1000-pve1-pve2.md](migration/services-vlan-1000-pve1-pve2.md) | **Plan:** Services-VLAN 1000 pve1+pve2, Horus-NPM ohne extra VPN |
|
||||||
| [pve1/guests/](pve1/guests/) | pve1: Docker-Stacks pro VM/CT (Compose, ohne Daten) |
|
| [pve1/guests/](pve1/guests/) | pve1: Docker-Stacks pro VM/CT (Compose, ohne Daten) |
|
||||||
| [shared/opnsense-docker-subnet-routing.md](shared/opnsense-docker-subnet-routing.md) | How-To: Docker-Subnetz über OPNsense |
|
| [shared/opnsense-docker-subnet-routing.md](shared/opnsense-docker-subnet-routing.md) | How-To: Docker-Subnetz über OPNsense |
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,297 @@
|
|||||||
|
# Migrationsplan: Services-VLAN 1000 (pve1 + pve2)
|
||||||
|
|
||||||
|
**Status:** 📋 **Plan — noch nicht umsetzen** (Freigabe durch Betreiber erforderlich)
|
||||||
|
**Erstellt:** 2026-06-28
|
||||||
|
**Ziel:** Gemeinsames Services-L2 über beide Proxmox-Hosts, erreichbar von **Horus-NPM** ohne pro VM/Subnetz neue WireGuard-Tunnel.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Kurzfassung
|
||||||
|
|
||||||
|
| | Heute | Ziel |
|
||||||
|
|---|--------|------|
|
||||||
|
| L2 Services | `vmbr1` **pro Host isoliert** (kein vSwitch pve1↔pve2) | **VLAN 1000** auf `vmbr0`-Trunk, beide Hosts + Switch |
|
||||||
|
| Subnetz | `10.100.2.0/24` (nur pve2 produktiv) | **Unverändert** `10.100.2.0/24` (IPs bleiben) |
|
||||||
|
| Gateway | OPNsense opt7 `vtnet1` → `vmbr1` → `10.100.2.1` | OPNsense **VLAN 1000** auf `vtnet0` → `10.100.2.1` |
|
||||||
|
| Horus-Zugang | WG → OPNsense → `10.100.2.0/24` (Firewall unvollständig) | Gleicher Pfad, **einmalige** Firewall für ganzes Subnetz |
|
||||||
|
| Neue VM/CT | Host-abhängig / extra Routing | An `vmbr0`, Tag **1000** — Horus-NPM forwardet direkt |
|
||||||
|
|
||||||
|
**VLAN-ID Vorschlag:** **1000** (bewusst außerhalb des Schemas „VLAN-ID = drittes Oktett“, um Kollision mit VLAN 10/20/… zu vermeiden).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Motivation
|
||||||
|
|
||||||
|
- **Horus-NPM** braucht pro Dienst nur Forward Host + Port — Engpass ist **Routing/Firewall**, nicht NPM.
|
||||||
|
- Aktuell: `10.100.2.0/24` nur auf pve2-`vmbr1`; pve1-`vmbr1` ist leer/isoliert.
|
||||||
|
- Docker-Subnetze (z. B. VM 101 `docbr0` `10.2.2.0/24`) brauchen **eigenen** VM101↔Horus-Tunnel — soll für **Services** entfallen.
|
||||||
|
- Externer Zugriff über **Horus** (nicht npmplus pve2 / Apollo-Heim-IP).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Topologie (Ziel)
|
||||||
|
|
||||||
|
```
|
||||||
|
Internet
|
||||||
|
│
|
||||||
|
Horus (10.1.1.1) — NPM :443
|
||||||
|
│ WireGuard wg_horus
|
||||||
|
▼
|
||||||
|
OPNsense (pve2 VM 104) vtnet0 + VLAN 1000 → 10.100.2.1/24
|
||||||
|
│
|
||||||
|
├── physischer Switch (Trunk VLAN 1000)
|
||||||
|
│ ├── pve2 vmbr0.1000 → VM 106 HA, CT 101 (net1), CT 110, …
|
||||||
|
│ └── pve1 vmbr0.1000 → künftige Service-VMs/CTs
|
||||||
|
│
|
||||||
|
└── (kein vmbr1 mehr für Services)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Nicht im Scope dieses Plans:** Konsolidierung von `10.2.2.0/24` (VM 101 docbr0) — separates Thema.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Betroffene Systeme (Ist)
|
||||||
|
|
||||||
|
| Gast | Host | Heute | IP |
|
||||||
|
|------|------|-------|-----|
|
||||||
|
| VM 106 `homeassistant` | pve2 | `vmbr1` (net1) | `10.100.2.12` |
|
||||||
|
| CT 101 `docker` | pve2 | `vmbr1` (net1) | `10.100.2.10` |
|
||||||
|
| CT 110 `AIDEV` | pve2 | Services-Netz | `10.100.2.13` |
|
||||||
|
| VM 104 OPNsense | pve2 | `vtnet1` → opt7 SERVICES | `10.100.2.1` |
|
||||||
|
| VM 104 Fallback | pve1 | `vtnet1` → opt7 (gestoppt) | `10.100.2.1` (Config) |
|
||||||
|
| Horus NPM | Horus | Proxy `hassio.jeanavril.com` | → `10.100.2.12:8123` |
|
||||||
|
| npmplus (CT 101) | pve2 | `hassio.apollo.jeanavril.com` | → `10.100.2.12` (Apollo/Heim — **nicht** Horus-Pfad) |
|
||||||
|
|
||||||
|
**Horus-WG (bereits):** Peer OPNsense `AllowedIPs = 10.1.1.22/32, 10.100.2.0/24` — Subnetz bleibt, **keine** Horus-Änderung nötig, wenn `10.100.2.0/24` erhalten bleibt.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Design-Entscheidungen (zur Freigabe)
|
||||||
|
|
||||||
|
| Punkt | Vorschlag | Alternative |
|
||||||
|
|-------|-----------|-------------|
|
||||||
|
| VLAN-ID | **1000** | z. B. 102 (näher am „100“-Subnetz-Namen) |
|
||||||
|
| Subnetz | **10.100.2.0/24** behalten | Neues Subnetz → Horus/OPNsense/DNS anpassen |
|
||||||
|
| Gateway | **10.100.2.1** auf OPNsense VLAN 1000 | — |
|
||||||
|
| CARP auf Services | **Nein** (wie heute) — nur Master routet Services | CARP-VIP `10.100.2.1` (mehr Aufwand, Failover-Konsistenz) |
|
||||||
|
| DHCP | **Statische IPs** (Status quo) | OPNsense DHCP optional |
|
||||||
|
| vmbr1 nach Migration | **Leer lassen / später entfernen** | — |
|
||||||
|
|
||||||
|
**CARP-Hinweis:** Failover betrifft weiterhin nur VLANs auf `vmbr0` (10, 20, …). Services-VLAN 1000 hängt am gleichen Trunk — **Backup-OPNsense** (pve1) braucht dieselbe VLAN-1000-Konfiguration in der synchronisierten Config, damit bei Failover Routing zu `10.100.2.0/24` weiter funktioniert (ohne CARP auf `.1` reicht, wenn nur der **Master** aktiv Services routet und Backup identische Interface-Definition hat).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Voraussetzungen / Checks vor Start
|
||||||
|
|
||||||
|
- [ ] **Freigabe** dieses Plans durch Betreiber
|
||||||
|
- [ ] **Switch:** Trunk-Ports zu pve1 + pve2 erlauben **VLAN 1000** (tagged) — [switch-portplan.md](../shared/switch-portplan.md) prüfen/anpassen
|
||||||
|
- [ ] **pve1** `vmbr0`: `bridge-vlan-aware yes`, VIDs 2–4094 (bereits laut [pve1/02_netzwerk.md](../pve1/02_netzwerk.md))
|
||||||
|
- [ ] **pve2** `vmbr0`: VLAN-aware bestätigen
|
||||||
|
- [ ] **Wartungsfenster** für HA / Frigate / npmplus (kurze Unterbrechung pro Gast)
|
||||||
|
- [ ] **⛔ VM 104** während Migration **nicht** per Agent stoppen/starten — [pve1/04_fallback_aktivierung.md](../pve1/04_fallback_aktivierung.md)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phasen
|
||||||
|
|
||||||
|
### Phase 0 — Dokumentation & Freigabe (jetzt)
|
||||||
|
|
||||||
|
- Plan reviewen (dieses Dokument)
|
||||||
|
- VLAN-ID **1000** bestätigen oder ändern
|
||||||
|
- Switch-Portplan ergänzen
|
||||||
|
|
||||||
|
**Aufwand:** ~30 min
|
||||||
|
**Risiko:** keins
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Phase 1 — OPNsense: VLAN 1000 anlegen (ohne Gäste umzuhängen)
|
||||||
|
|
||||||
|
**Nur GUI, kein VM-Stop.**
|
||||||
|
|
||||||
|
1. **Interfaces → Other Types → VLAN**
|
||||||
|
- Parent: **`vtnet0`** (Trunk)
|
||||||
|
- Tag: **1000**
|
||||||
|
- Beschreibung: `SERVICES` oder `SERVICES-VLAN1000`
|
||||||
|
|
||||||
|
2. **Interfaces → Assignments**
|
||||||
|
- Neues Interface zuweisen (z. B. `opt11` oder ersetzt später opt7)
|
||||||
|
- IPv4: **`10.100.2.1/24`** — **erst aktivieren, wenn Phase 2 parallel läuft**, sonst Konflikt mit opt7/vmbr1
|
||||||
|
|
||||||
|
3. **Firewall** (VLAN-1000-Interface + `wg_horus`) — **einmalig für ganzes Subnetz:**
|
||||||
|
|
||||||
|
| Interface | Source | Destination | Zweck |
|
||||||
|
|-----------|--------|-------------|-------|
|
||||||
|
| `wg_horus` | `10.1.1.0/24` | `10.100.2.0/24` | Horus → Services (Hinweg) |
|
||||||
|
| VLAN 1000 | `10.100.2.0/24` | `10.1.1.0/24` | Services → Horus (Rückweg; ggf. durch *established* abgedeckt) |
|
||||||
|
| VLAN 1000 | `10.1.1.0/24` | `10.100.2.0/24` | falls Pakete so eintreffen |
|
||||||
|
| optional | LAN/VLAN10 | `10.100.2.0/24` | Admin aus Management |
|
||||||
|
|
||||||
|
4. **Kein Outbound-NAT** für `10.100.2.0/24` ↔ Horus (wie [opnsense-step-a-nat.md](../shared/horus-opnsense-wireguard/opnsense-step-a-nat.md)).
|
||||||
|
|
||||||
|
5. **Static Routes:** `10.100.2.0/24` lokal connected — keine Extra-Route nötig.
|
||||||
|
|
||||||
|
**Test (während opt7 noch aktiv):** VLAN 1000 Interface **disabled** lassen bis Phase 2.
|
||||||
|
|
||||||
|
**Aufwand:** ~1–2 h
|
||||||
|
**Risiko:** niedrig (wenn 10.100.2.1 noch nicht auf VLAN 1000 enabled)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Phase 2 — Proxmox: VLAN-aware Bridge für Gäste
|
||||||
|
|
||||||
|
Auf **pve1** und **pve2** (nur Doku / Vorbereitung, keine Gäste ändern):
|
||||||
|
|
||||||
|
- Gäste- NIC künftig: **`vmbr0`**, Tag **`1000`**, Modell `virtio`
|
||||||
|
- In Proxmox UI: Netzwerk → `vmbr0` → VLAN 1000 erlaubt (bereits vlan-aware)
|
||||||
|
|
||||||
|
Optional Proxmox `/etc/network/interfaces` Kommentar:
|
||||||
|
|
||||||
|
```text
|
||||||
|
# vmbr0.1000 — Services 10.100.2.0/24 (VLAN 1000), siehe migration/services-vlan-1000-pve1-pve2.md
|
||||||
|
```
|
||||||
|
|
||||||
|
**Aufwand:** ~30 min
|
||||||
|
**Risiko:** keins (nur Vorbereitung)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Phase 3 — Migration Gäste (pve2), einzeln mit Rollback
|
||||||
|
|
||||||
|
**Reihenfolge empfohlen** (niedrigste Abhängigkeit zuerst):
|
||||||
|
|
||||||
|
| # | Gast | Aktion | Downtime |
|
||||||
|
|---|------|--------|----------|
|
||||||
|
| 1 | CT 110 AIDEV | net auf `vmbr0`, tag 1000 | ~1 min |
|
||||||
|
| 2 | CT 101 `docker` | **net1** von vmbr1 → vmbr0 tag 1000; net0 (Mgmt) unverändert | ~2–5 min (Frigate/npmplus) |
|
||||||
|
| 3 | VM 106 HA | net1 → vmbr0 tag 1000 | ~3–5 min |
|
||||||
|
|
||||||
|
**Pro Schritt:**
|
||||||
|
|
||||||
|
1. Gast stoppen (CT: `pct stop`, VM: `qm shutdown`)
|
||||||
|
2. Netzwerk in Proxmox: Bridge `vmbr0`, VLAN Tag **1000**, gleiche MAC wenn möglich
|
||||||
|
3. OPNsense: **VLAN 1000 mit 10.100.2.1 enable**, **opt7/vmbr1 disable** (nur nach erstem erfolgreichen Gast-Test)
|
||||||
|
4. Gast starten
|
||||||
|
5. Tests:
|
||||||
|
```bash
|
||||||
|
ping 10.100.2.1
|
||||||
|
ping 10.100.2.12 # von pve2/pve1
|
||||||
|
# von Horus:
|
||||||
|
ping 10.100.2.12
|
||||||
|
curl -sI http://10.100.2.12:8123
|
||||||
|
```
|
||||||
|
|
||||||
|
**Rollback pro Gast:** Interface zurück auf `vmbr1`, opt7 wieder aktiv, VLAN 1000 disable.
|
||||||
|
|
||||||
|
**Aufwand:** ~2–4 h (inkl. Tests)
|
||||||
|
**Risiko:** mittel (Fehlkonfiguration = Services offline)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Phase 4 — OPNsense aufräumen
|
||||||
|
|
||||||
|
- **opt7 (vtnet1 / vmbr1)** deaktivieren oder entfernen
|
||||||
|
- pve2 VM 104: net1 (`vtnet1`) optional abkoppeln (nur nach stabiler Phase 3)
|
||||||
|
- Config-Sync zu pve1-Fallback prüfen (VLAN 1000 in Backup-Config)
|
||||||
|
- **Horus-Test:** `https://hassio.jeanavril.com` (NPM → `10.100.2.12:8123`)
|
||||||
|
|
||||||
|
**Aufwand:** ~1 h
|
||||||
|
**Risiko:** niedrig
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Phase 5 — pve1 produktiv nutzen
|
||||||
|
|
||||||
|
- Erste Test-CT/VM auf pve1: `vmbr0`, tag **1000**, statische IP aus `10.100.2.0/24`
|
||||||
|
- Horus-NPM: neuer Proxy-Host → `10.100.2.x:port`
|
||||||
|
- **Kein** zusätzlicher WG-Tunnel nötig
|
||||||
|
|
||||||
|
**Aufwand:** ~30 min pro erstem Dienst
|
||||||
|
**Risiko:** niedrig
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Phase 6 — Doku & Optional Cleanup
|
||||||
|
|
||||||
|
- [shared/infrastruktur-netzwerk.md](../shared/infrastruktur-netzwerk.md) — vmbr1-Hinweis aktualisieren
|
||||||
|
- [pve1/02_netzwerk.md](../pve1/02_netzwerk.md), [pve2/](../pve2/) — VLAN 1000
|
||||||
|
- `vmbr1` auf beiden Hosts: in Doku als „legacy / ungenutzt“ markieren
|
||||||
|
- npmplus `hassio.apollo` — bewusst lassen oder deprecaten (Apollo-Pfad)
|
||||||
|
|
||||||
|
**Aufwand:** ~1 h
|
||||||
|
**Risiko:** keins
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Horus & NPM (nach Migration)
|
||||||
|
|
||||||
|
| Komponente | Änderung nötig? |
|
||||||
|
|------------|-----------------|
|
||||||
|
| Horus WG Peer OPNsense `AllowedIPs` | **Nein** (Subnetz bleibt `10.100.2.0/24`) |
|
||||||
|
| Horus `wg0-opnsense-routes.sh` | **Nein** |
|
||||||
|
| Horus NPM Proxy-Hosts | **Nein** für bestehende IPs; neue Dienste nur NPM-Eintrag |
|
||||||
|
| Home Assistant `trusted_proxies` | `10.1.1.1` (+ ggf. Horus-NPM-IP) — siehe Betrieb Horus |
|
||||||
|
| DNS `*.jeanavril.com` | unverändert (Horus) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Gesamtaufwand (Schätzung)
|
||||||
|
|
||||||
|
| Phase | Aufwand | Downtime |
|
||||||
|
|-------|---------|----------|
|
||||||
|
| 0 Freigabe | 0,5 h | — |
|
||||||
|
| 1 OPNsense VLAN | 1–2 h | keins |
|
||||||
|
| 2 Proxmox Vorbereitung | 0,5 h | keins |
|
||||||
|
| 3 Gäste migrieren | 2–4 h | ~10–15 min gesamt (gestaffelt) |
|
||||||
|
| 4 OPNsense Cleanup | 1 h | optional kurz |
|
||||||
|
| 5 pve1 erster Gast | 0,5 h | minimal |
|
||||||
|
| 6 Doku | 1 h | — |
|
||||||
|
| **Summe** | **~1–2 Arbeitstage** (inkl. Puffer/Tests) | **gestaffelt** |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Risiken & Mitigation
|
||||||
|
|
||||||
|
| Risiko | Mitigation |
|
||||||
|
|--------|------------|
|
||||||
|
| Switch trunk ohne VLAN 1000 | Phase 0 Switch prüfen |
|
||||||
|
| Doppel-IP `10.100.2.1` (opt7 + VLAN1000) | VLAN 1000 erst enable, wenn erster Gast umgehängt |
|
||||||
|
| CARP/Failover Services | Backup-OPNsense Config sync; Failover-Test **nur manuell** |
|
||||||
|
| HA/WebSockets über Horus-NPM | `trusted_proxies`, NPM WebSockets (bereits an für hassio) |
|
||||||
|
| VM 104 durch Agent gestoppt | ⛔ Regel in [04_fallback_aktivierung.md](../pve1/04_fallback_aktivierung.md) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Abnahme-Checkliste (nach Umsetzung)
|
||||||
|
|
||||||
|
- [ ] Von **pve1** und **pve2**: `ping 10.100.2.12`
|
||||||
|
- [ ] Von **Horus**: `ping 10.100.2.12`, `curl http://10.100.2.12:8123`
|
||||||
|
- [ ] **hassio.jeanavril.com** über Horus-NPM (extern ohne VPN)
|
||||||
|
- [ ] **Frigate** / npmplus intern (`10.100.2.10`) ok
|
||||||
|
- [ ] Neue Test-VM auf **pve1** VLAN 1000 erreichbar von Horus
|
||||||
|
- [ ] OPNsense: opt7/vmbr1 deaktiviert, VLAN 1000 produktiv
|
||||||
|
- [ ] Doku aktualisiert
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Referenzen
|
||||||
|
|
||||||
|
| Dokument | Inhalt |
|
||||||
|
|----------|--------|
|
||||||
|
| [shared/infrastruktur-netzwerk.md](../shared/infrastruktur-netzwerk.md) | VLANs, vmbr0/vmbr1 |
|
||||||
|
| [pve1/02_netzwerk.md](../pve1/02_netzwerk.md) | pve1 Bridges |
|
||||||
|
| [pve1/04_fallback_aktivierung.md](../pve1/04_fallback_aktivierung.md) | CARP, vmbr1 |
|
||||||
|
| [shared/horus-opnsense-wireguard/opnsense-step-a-nat.md](../shared/horus-opnsense-wireguard/opnsense-step-a-nat.md) | Horus ↔ OPNsense |
|
||||||
|
| [shared/opnsense-docker-subnet-routing.md](../shared/opnsense-docker-subnet-routing.md) | Analog für Docker-Subnetze (VM 101) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Offene Punkte zur Freigabe
|
||||||
|
|
||||||
|
1. **VLAN-ID 1000** — bestätigen?
|
||||||
|
2. **Subnetz 10.100.2.0/24** beibehalten — ok?
|
||||||
|
3. **CARP auf 10.100.2.1** — bewusst **nein**?
|
||||||
|
4. **Switch-Ports** — wer trägt VLAN 1000 ein (Aruba)?
|
||||||
|
5. **Wartungsfenster** für Phase 3 (HA/Frigate)?
|
||||||
|
|
||||||
|
**Nach Freigabe:** Phase 1 starten — **nicht** vorher Gäste umhängen.
|
||||||
@@ -7,6 +7,18 @@
|
|||||||
| pve1 | 192.168.10.5 | Primärer Proxmox-Host, Fallback-Router |
|
| pve1 | 192.168.10.5 | Primärer Proxmox-Host, Fallback-Router |
|
||||||
| pve2 | 192.168.10.4 | Produktions-Proxmox-Host, aktiver Router |
|
| pve2 | 192.168.10.4 | Produktions-Proxmox-Host, aktiver Router |
|
||||||
|
|
||||||
|
## VMs / Container auf pve1
|
||||||
|
|
||||||
|
| VMID | Name | IP | Zweck | Status |
|
||||||
|
|------|------|----|-------|--------|
|
||||||
|
| 101 | ubuntu | 192.168.10.10 | Docker-Host (Nextcloud, Gitea, NPM, …) | running, onboot |
|
||||||
|
| 104 | opnsense-fallback | — | CARP-Backup OPNsense | stopped, onboot:0 |
|
||||||
|
| 105 | finance | 192.168.10.43 | IBKR TWS Trading-VM (Xvfb + noVNC) | running, onboot |
|
||||||
|
|
||||||
|
Docs guests: [guests/](guests/)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Fallback-Router
|
## Fallback-Router
|
||||||
|
|
||||||
- **VMID:** 104
|
- **VMID:** 104
|
||||||
|
|||||||
@@ -0,0 +1,111 @@
|
|||||||
|
# VM 105 — finance (IBKR TWS Trading-VM)
|
||||||
|
|
||||||
|
| | |
|
||||||
|
|---|---|
|
||||||
|
| **Proxmox** | pve1, VMID 105 |
|
||||||
|
| **IP** | 192.168.10.43 (DHCP) |
|
||||||
|
| **OS** | Ubuntu 25.10 (Questing Quokka) |
|
||||||
|
| **User** | `ubuntu` (sudo), SSH-Key: `/root/.ssh/finance_vm` |
|
||||||
|
| **VNC** | noVNC Browser: `http://<VM-IP>:6080/vnc.html` |
|
||||||
|
| **TWS** | `/home/tws/Jts/` |
|
||||||
|
| **IBC** | `/home/tws/ibc/` |
|
||||||
|
|
||||||
|
## Zweck
|
||||||
|
|
||||||
|
Dedizierte VM für Interactive Brokers Trader Workstation (TWS).
|
||||||
|
Headless-Betrieb via **Xvfb** (virtueller Framebuffer 1920×1080) + **noVNC** im Browser.
|
||||||
|
IBC automatisiert den Login.
|
||||||
|
|
||||||
|
## Stack
|
||||||
|
|
||||||
|
```
|
||||||
|
VM 105 finance (12 GB RAM, 4 vCPU, 32 GB Disk)
|
||||||
|
└── Xvfb :1 (1920×1080)
|
||||||
|
├── Openbox (WM, kein Desktop)
|
||||||
|
├── TigerVNC x0vncserver → Port 5900
|
||||||
|
├── noVNC + websockify → Port 6080 (Browser-Zugang)
|
||||||
|
└── TWS via IBC (automatischer Login, API Port 7497)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Services
|
||||||
|
|
||||||
|
| Service | Unit | Status |
|
||||||
|
|---------|------|--------|
|
||||||
|
| Xvfb | `xvfb.service` | autostart |
|
||||||
|
| Openbox | `openbox.service` | autostart |
|
||||||
|
| VNC | `vncserver.service` | autostart |
|
||||||
|
| noVNC | `novnc.service` | autostart |
|
||||||
|
| TWS+IBC | `tws-ibc.service` | autostart |
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Status aller Services
|
||||||
|
systemctl status xvfb openbox vncserver novnc tws-ibc
|
||||||
|
|
||||||
|
# noVNC im Browser
|
||||||
|
http://192.168.10.XX:6080/vnc.html
|
||||||
|
|
||||||
|
# TWS API (local / aus dem LAN)
|
||||||
|
Host: 192.168.10.XX Port: 7497
|
||||||
|
```
|
||||||
|
|
||||||
|
## Wichtige Pfade
|
||||||
|
|
||||||
|
| Pfad | Inhalt |
|
||||||
|
|------|--------|
|
||||||
|
| `/home/tws/Jts/` | TWS Installation |
|
||||||
|
| `/home/tws/ibc/` | IBC Controller |
|
||||||
|
| `/home/tws/ibc/config.ini` | IBC Konfiguration (Login, Trading-Mode) |
|
||||||
|
| `/home/tws/.vnc/passwd` | VNC-Passwort |
|
||||||
|
| `/var/log/tws-ibc.log` | TWS/IBC Startlog |
|
||||||
|
|
||||||
|
## Setup-Script
|
||||||
|
|
||||||
|
Initiales Setup: [`setup-tws.sh`](setup-tws.sh)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Auf dem Proxmox-Host ausführen (nach erstem Boot der VM):
|
||||||
|
ssh -i /root/.ssh/finance_vm ubuntu@192.168.10.XX 'bash -s' < /root/docu/pve1/guests/vm105-finance/setup-tws.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
## IBC Konfiguration
|
||||||
|
|
||||||
|
> IBC (https://github.com/IbcAlpha/IBC) automatisiert TWS-Login und API-Aktivierung.
|
||||||
|
> Bei neuen TWS-Versionen ggf. `jvmOptions` in `config.ini` anpassen (--add-opens).
|
||||||
|
|
||||||
|
```ini
|
||||||
|
# /home/tws/ibc/config.ini (Auszug)
|
||||||
|
IbLoginId=DEIN_USERNAME
|
||||||
|
IbPassword=DEIN_PASSWORT
|
||||||
|
TradingMode=live # oder: paper
|
||||||
|
ReadOnlyLogin=no
|
||||||
|
AcceptNonBrokerageAccountWarning=yes
|
||||||
|
```
|
||||||
|
|
||||||
|
## TWS API
|
||||||
|
|
||||||
|
TWS muss API aktiviert haben (einmalig manuell in TWS-Einstellungen):
|
||||||
|
Edit → Global Configuration → API → Settings:
|
||||||
|
- [x] Enable ActiveX and Socket Clients
|
||||||
|
- Socket port: **7497**
|
||||||
|
- [x] Allow connections from localhost only *(deaktivieren falls remote)*
|
||||||
|
|
||||||
|
## Netzwerk
|
||||||
|
|
||||||
|
| | |
|
||||||
|
|---|---|
|
||||||
|
| Bridge | vmbr0 (VLAN 10, Management) |
|
||||||
|
| MAC | BC:24:11:CD:7F:9A |
|
||||||
|
| IP | 192.168.10.43 (DHCP) |
|
||||||
|
|
||||||
|
## Ressourcen
|
||||||
|
|
||||||
|
| | |
|
||||||
|
|---|---|
|
||||||
|
| RAM | 12 GB |
|
||||||
|
| CPU | 4 vCPU (host type) |
|
||||||
|
| Disk | 32 GB (thin, local-lvm) |
|
||||||
|
|
||||||
|
## Erstellt
|
||||||
|
|
||||||
|
2026-06-28 via Cloud-Image (ubuntu-25.10-cloudimg-amd64.img)
|
||||||
|
SSH-Key: `/root/.ssh/finance_vm` (pve1-root → tws-user)
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# TWS + IBC Installation auf VM 105 finance
|
||||||
|
# Ausführen als tws-User oder ubuntu-User mit sudo
|
||||||
|
# Voraussetzung: setup-tws.sh wurde erfolgreich ausgeführt
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
TWS_USER=tws
|
||||||
|
TWS_HOME=/home/tws
|
||||||
|
|
||||||
|
echo "=== TWS Installer herunterladen ==="
|
||||||
|
# IBKR bietet stable und latest an; stable bevorzugt für Produktion
|
||||||
|
TWS_URL="https://download2.interactivebrokers.com/installers/tws/stable-standalone/tws-stable-standalone-linux-x64.sh"
|
||||||
|
INSTALLER="$TWS_HOME/tws-installer.sh"
|
||||||
|
|
||||||
|
sudo -u $TWS_USER wget -q --show-progress -O "$INSTALLER" "$TWS_URL"
|
||||||
|
sudo chmod +x "$INSTALLER"
|
||||||
|
|
||||||
|
echo "=== TWS Installation starten (GUI via DISPLAY :1 / noVNC) ==="
|
||||||
|
echo "Öffne noVNC im Browser und klicke den Installer durch:"
|
||||||
|
echo " http://$(hostname -I | awk '{print $1}'):6080/vnc.html"
|
||||||
|
echo ""
|
||||||
|
echo "Installer wird jetzt gestartet..."
|
||||||
|
sudo -u $TWS_USER DISPLAY=:1 "$INSTALLER" &
|
||||||
|
echo "Installer PID: $!"
|
||||||
|
echo ""
|
||||||
|
echo "Nach der Installation bitte dieses Script weiter ausführen."
|
||||||
|
echo "Drücke Enter wenn TWS installiert wurde..."
|
||||||
|
read -r
|
||||||
|
|
||||||
|
echo "=== IBC herunterladen ==="
|
||||||
|
IBC_DIR="$TWS_HOME/ibc"
|
||||||
|
sudo -u $TWS_USER mkdir -p "$IBC_DIR"
|
||||||
|
|
||||||
|
# Aktuelle Version von GitHub ermitteln
|
||||||
|
IBC_LATEST=$(curl -s https://api.github.com/repos/IbcAlpha/IBC/releases/latest | grep '"tag_name"' | cut -d'"' -f4)
|
||||||
|
echo "IBC Version: $IBC_LATEST"
|
||||||
|
|
||||||
|
IBC_URL="https://github.com/IbcAlpha/IBC/releases/download/${IBC_LATEST}/IBCLinux-${IBC_LATEST}.zip"
|
||||||
|
sudo -u $TWS_USER wget -q --show-progress -O "$IBC_DIR/ibc.zip" "$IBC_URL"
|
||||||
|
sudo -u $TWS_USER unzip -q -o "$IBC_DIR/ibc.zip" -d "$IBC_DIR/"
|
||||||
|
sudo chmod +x "$IBC_DIR"/*.sh "$IBC_DIR/scripts"/*.sh 2>/dev/null || true
|
||||||
|
|
||||||
|
echo "=== IBC Konfiguration erstellen ==="
|
||||||
|
# TWS-Pfad ermitteln (Standard-Installpfad)
|
||||||
|
TWS_PATH=$(find "$TWS_HOME" -name "jts.ini" 2>/dev/null | head -1 | xargs dirname 2>/dev/null || echo "$TWS_HOME/Jts")
|
||||||
|
|
||||||
|
sudo -u $TWS_USER tee "$IBC_DIR/config.ini" > /dev/null <<IBCCONF
|
||||||
|
# IBC Konfiguration für TWS
|
||||||
|
# Dokumentation: https://github.com/IbcAlpha/IBC/blob/master/userguide.md
|
||||||
|
|
||||||
|
[Logon]
|
||||||
|
IbLoginId=DEIN_IBKR_USERNAME
|
||||||
|
IbPassword=DEIN_IBKR_PASSWORT
|
||||||
|
TradingMode=live
|
||||||
|
# TradingMode=paper
|
||||||
|
|
||||||
|
[TWS]
|
||||||
|
ReadOnlyLogin=no
|
||||||
|
AcceptNonBrokerageAccountWarning=yes
|
||||||
|
AutoClosedown=no
|
||||||
|
ClosedownAt=
|
||||||
|
|
||||||
|
[API]
|
||||||
|
OverrideTwsApiPort=7497
|
||||||
|
AcceptIncomingConnectionAction=accept
|
||||||
|
AllowedAddresses=
|
||||||
|
|
||||||
|
[Logging]
|
||||||
|
LogToConsole=yes
|
||||||
|
IBCCONF
|
||||||
|
|
||||||
|
echo "=== IBC Start-Script anpassen ==="
|
||||||
|
# IBC nutzt twsstart.sh oder StartTWS.sh je nach Version
|
||||||
|
IBC_SCRIPT=$(find "$IBC_DIR" -name "twsstart.sh" -o -name "StartTWS.sh" 2>/dev/null | head -1)
|
||||||
|
if [ -z "$IBC_SCRIPT" ]; then
|
||||||
|
echo "WARNUNG: IBC Start-Script nicht gefunden, manuell prüfen in $IBC_DIR"
|
||||||
|
else
|
||||||
|
echo "IBC Start-Script: $IBC_SCRIPT"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "=== tws-ibc Systemd-Service erstellen ==="
|
||||||
|
sudo tee /etc/systemd/system/tws-ibc.service > /dev/null <<TWSSERVICE
|
||||||
|
[Unit]
|
||||||
|
Description=TWS via IBC (Interactive Brokers Controller)
|
||||||
|
After=novnc.service openbox.service
|
||||||
|
Requires=xvfb.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
User=$TWS_USER
|
||||||
|
Environment=DISPLAY=:1
|
||||||
|
Environment=HOME=$TWS_HOME
|
||||||
|
WorkingDirectory=$IBC_DIR
|
||||||
|
ExecStart=$IBC_DIR/twsstart.sh
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=30
|
||||||
|
StandardOutput=append:/var/log/tws-ibc.log
|
||||||
|
StandardError=append:/var/log/tws-ibc.log
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
TWSSERVICE
|
||||||
|
|
||||||
|
sudo touch /var/log/tws-ibc.log
|
||||||
|
sudo chown $TWS_USER:$TWS_USER /var/log/tws-ibc.log
|
||||||
|
|
||||||
|
sudo systemctl daemon-reload
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== Installation abgeschlossen ==="
|
||||||
|
echo ""
|
||||||
|
echo "WICHTIG: Vor dem Start von tws-ibc.service:"
|
||||||
|
echo " 1. IBC-Credentials eintragen:"
|
||||||
|
echo " sudo nano $IBC_DIR/config.ini"
|
||||||
|
echo " 2. IBC-Start-Script prüfen:"
|
||||||
|
echo " ls $IBC_DIR/"
|
||||||
|
echo " 3. Service aktivieren:"
|
||||||
|
echo " sudo systemctl enable --now tws-ibc"
|
||||||
|
echo ""
|
||||||
|
echo "TWS manuell testen (ohne IBC):"
|
||||||
|
echo " sudo -u tws DISPLAY=:1 $TWS_PATH/tws"
|
||||||
|
echo ""
|
||||||
|
echo "Logs:"
|
||||||
|
echo " tail -f /var/log/tws-ibc.log"
|
||||||
|
echo " journalctl -u tws-ibc -f"
|
||||||
@@ -0,0 +1,142 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Setup-Script für VM 105 finance: Xvfb + noVNC + TWS + IBC
|
||||||
|
# Ausführen als ubuntu-User (sudo-fähig), nicht-interaktiv:
|
||||||
|
# ssh -i /root/.ssh/finance_vm ubuntu@192.168.10.43 'bash -s' < setup-tws.sh
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
VNC_PASS="${VNC_PASS:-$(openssl rand -base64 12 | tr -d '/+=')}"
|
||||||
|
|
||||||
|
echo "=== [1/6] System-Update ==="
|
||||||
|
sudo apt-get update -qq
|
||||||
|
sudo DEBIAN_FRONTEND=noninteractive apt-get upgrade -y -qq
|
||||||
|
|
||||||
|
echo "=== [2/6] Pakete installieren ==="
|
||||||
|
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y -qq \
|
||||||
|
xvfb \
|
||||||
|
openbox \
|
||||||
|
tigervnc-standalone-server \
|
||||||
|
novnc \
|
||||||
|
websockify \
|
||||||
|
openjdk-21-jre \
|
||||||
|
wget \
|
||||||
|
unzip \
|
||||||
|
xdotool \
|
||||||
|
x11-utils \
|
||||||
|
x11-xserver-utils \
|
||||||
|
fonts-dejavu \
|
||||||
|
dbus-x11 \
|
||||||
|
libxtst6 \
|
||||||
|
libxi6 \
|
||||||
|
ca-certificates \
|
||||||
|
curl
|
||||||
|
|
||||||
|
echo "=== [3/6] tws-User anlegen ==="
|
||||||
|
if ! id -u tws &>/dev/null; then
|
||||||
|
sudo useradd -m -s /bin/bash tws
|
||||||
|
fi
|
||||||
|
sudo mkdir -p /home/tws/.vnc /home/tws/.config/openbox
|
||||||
|
sudo chown -R tws:tws /home/tws
|
||||||
|
|
||||||
|
echo "=== [4/6] VNC-Passwort setzen (automatisch) ==="
|
||||||
|
echo "$VNC_PASS" | sudo -u tws vncpasswd -f | sudo -u tws tee /home/tws/.vnc/passwd > /dev/null
|
||||||
|
sudo chmod 600 /home/tws/.vnc/passwd
|
||||||
|
sudo chown tws:tws /home/tws/.vnc/passwd
|
||||||
|
|
||||||
|
echo "=== [5/6] Systemd-Services erstellen ==="
|
||||||
|
|
||||||
|
sudo tee /etc/systemd/system/xvfb.service > /dev/null <<'EOF'
|
||||||
|
[Unit]
|
||||||
|
Description=Virtual Framebuffer 1920x1080
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
User=tws
|
||||||
|
ExecStart=/usr/bin/Xvfb :1 -screen 0 1920x1080x24 -ac -nolisten tcp
|
||||||
|
Restart=always
|
||||||
|
RestartSec=5
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
|
||||||
|
sudo tee /etc/systemd/system/openbox.service > /dev/null <<'EOF'
|
||||||
|
[Unit]
|
||||||
|
Description=Openbox Window Manager on DISPLAY :1
|
||||||
|
After=xvfb.service
|
||||||
|
Requires=xvfb.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
User=tws
|
||||||
|
Environment=DISPLAY=:1
|
||||||
|
Environment=HOME=/home/tws
|
||||||
|
ExecStart=/usr/bin/openbox-session
|
||||||
|
Restart=always
|
||||||
|
RestartSec=5
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
|
||||||
|
sudo tee /etc/systemd/system/vncserver.service > /dev/null <<'EOF'
|
||||||
|
[Unit]
|
||||||
|
Description=TigerVNC x0vncserver on DISPLAY :1
|
||||||
|
After=xvfb.service
|
||||||
|
Requires=xvfb.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
User=tws
|
||||||
|
Environment=DISPLAY=:1
|
||||||
|
ExecStart=/usr/bin/x0vncserver -display :1 -rfbport 5900 -SecurityTypes VncAuth -PasswordFile /home/tws/.vnc/passwd
|
||||||
|
Restart=always
|
||||||
|
RestartSec=5
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
|
||||||
|
sudo tee /etc/systemd/system/novnc.service > /dev/null <<'EOF'
|
||||||
|
[Unit]
|
||||||
|
Description=noVNC Websocket Proxy
|
||||||
|
After=vncserver.service
|
||||||
|
Requires=vncserver.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
User=tws
|
||||||
|
ExecStart=/usr/share/novnc/utils/novnc_proxy --vnc localhost:5900 --listen 0.0.0.0:6080
|
||||||
|
Restart=always
|
||||||
|
RestartSec=5
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Openbox autostart (leer)
|
||||||
|
sudo -u tws tee /home/tws/.config/openbox/autostart > /dev/null <<'EOF'
|
||||||
|
# TWS wird via tws-ibc.service gestartet
|
||||||
|
EOF
|
||||||
|
|
||||||
|
echo "=== [6/6] Services aktivieren ==="
|
||||||
|
sudo systemctl daemon-reload
|
||||||
|
sudo systemctl enable --now xvfb openbox vncserver novnc
|
||||||
|
|
||||||
|
# Kurz warten damit Services hochfahren
|
||||||
|
sleep 3
|
||||||
|
sudo systemctl is-active xvfb vncserver novnc || true
|
||||||
|
|
||||||
|
VM_IP=$(hostname -I | awk '{print $1}')
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "========================================"
|
||||||
|
echo " Basis-Stack erfolgreich eingerichtet"
|
||||||
|
echo "========================================"
|
||||||
|
echo ""
|
||||||
|
echo " noVNC Browser: http://${VM_IP}:6080/vnc.html"
|
||||||
|
echo " VNC Passwort: ${VNC_PASS}"
|
||||||
|
echo " VNC Port: 5900"
|
||||||
|
echo ""
|
||||||
|
echo " BITTE NOTIEREN: VNC-Passwort wird nicht erneut angezeigt"
|
||||||
|
echo " Ändern mit: sudo -u tws vncpasswd /home/tws/.vnc/passwd"
|
||||||
|
echo ""
|
||||||
|
echo "Nächster Schritt: TWS + IBC installieren:"
|
||||||
|
echo " ssh -i /root/.ssh/finance_vm ubuntu@${VM_IP} 'bash -s' < setup-tws-installer.sh"
|
||||||
|
echo ""
|
||||||
Reference in New Issue
Block a user