leonspahnweb
v1.0.0
Published
Tunnel-Client: macht einen lokalen Webserver über eine zentrale Proxy-Plattform öffentlich erreichbar.
Maintainers
Readme
@leonspahn/leonspahnweb
Tunnel-Client für die dezentrale Tunnel-Plattform. Macht einen lokal laufenden Webserver (Express, Next.js, Fastify, ...) über eine zentrale Proxy-Instanz öffentlich erreichbar – ohne Portfreigabe und ohne eigene öffentliche IP.
Browser ──HTTPS──▶ Plattform ──WSS-Tunnel──▶ leonspahnweb ──HTTP──▶ localhost:3000Der Tunnel wird ausgehend vom Admin-Server aufgebaut (WSS). Eingehende Firewall-Regeln sind nicht nötig.
Installation
npm install @leonspahn/leonspahnwebVoraussetzung: Node.js ≥ 18
Nutzung
const { connect } = require('@leonspahn/leonspahnweb');
const tunnel = connect({
domain: 'admin1.systemadmin', // Deine Kennung auf der Plattform
token: process.env.TUNNEL_TOKEN, // Auth-Token (nie hart codieren!)
localPort: 3000, // Port Deines lokalen Webservers
// serverUrl weggelassen -> Standard: ws://194.15.38.137:3001 (vorläufig, unverschlüsselt)
// Mit Domain + HTTPS später: serverUrl: 'wss://meine-plattform.de'
});
tunnel.on('connected', () => console.log('Tunnel verbunden'));
tunnel.on('ready', ({ url }) => console.log('Erreichbar unter:', url));
tunnel.on('disconnected', (code) => console.log('Getrennt:', code));
tunnel.on('error', (err) => console.error('Tunnel-Fehler:', err.message));
// Sauber beenden:
process.on('SIGINT', () => { tunnel.close(); process.exit(0); });Die Seite ist danach unter https://meine-plattform.de/admin1.systemadmin/
erreichbar. Die Plattform meldet die genaue URL per ready-Event.
Lokal testen (Server auf Port 3001)
# Terminal 1 – Server aus dem Paket leonspahnweb-server
npm install && npm start
# Terminal 2 – Demo-App (Port 3000) + Tunnel
npm install && node examples/demo.jsDer Client verbindet sich standardmäßig mit dem Server auf 194.15.38.137:3001.
Für einen rein lokalen Test: TUNNEL_SERVER_URL=ws://localhost:3001 node examples/demo.js
Danach im Browser: http://194.15.38.137:3001/admin1.systemadmin/ (lokal: http://localhost:3001/...)
Optionen
| Option | Typ | Standard | Beschreibung |
|---------------------|----------|---------------|------------------------------------------------------|
| domain | string | – (Pflicht) | Tunnel-Kennung, z. B. admin1.systemadmin |
| token | string | – (Pflicht) | Authentifizierungs-Token |
| localPort | number | – (Pflicht) | Port des lokalen Servers |
| serverUrl | string | ws://194.15.38.137:3001 (oder TUNNEL_SERVER_URL) | WebSocket-URL der Plattform; später wss:// |
| allowInsecure | boolean | false | erlaubt ws:// zu anderen Hosts (nur localhost und der Standard-Server sind ohnehin erlaubt) |
| localHost | string | 127.0.0.1 | Host des lokalen Servers |
| reconnectInterval | number | 5000 | Wartezeit (ms) bis zum nächsten Verbindungsversuch |
| requestTimeout | number | 30000 | Timeout (ms) für lokale Requests |
| maxBodyBytes | number | 52428800 | Maximale Größe einer lokalen Antwort (Bytes) |
| logger | object / false | console | Eigener Logger oder false zum Deaktivieren |
Verhalten
- Auto-Reconnect: Bricht die Verbindung ab, versucht der Client alle 5 Sekunden (konfigurierbar) sich neu zu verbinden.
- Heartbeat: Ping/Pong erkennt hängende Verbindungen und baut sie neu auf.
- Auth-Fehler (HTTP 401/403): Es wird nicht erneut versucht – prüfe dann
domainundtoken. - Verdrängt (Close-Code 4001): Verbindet sich eine zweite Instanz mit
derselben
domain, ersetzt der Server die alte. Diese verbindet sich dann nicht erneut (sonst würden sich beide endlos verdrängen) und meldet einenerror. - Lokaler Server down: Der Browser erhält
502 Bad Gateway, bei Zeitüberschreitung504 Gateway Timeout. - Sicherheit: Aktuell läuft der Tunnel vorläufig über die IP per
ws://– das Token wird dabei im Klartext übertragen (Warnung in der Konsole). Für den echten Betrieb Domain + HTTPS einrichten undwss://verwenden.ws://zu anderen Hosts alslocalhostund dem Standard-Server verlangtallowInsecure: true.
Hinweise
- Requests und Antworten werden vollständig gepuffert (kein Streaming); Server-Sent-Events und WebSocket-Upgrades werden nicht getunnelt.
- Das Token gehört in eine Umgebungsvariable oder einen Secret-Store.
Protokoll (für Plattform-Betreiber)
Alle Frames sind JSON-Textnachrichten. Bodies sind Base64-kodiert.
| Richtung | Frame |
|-------------------|----------------------------------------------------------------|
| Server → Client | { type: "request", requestId, method, path, headers, body } |
| Client → Server | { type: "response", requestId, status, headers, body } |
| Server → Client | { type: "ready", url? } (optional) |
Beim Handshake werden die Header x-tunnel-domain und x-tunnel-token
gesendet. Bei ungültigen Daten sollte der Server mit HTTP 401 oder 403
antworten.
Lizenz
MIT
