dev.toppyr.de — Reverse-Tunnel zu Mac mini für Dev-Zugang #1

Closed
opened 2026-03-31 00:40:28 +02:00 by tobias · 1 comment
Owner

Beschreibung

Temporärer sicherer Zugang zu Dev-Servern auf dem Mac mini über dev.toppyr.de. Kein offener Port am Mac mini nötig.

Architektur

Browser → dev.toppyr.de → Traefik (VServer) → SSH-Tunnel → Mac mini:PORT

Umsetzung

1. SSH Reverse Tunnel (Mac mini → VServer)

# Mac mini öffnet Tunnel zum VServer
ssh -N -R 9080:localhost:8781 dotty@152.53.119.77

Der VServer lauscht dann auf localhost:9080 und leitet zum Mac mini weiter.

2. Traefik-Konfiguration (VServer)

Neuer Service in docker-compose.yml oder dynamische Traefik-Config:

# File Provider: /opt/collaboration/traefik/dynamic/dev-tunnel.yml
http:
  routers:
    dev-tunnel:
      rule: "Host(`dev.toppyr.de`)"
      entryPoints:
        - websecure
      tls:
        certResolver: letsencrypt
      service: dev-tunnel
      middlewares:
        - dev-auth
  
  services:
    dev-tunnel:
      loadBalancer:
        servers:
          - url: "http://host.docker.internal:9080"
  
  middlewares:
    dev-auth:
      basicAuth:
        users:
          - "tobias:$apr1$...$..."  # htpasswd generiert

Oder Keycloak Forward-Auth statt Basic-Auth (wie bei den anderen Services).

3. DNS

dev.toppyr.de → A-Record auf VServer (152.53.119.77)

4. Tunnel persistent machen (optional)

# autossh für automatischen Reconnect
autossh -M 0 -N -R 9080:localhost:8781 \
  -o "ServerAliveInterval 30" \
  -o "ServerAliveCountMax 3" \
  dotty@152.53.119.77

Oder als LaunchAgent auf dem Mac mini.

Sicherheit

  • Kein offener Port am Mac mini
  • Verschlüsselt (SSH + HTTPS)
  • Auth-Layer vor Traefik (Basic-Auth oder Keycloak SSO)
  • Jederzeit abschaltbar (Tunnel beenden)
  • Kein Wildcard — nur explizit dev.toppyr.de
  • ⚠️ Tunnel muss aktiv sein, sonst 502

Variablen Port

Der Tunnel-Port (9080) und der Ziel-Port am Mac mini (8781) sollten per ENV konfigurierbar sein, damit verschiedene Dev-Server durchgeschaltet werden können.

Alternativen (verworfen)

Option Warum nicht
Cloudflare Tunnel Extra Dependency, DNS muss bei Cloudflare liegen
Tailscale Guter Ansatz, aber kein Browser-Zugang ohne Client
Port-Forwarding Router Sicherheitsalptraum, feste IP nötig
ngrok Drittanbieter, Daten fließen über deren Server
## Beschreibung Temporärer sicherer Zugang zu Dev-Servern auf dem Mac mini über `dev.toppyr.de`. Kein offener Port am Mac mini nötig. ## Architektur ``` Browser → dev.toppyr.de → Traefik (VServer) → SSH-Tunnel → Mac mini:PORT ``` ## Umsetzung ### 1. SSH Reverse Tunnel (Mac mini → VServer) ```bash # Mac mini öffnet Tunnel zum VServer ssh -N -R 9080:localhost:8781 dotty@152.53.119.77 ``` Der VServer lauscht dann auf `localhost:9080` und leitet zum Mac mini weiter. ### 2. Traefik-Konfiguration (VServer) Neuer Service in `docker-compose.yml` oder dynamische Traefik-Config: ```yaml # File Provider: /opt/collaboration/traefik/dynamic/dev-tunnel.yml http: routers: dev-tunnel: rule: "Host(`dev.toppyr.de`)" entryPoints: - websecure tls: certResolver: letsencrypt service: dev-tunnel middlewares: - dev-auth services: dev-tunnel: loadBalancer: servers: - url: "http://host.docker.internal:9080" middlewares: dev-auth: basicAuth: users: - "tobias:$apr1$...$..." # htpasswd generiert ``` **Oder** Keycloak Forward-Auth statt Basic-Auth (wie bei den anderen Services). ### 3. DNS `dev.toppyr.de` → A-Record auf VServer (152.53.119.77) ### 4. Tunnel persistent machen (optional) ```bash # autossh für automatischen Reconnect autossh -M 0 -N -R 9080:localhost:8781 \ -o "ServerAliveInterval 30" \ -o "ServerAliveCountMax 3" \ dotty@152.53.119.77 ``` Oder als LaunchAgent auf dem Mac mini. ## Sicherheit - ✅ Kein offener Port am Mac mini - ✅ Verschlüsselt (SSH + HTTPS) - ✅ Auth-Layer vor Traefik (Basic-Auth oder Keycloak SSO) - ✅ Jederzeit abschaltbar (Tunnel beenden) - ✅ Kein Wildcard — nur explizit `dev.toppyr.de` - ⚠️ Tunnel muss aktiv sein, sonst 502 ## Variablen Port Der Tunnel-Port (9080) und der Ziel-Port am Mac mini (8781) sollten per ENV konfigurierbar sein, damit verschiedene Dev-Server durchgeschaltet werden können. ## Alternativen (verworfen) | Option | Warum nicht | |--------|-------------| | Cloudflare Tunnel | Extra Dependency, DNS muss bei Cloudflare liegen | | Tailscale | Guter Ansatz, aber kein Browser-Zugang ohne Client | | Port-Forwarding Router | Sicherheitsalptraum, feste IP nötig | | ngrok | Drittanbieter, Daten fließen über deren Server |
Author
Owner

Erledigt (31.03.2026)

Umsetzung

  • SSH Reverse Tunnel: Mac mini → VServer (ssh -N -R 0.0.0.0:9080:localhost:PORT vserver)
  • socat Container: dev-tunnel im Docker-Compose, leitet von Docker-Netzwerk an Host-Port 9080
  • GatewayPorts: yes in /etc/ssh/sshd_config (nötig damit Docker-Container den Tunnel erreichen)
  • Vite Proxy: /api Requests werden serverseitig an Backend durchgeleitet
  • Vite allowedHosts: dev.toppyr.de explizit erlaubt (sonst 403)

Zugang

  • URL: https://dev.toppyr.de
  • Auth: Keycloak SSO (siehe #7)
  • Tunnel starten: Dotty macht das automatisch wenn Dev-Zugang gebraucht wird

Konfigurationsdateien

  • VServer: /opt/collaboration/docker-compose.yml (dev-tunnel + dev-forward-auth Services)
  • Mac mini: antragsideen-app/frontend/vite.config.js (allowedHosts + proxy)
  • SSH: /etc/ssh/sshd_configGatewayPorts yes
## Erledigt (31.03.2026) ### Umsetzung - **SSH Reverse Tunnel:** Mac mini → VServer (`ssh -N -R 0.0.0.0:9080:localhost:PORT vserver`) - **socat Container:** `dev-tunnel` im Docker-Compose, leitet von Docker-Netzwerk an Host-Port 9080 - **GatewayPorts:** `yes` in `/etc/ssh/sshd_config` (nötig damit Docker-Container den Tunnel erreichen) - **Vite Proxy:** `/api` Requests werden serverseitig an Backend durchgeleitet - **Vite allowedHosts:** `dev.toppyr.de` explizit erlaubt (sonst 403) ### Zugang - **URL:** https://dev.toppyr.de - **Auth:** Keycloak SSO (siehe #7) - **Tunnel starten:** Dotty macht das automatisch wenn Dev-Zugang gebraucht wird ### Konfigurationsdateien - VServer: `/opt/collaboration/docker-compose.yml` (dev-tunnel + dev-forward-auth Services) - Mac mini: `antragsideen-app/frontend/vite.config.js` (allowedHosts + proxy) - SSH: `/etc/ssh/sshd_config` → `GatewayPorts yes`
Sign in to join this conversation.
No Label
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: tobias/toppyr-stack#1
No description provided.