forwarding

This commit is contained in:
chk
2026-06-07 07:21:30 +02:00
parent 475dfcc446
commit c04e5902ce
3 changed files with 98 additions and 67 deletions

111
README.md
View File

@@ -22,7 +22,7 @@ terminiert TLS (Let's Encrypt) und leitet an den passenden Upstream weiter.
- [Authentifizierung](#authentifizierung) - [Authentifizierung](#authentifizierung)
- [TLS / Let's Encrypt](#tls--lets-encrypt) - [TLS / Let's Encrypt](#tls--lets-encrypt)
- [Container & Betrieb](#container--betrieb) - [Container & Betrieb](#container--betrieb)
- [Neuen Dienst hinzufügen](#neuen-dienst-hinzufügen) - [Eine neue Seite ins Portal aufnehmen](#eine-neue-seite-ins-portal-aufnehmen)
- [Dateiübersicht](#dateiübersicht) - [Dateiübersicht](#dateiübersicht)
--- ---
@@ -134,7 +134,7 @@ Dienst im iFrame. Bild: [`doc/Portal.png`](doc/Portal.png) · Quellen:
> automatisch aus `forwarding.conf` erzeugt. Ein neuer Dienst in > automatisch aus `forwarding.conf` erzeugt. Ein neuer Dienst in
> `forwarding.conf` taucht also erst dann in der Navigationsleiste auf, wenn er > `forwarding.conf` taucht also erst dann in der Navigationsleiste auf, wenn er
> auch ins `services`-Array eingetragen wird (siehe > auch ins `services`-Array eingetragen wird (siehe
> [Neuen Dienst hinzufügen](#neuen-dienst-hinzufügen)). > [Eine neue Seite ins Portal aufnehmen](#eine-neue-seite-ins-portal-aufnehmen)).
Aktuell im Portal verlinkte Dienste (`public/app.js`): Aktuell im Portal verlinkte Dienste (`public/app.js`):
@@ -353,24 +353,105 @@ docker logs appServer_PortalUI | grep connect-proxies
--- ---
## Neuen Dienst hinzufügen ## Eine neue Seite ins Portal aufnehmen
Zwei Fragen entscheiden, wie eine Seite angebunden wird: **(1) Wie erreicht der
nginx-Container das Backend?** und **(2) unter welcher Subdomain** soll es laufen?
### Wie das Backend erreichbar ist zwei Wege
- **A) Direkt** das Backend ist vom nginx-Container aus erreichbar:
- **lokaler Container** im Docker-Netz `appRobotNet` → per Container-Name,
z. B. `http://open-webui:8080`.
- **Gerät im LAN** → per **IP**, z. B. `http://192.168.0.210:9183`.
- ⚠️ **Kein `.local`/mDNS!** Namen wie `thinkcentre.local` löst der Container
**nicht** auf (Docker-DNS kann kein mDNS) → der Dienst wird zum 503-Platzhalter.
Immer IP **oder** Tunnel verwenden.
- **B) Über den SSH-Reverse-Tunnel** das Backend steht hinter NAT/Firewall
(Roboter-Pi, ThinkCentre, InformatikWeb) und hat keine Route ins Server-LAN. Es
„meldet sich“ per autossh beim Server an und wird dort auf einem festen Port
erreichbar.
### Hintergrund: der SSH-Reverse-Tunnel
Auf der **Geräteseite** (z. B. im Portainer-Stack des Roboters) läuft ein
autossh-Container `appRobot_Tunnel`, der eine Dauerverbindung zu
`tunnel@server.schooltech.ch -p 2255` (= Container `appServer_TunnelHead`)
aufbaut. Pro Dienst eine Zeile:
1. **Zeile in `forwarding.conf`** ergänzen, z. B.:
``` ```
meinDienst.server.schooltech.ch http://appServer_TunnelHead:9999 redirect true false -R 0.0.0.0:<HubPort>:<container>:<port>
``` ```
2. **DNS:** sicherstellen, dass die Subdomain auf den Server zeigt
(Wildcard `*.server.schooltech.ch` oder A-Record). Bedeutung: „Öffne am TunnelHead den Port `<HubPort>` und leite ihn an
3. **Zertifikat** holen Domain in `letsEncrypt.sh` aufnehmen und Skript laufen `<container>:<port>` auf der Geräteseite weiter.“ Damit wird `<container>:<port>`
lassen (sonst überspringt `connect-proxies.sh` den vHost). (Geräteseite) für nginx als **`appServer_TunnelHead:<HubPort>`** erreichbar und
4. **nginx neu starten:** `docker restart appServer_PortalUI`. `forwarding.conf` proxyt genau dorthin.
5. **Optional im Portal sichtbar machen:** Eintrag im `services`-Array in
`public/app.js` ergänzen: **Aktuelle Tunnel-Belegung** (aus dem autossh-Command des `appRobot_Tunnel`-Stacks):
| HubPort | → Geräteseite | Portal-Subdomain |
|---|---|---|
| 9703 | `portainer:9000` | `tcPortainer` |
| 9710 | `appRobot_Control:10010` | `tcControl` |
| 9712 | `appRobot_Simulation:1003` | `tcSimulation` |
| 9725 | `appRobot_AccessBase:443` | `robotBase` |
| 9726 | `appRobot_AccessEllbow:443` | `robotEllbow` |
| 9727 | `appRobot_AccessHand:443` | `robotHand` |
| 9743 | `AppRobotWebcam:8444` | `robotVideo` |
| 9744 | `appRobot_CodeServer:8443` | `robotVSCode` |
| 9780 | `appRobot_guacamole:8080` | `tcGuac` |
| 9793 | `appRobot_Homing:2093` | `robotHoming` |
| 9798 | `appRobot_Driver:2098` | `robotDriver` |
> Konvention der HubPorts: **81xx → RP3/SCARA**, **97xx → ThinkCentre/Roboter**,
> **99xx → InformatikWeb**. Das `0.0.0.0:` setzt voraus, dass am TunnelHead-sshd
> `GatewayPorts clientspecified` aktiv ist (ist es).
### Rezept A: neue Seite **über den Tunnel**
1. **Tunnel öffnen** geräteseitig im autossh-Command eine `-R`-Zeile ergänzen
(freien HubPort wählen), z. B.:
```
-R 0.0.0.0:9750:appRobot_NeuerDienst:8080 \
```
Stack neu deployen (Portainer). Der Dienst ist nun `appServer_TunnelHead:9750`.
2. **`forwarding.conf`** (Server) Zeile ergänzen; das Schema muss zu dem passen,
was das Backend spricht:
```
neuerdienst.server.schooltech.ch http://appServer_TunnelHead:9750 redirect true false
```
3. **Zertifikat** Domain in `letsEncrypt.sh` aufnehmen (**mit `--cert-name`!**)
und ausführen; ohne Zertifikat überspringt `connect-proxies.sh` den vHost.
4. **nginx neu starten:** `docker restart appServer_PortalUI`, dann im Log prüfen:
`[+] … Zertifikat OK … Erzeuge 443`.
5. **Optional im Portal-Menü zeigen:** Eintrag im `services`-Array in
`public/app.js`:
```js ```js
{ id: "mein", name: "Mein Dienst", url: "https://meinDienst.server.schooltech.ch/" } { id: "neu", name: "Neuer Dienst", url: "https://neuerdienst.server.schooltech.ch/" }
``` ```
6. **Optional Login erzwingen:** in `forwarding.conf` als 8. Spalte 6. **Optional Login erzwingen:** in `forwarding.conf` 8. Spalte `… 443 true`.
`… server.schooltech.ch 443 true` setzen.
### Rezept B: neue Seite **direkt** (lokaler Container / LAN-IP)
Wie A, nur **Schritt 1 entfällt**. Der Upstream in `forwarding.conf` zeigt direkt
auf den Container-Namen oder die LAN-IP (niemals `.local`):
```
neuerdienst.server.schooltech.ch http://192.168.0.50:8080 redirect true false
```
(Rest identisch: Zertifikat → Restart → optional `app.js`/Auth.)
### Eine Seite entfernen
1. Zeile in `forwarding.conf` löschen (oder mit `#` auskommentieren) und ggf. den
`app.js`-Eintrag entfernen → `docker restart appServer_PortalUI`.
2. Falls über Tunnel: die `-R`-Zeile aus dem `appRobot_Tunnel`-Stack entfernen und
neu deployen.
3. Optional Zertifikat aufräumen: `certbot delete --cert-name <domain>`.
> **Spalten-Kurzreferenz** der `forwarding.conf`:
> `server_name upstream_url http_behavior websockets verify_upstream_tls [cert_domain] [listen_port] [auth_required]`
> — Details siehe [`forwarding.conf` das Herzstück](#forwardingconf--das-herzstück).
--- ---

View File

@@ -30,7 +30,8 @@ tcSimulation.server.schooltech.ch https://appServer_TunnelHead:9712
#tcVideocontroller.server.schooltech.ch https://tcvideo:9443 redirect true false #tcVideocontroller.server.schooltech.ch https://tcvideo:9443 redirect true false
robotHoming.server.schooltech.ch https://appServer_TunnelHead:9793 redirect true fals robotHoming.server.schooltech.ch https://appServer_TunnelHead:9793 redirect true fals
#robotVideo.server.schooltech.ch https://appServer_TunnelHead:9743 redirect true false robotVideo.server.schooltech.ch 443 true #robotVideo.server.schooltech.ch https://appServer_TunnelHead:9743 redirect true false robotVideo.server.schooltech.ch 443 true
robotVideo.server.schooltech.ch http://thinkcentre.local:8444 redirect true false #robotVideo.server.schooltech.ch http://thinkcentre.local:8444 redirect true false
robotVideo.server.schooltech.ch https://appServer_TunnelHead:9743 redirect true false
tcControl.server.schooltech.ch https://appServer_TunnelHead:9710 redirect true false tcControl.server.schooltech.ch 443 true tcControl.server.schooltech.ch https://appServer_TunnelHead:9710 redirect true false tcControl.server.schooltech.ch 443 true
nextcloud.server.schooltech.ch http://192.168.0.210:9183 redirect true false nextcloud.server.schooltech.ch http://192.168.0.210:9183 redirect true false
robotBase.server.schooltech.ch https://appServer_TunnelHead:9725 redirect true false robotBase.server.schooltech.ch https://appServer_TunnelHead:9725 redirect true false

View File

@@ -1,51 +0,0 @@
# server_name upstream_url ttp_behavior websockets verify_upstream_tls [cert_domain] listen port [Auth_Required]
#fluidncRed.server.schooltech.ch http://appServer_TunnelHead:8120 redirect true false
# 444 → 8121 (WS/WSS)
# fluidncRedWs.server.schooltech.ch http://appServer_TunnelHead:8121 redirect true false fluidncRedWs.server.schooltech.ch 444
#server.schooltech.ch local static false false
server.schooltech.ch local redirect false false server.schooltech.ch 443
#inf InformatiWeb ist per Tunnel angeschlossen. Soll auf 97xx Ports gehen
infPortainer.server.schooltech.ch http://appServer_TunnelHead:9903 redirect true false
infGuac.server.schooltech.ch http://appServer_TunnelHead:9980 redirect true false
#RP5 ist "Lokal" der Server
rp5Guac.server.schooltech.ch http://appServer_guacamole:8080 redirect true false
rp5Portainer.server.schooltech.ch http://portainer:9000 redirect true false
ai.server.schooltech.ch http://open-webui:8080 redirect true false
whisper.server.schooltech.ch http://appServer_TunnelHead:11435 redirect true false
#RP3 ist Raspi für die Scara-Robots, per Tunnel angeschlossen. Er hat 81xx Ports am TunnelHead
rp3Portainer.server.schooltech.ch http://appServer_TunnelHead:8100 redirect true false
rp3Guac.server.schooltech.ch http://appServer_TunnelHead:8180 redirect true false
fluidncRed.server.schooltech.ch http://appServer_TunnelHead:8120 redirect true false
fluidncWhite.server.schooltech.ch https://appServer_TunnelHead:8104 redirect true false
# ThinkCentre ist ein MiniPC der neben dem einen Roboter steht. Hier sind die 97xx Ports zugewiesen
tcGuac.server.schooltech.ch http://appServer_TunnelHead:9780 redirect false false
tcPortainer.server.schooltech.ch http://appServer_TunnelHead:9703 redirect true false
tcSimulation.server.schooltech.ch https://appServer_TunnelHead:9712 redirect true false
#tcVideocontroller.server.schooltech.ch https://tcvideo:9443 redirect true false
robotHoming.server.schooltech.ch https://appServer_TunnelHead:9793 redirect true fals
#robotVideo.server.schooltech.ch https://appServer_TunnelHead:9743 redirect true false robotVideo.server.schooltech.ch 443 true
robotVideo.server.schooltech.ch http://thinkcentre.local:8444 redirect true false
tcControl.server.schooltech.ch https://appServer_TunnelHead:9710 redirect true false tcControl.server.schooltech.ch 443 true
nextcloud.server.schooltech.ch http://192.168.0.210:9183 redirect true false
robotBase.server.schooltech.ch https://appServer_TunnelHead:9725 redirect true false
robotEllbow.server.schooltech.ch https://appServer_TunnelHead:9726 redirect true false
robotHand.server.schooltech.ch https://appServer_TunnelHead:9727 redirect true false
robotDriver.server.schooltech.ch https://appServer_TunnelHead:9798 redirect true false robotDriver.server.schooltech.ch 443 true
robotVSCode.server.schooltech.ch http://appServer_TunnelHead:9744 redirect true false
overleaf.server.schooltech.ch http://thinkcentre.local:7070 redirect true false overleaf.server.schooltech.ch 443 true
# Gian Forrer hat einen MineCraft auf dem InformatikWeb
mineCraft24454.server.schooltech.ch https://appServer_TunnelHead:24454 redirect true false
mineCraft25565.server.schooltech.ch https://appServer_TunnelHead:25565 redirect true false
# Beispiel mit abweichendem Zertifikats-Ordner (Lineage-Suffix)
# tcGuac.server.schooltech.ch https://guac:8443 redirect true false server.schooltech.ch-0002
# Beispiel für WS auf port+1 (zwei Einträge, einer nur für WS-Endpunkt)
# wsApp.server.schooltech.ch https://wsapp:443 redirect true false