Przejdź do treści

Architektura

Przebieg działania

Domyślnie (lokalne tmux + tunel):

Kod
Browser (phone)
  |
  | HTTPS
  v
Cloudflare Quick Tunnel
  |
  | HTTP/WS
  v
Local Termbridge server
  |
  | PTY
  v
Tmux session

Tryb bezpośredni sandboxa (Daytona, bez tunelu):

Kod
Browser (phone)
  |
  | HTTPS
  v
Daytona preview link
  |
  | HTTP/WS
  v
Termbridge server (sandbox)
  |
  | PTY
  v
Tmux session (sandbox)

Gdy ustawiono --no-tunnel, Termbridge pomija Cloudflare i używa podanego przez Ciebie publicznego URL.

Komponenty

Proces CLI

  • Uruchamia serwer HTTP, który udostępnia zasoby UI.
  • Uruchamia serwer WebSocket do komunikacji z terminalem.
  • Tworzy jedną lub więcej sesji tmux (lub PTY Daytona).
  • Wydaje jednorazowe tokeny dostępu.
  • Uruchamia tunel i monitoruje go, gdy jest włączony (obecnie Cloudflare).
  • W trybie bezpośrednim sandboxa uruchamia Termbridge wewnątrz sandboxa i czeka na link URL.

Backend terminala

  • Backend tmux: używa node-pty, aby połączyć się z tmux i obsługiwać rzeczywiste naciśnięcia klawiszy oraz wyjście.
  • Backend Daytona: używa PTY Daytona wewnątrz sandboxa.
  • Ustawia TERM=xterm-256color i COLORTERM=truecolor, aby zapewnić pełną obsługę kolorów.
  • W przypadku tmux wyłącza pasek stanu tmux, aby zachować przejrzystość UI.

Rejestr terminali

  • Śledzi dostępne sesje terminala.
  • Udostępnia listę dla UI i sprawdza poprawność wybranych identyfikatorów terminali.

Uwierzytelnianie i sesja

  • Jednorazowy token jest wyświetlany jako URL i zakodowany w kodzie QR.
  • GET /__tb/s/:token wykorzystuje token i ustawia sesję cookie.
  • Połączenia WebSocket wymagają prawidłowego pliku cookie sesji i tokena CSRF.
  • Token CSRF jest pobierany przez GET /__tb/api/csrf i przekazywany w parametrze zapytania WebSocket.

Tryb proxy

Po przekazaniu --proxy <port>:

  • Wszystkie trasy termbridge są dostępne pod prefiksem /__tb/
  • Żądania niezwiązane z /__tb/ są przekazywane do aplikacji docelowej przez proxy
  • UI udostępnia widoki Terminal/Preview za pomocą przełącznika widoków
  • Widok Preview ładuje element iframe wskazujący na /
  • Połączenia WebSocket HMR są przekazywane do aplikacji docelowej

Bezpieczeństwo

  • Ochrona CSRF: aktualizacje połączenia WebSocket wymagają tokena CSRF, aby zapobiec przejęciu połączenia z innej witryny.
  • Limity danych wejściowych: treść żądania HTTP do 64 KB, wiadomość WebSocket do 1 MB, dane wejściowe terminala do 64 KB na wiadomość.
  • Ograniczanie liczby żądań: limity na wykorzystanie tokena i połączenia WebSocket dla każdego IP.

Punkty końcowe API

Wszystkie trasy znajdują się pod prefiksem /__tb/, aby uniknąć konfliktów z aplikacjami obsługiwanymi przez proxy:

  • GET /__tb/healthz — kontrola stanu
  • GET /__tb/s/:token — wykorzystanie tokena → cookie → przekierowanie
  • GET /__tb/api/terminals — lista terminali
  • GET /__tb/api/csrf — pobranie tokena CSRF dla WebSocket
  • GET /__tb/api/config — pobranie konfiguracji (proxyPort, devProxyUrl)
  • POST /__tb/api/terminals — utworzenie nowej sesji tmux
  • GET /__tb/app/* — zapasowa obsługa SPA
  • WS /__tb/ws/terminal/:terminalId?csrf=<token> — strumieniowanie komunikacji z terminalem

Gdy tryb proxy jest włączony:

  • GET / — przekierowuje do aplikacji obsługiwanej przez proxy (lub /__tb/app, jeśli jest wyłączony)
  • * /* — przekazywany przez proxy do aplikacji docelowej

Protokół WebSocket

Klient -> serwer:

JSON
{ "type": "input", "data": "ls -la" }
{ "type": "resize", "cols": 120, "rows": 32 }
{ "type": "control", "key": "ctrl_c" }

Serwer -> klient:

JSON
{ "type": "output", "data": "..." }
{ "type": "status", "state": "connected" }

Stos UI

  • Vite + TanStack Router
  • xterm.js + dodatek Fit + renderer WebGL
  • Układ z myślą przede wszystkim o urządzeniach mobilnych i ze stałym paskiem wprowadzania
  • Automatyczne ponowne łączenie z rosnącymi przerwami (do 10 prób)
  • Wskaźnik stanu połączenia