Używamy cookies, żeby zwiększyć Twoje doświadczenia na stronie
CodeWorlds
Powrót do kolekcji
Przewodnik11 min czytania

tunnl.gg, tunel do localhosta jedną komendą

tunnl.gg wystawia lokalną aplikację w internet jedną komendą SSH, bez konta i bez instalacji. Limity, samodzielny hosting i porównanie z ngrok.

tunnl.gg - Wystawianie lokalnych aplikacji w internet jedną komendą SSH

Pracujesz nad aplikacją na localhost:3000 i nagle potrzebujesz pokazać ją klientowi, przetestować webhooki od Stripe'a albo sprawdzić jak działa na telefonie kolegi. Co robisz? Deployujesz na staging? Konfigurujesz ngrok z tokenami i kontami? A może po prostu wpisujesz jedną komendę SSH i masz publiczny URL w 2 sekundy?

tunnl.gg to minimalistyczne narzędzie tunelujące oparte na SSH, które robi dokładnie jedną rzecz - i robi ją dobrze. Wystawia twoją lokalną aplikację w internet bez żadnej instalacji, bez zakładania konta, bez konfiguracji tokenów. Jedyne czego potrzebujesz to SSH, który i tak masz na swoim komputerze.

Czym jest tunnl.gg?

tunnl.gg to darmowa, open-source usługa tunelowania SSH napisana w Go. Pozwala wystawić dowolną aplikację działającą na localhost (lub w sieci lokalnej) pod publicznym adresem HTTPS z automatycznym certyfikatem SSL. Cały proces sprowadza się do jednej komendy:

Code
Bash
ssh -t -R 80:localhost:8080 proxy.tunnl.gg

Po wykonaniu tej komendy dostajesz losową subdomenę, np. https://crisp-cedar-c8b5a1d2.tunnl.gg, pod którą twoja lokalna aplikacja jest dostępna z całego świata.

Projekt został stworzony przez klipitkas i jest dostępny na GitHubie pod licencją MIT.

Dlaczego tunnl.gg?

Zero instalacji, zero konfiguracji

To największa zaleta tunnl.gg. Nie musisz:

  • Instalować żadnego klienta ani CLI
  • Zakładać konta
  • Generować tokenów API
  • Konfigurować czegokolwiek

SSH jest preinstalowany na praktycznie każdym systemie operacyjnym - macOS, Linux, a nawet Windows 10+ ma wbudowany klient SSH.

Porównanie z alternatywami

Cechatunnl.ggngroklocaltunnelCloudflare Tunnel
InstalacjaNie (SSH)Tak (CLI)Tak (npm)Tak (CLI)
KontoNieTakNieTak
Darmowy planTak (100%)OgraniczonyTakTak
HTTPSAutomatycznyAutomatycznyAutomatycznyAutomatyczny
Custom subdomenaNiePłatneOpcjonalnieTak
WebSocketTakTakTakTak
Open sourceTak (MIT)NieTakKlient (Apache 2.0)
Self-hostingTakNieTakNie

Kiedy wybrać tunnl.gg?

tunnl.gg sprawdza się idealnie gdy:

  • Potrzebujesz szybko pokazać coś klientowi lub współpracownikowi
  • Testujesz webhooki (Stripe, GitHub, Slack)
  • Debugujesz mobilną wersję aplikacji na fizycznym urządzeniu
  • Pracujesz nad integracją OAuth i potrzebujesz publicznego callback URL
  • Nie chcesz instalować kolejnego narzędzia w systemie

Jak korzystać z tunnl.gg?

Podstawowe użycie

Wystawienie lokalnego serwera na porcie 8080:

Code
Bash
ssh -t -R 80:localhost:8080 proxy.tunnl.gg

Flaga -t jest obowiązkowa - alokuje pseudo-terminal (TTY), dzięki czemu serwer może wyświetlić URL twojego tunelu. Po połączeniu zobaczysz:

Code
TEXT
Tunnel established!
https://crisp-cedar-c8b5a1d2.tunnl.gg

Wystawianie różnych portów

Jeśli twoja aplikacja działa na porcie 3000 (np. Next.js, React dev server):

Code
Bash
ssh -t -R 80:localhost:3000 proxy.tunnl.gg

Aplikacja na porcie 5173 (Vite):

Code
Bash
ssh -t -R 80:localhost:5173 proxy.tunnl.gg

Wystawianie zdalnego hosta

Możesz też wystawić aplikację działającą na innej maszynie w sieci lokalnej:

Code
Bash
ssh -t -R 80:192.168.1.100:3000 proxy.tunnl.gg

Stabilne połączenie

Dla dłuższych sesji warto dodać keep-alive, żeby połączenie SSH nie zostało przerwane:

Code
Bash
ssh -t -R 80:localhost:8080 -o ServerAliveInterval=60 proxy.tunnl.gg

Pomijanie strony ostrzegawczej

tunnl.gg wyświetla stronę ostrzegawczą (interstitial) przy pierwszym wejściu z przeglądarki - to ochrona przed phishingiem. Jeśli korzystasz z API lub curl, możesz ją pominąć:

Code
Bash
curl -H "tunnl-skip-browser-warning: 1" https://subdomain.tunnl.gg

Architektura i działanie

tunnl.gg składa się z czterech głównych komponentów:

1. Serwer SSH (port 22)

Przyjmuje połączenia SSH z flagą -R (remote port forwarding). Nie wymaga autentykacji - to celowa decyzja projektowa dla darmowej usługi. Przy każdym połączeniu:

  • Generuje zapamiętywalna subdomenę w formacie przymiotnik-rzeczownik-hex (np. happy-tiger-a1b2c3d4)
  • Tworzy wewnętrzny listener TCP
  • Rejestruje tunel w centralnym rejestrze
  • Wysyła URL do klienta przez kanał SSH

2. Serwer HTTP (port 80)

Przekierowuje cały ruch na HTTPS odpowiedzią 301. Certyfikatów sam nie wystawia: trzeba je przygotować wcześniej, na przykład Certbotem, bo wbudowanej obsługi ACME w kodzie nie ma.

3. Serwer HTTPS (port 443)

Terminuje TLS i proxy'uje żądania z powrotem przez tunele SSH do lokalnych aplikacji użytkowników.

4. Endpoint statystyk (port 9090)

Dostępny tylko z localhost, udostępnia metryki: aktywne tunele, unikalne IP, łączne żądania, zablokowane adresy.

Przepływ żądania

Code
TEXT
Przeglądarka → HTTPS (tunnl.gg) → TLS termination → SSH tunnel → localhost:port
  1. Przeglądarka wysyła żądanie do https://happy-tiger-a1b2c3d4.tunnl.gg
  2. Serwer HTTPS terminuje TLS
  3. Na podstawie subdomeny znajduje odpowiedni tunel SSH
  4. Proxy'uje żądanie przez połączenie SSH
  5. Żądanie dociera do twojej lokalnej aplikacji
  6. Odpowiedź wraca tą samą drogą

Limity i ograniczenia

tunnl.gg ma sensowne limity zabezpieczające przed nadużyciami:

LimitWartośćOpis
Tunele na IP3Maksymalnie 3 jednoczesne tunele
Łącznie tuneli1000Limit globalny serwera
Żądania10/s (burst 20)Rate limiting per tunel
Body żądania128 MBMaksymalny rozmiar uploadu
Body odpowiedzi128 MBMaksymalny rozmiar downloadu
WebSocket1 GB/kierunekLimit danych per połączenie
Czas życia tunelu24hMaksymalny czas trwania
Timeout bezczynności2hAutomatyczne zamknięcie przy braku ruchu
Połączenia/min na IP10Ochrona przed flood
Blokada IP1hKara za nadużycia

Ograniczenia techniczne

  • Obsługuje tylko ruch HTTP/HTTPS (brak TCP/UDP)
  • Brak custom subdomen - zawsze losowe
  • TLS jest terminowany po stronie serwera (serwer widzi ruch w postaci niezaszyfrowanej)
  • Architektura single-server (brak skalowania)
  • Brak autentykacji tuneli

Self-hosting

tunnl.gg jest w pełni open-source i można go postawić na własnym serwerze. To świetna opcja jeśli:

  • Potrzebujesz kontroli nad danymi
  • Chcesz własną domenę
  • Potrzebujesz większych limitów

Wymagania

  • Docker i Docker Compose
  • Domena z rekordami DNS A (root i wildcard)
  • Certyfikat SSL (Let's Encrypt)

Konfiguracja DNS

Dodaj dwa rekordy A wskazujące na IP twojego serwera:

Code
TEXT
tunnl.twojadomena.com    →  IP_SERWERA
*.tunnl.twojadomena.com  →  IP_SERWERA

Certyfikat SSL

Wygeneruj certyfikat wildcard za pomocą Certbot:

Code
Bash
certbot certonly --manual --preferred-challenges dns \
  -d "tunnl.twojadomena.com" \
  -d "*.tunnl.twojadomena.com"

Docker Compose

Gotowego obrazu w żadnym rejestrze nie ma, więc buduje się go z sklonowanego repozytorium:

Code
YAML
services:
  tunnl:
    build: .
    ports:
      - "22:22"
      - "80:80"
      - "443:443"
    environment:
      - DOMAIN=tunnl.twojadomena.com
      - TLS_CERT=/certs/fullchain.pem
      - TLS_KEY=/certs/privkey.pem
    volumes:
      - ./data/certs:/certs:ro
      - ./data/host_key:/host_key
    restart: unless-stopped

Zmienne środowiskowe

ZmiennaDomyślna wartośćOpis
SSH_ADDR:22Adres serwera SSH
HTTP_ADDR:80Adres serwera HTTP
HTTPS_ADDR:443Adres serwera HTTPS
STATS_ADDR127.0.0.1:9090Endpoint metryk
HOST_KEY_PATHhost_keyŚcieżka do klucza hosta SSH
TLS_CERT/etc/letsencrypt/live/tunnl.gg/fullchain.pemŚcieżka do certyfikatu TLS
TLS_KEY/etc/letsencrypt/live/tunnl.gg/privkey.pemŚcieżka do klucza prywatnego TLS
DOMAINtunnl.ggDomena usługi

Budowanie ze źródeł

Projekt wymaga Go 1.24+:

Code
Bash
git clone https://github.com/klipitkas/tunnl.gg.git
cd tunnl.gg
make build

Dostępne targety:

Code
Bash
make build        # Zoptymalizowana wersja
make build-small  # Maksymalna optymalizacja rozmiaru (~6 MB)
make build-tiny   # To samo plus pakowanie upx-em, jeśli upx jest zainstalowany
make build-dev    # Szybka kompilacja z symbolami debugowania
make build-all    # Linux i macOS, po dwie architektury (bez Windowsa)

Bezpieczeństwo

Generowanie subdomen

tunnl.gg generuje subdomeny w formacie przymiotnik-rzeczownik-hex8, co daje ~4.4 biliona możliwych kombinacji (32 przymiotniki × 32 rzeczowniki × 4 miliardy wartości hex). Enumeracja jest niepraktyczna.

Ochrona przed phishingiem

Przy pierwszym wejściu z przeglądarki wyświetlana jest strona ostrzegawcza (interstitial), informująca że treść pochodzi z tunelu. Po zaakceptowaniu ustawiany jest cookie ważny 24 godziny.

Nagłówki bezpieczeństwa

Każda odpowiedź zawiera nagłówki:

  • X-Content-Type-Options: nosniff
  • X-Frame-Options: DENY
  • X-XSS-Protection: 1; mode=block
  • Referrer-Policy: strict-origin-when-cross-origin

Na co uważać

  • Brak autentykacji SSH oznacza, że każdy może utworzyć tunel
  • TLS terminowany po stronie serwera - operator może teoretycznie widzieć ruch
  • Nie używaj do przesyłania wrażliwych danych przez publiczną instancję
  • Self-hosting rozwiązuje te problemy

Praktyczne scenariusze użycia

Testowanie webhooków

Code
Bash
ssh -t -R 80:localhost:3000 proxy.tunnl.gg

Następnie w panelu Stripe podaj URL: https://twoja-subdomena.tunnl.gg/api/webhooks/stripe

Prezentacja dla klienta

Szybkie demo bez deployu:

Code
Bash
ssh -t -R 80:localhost:3000 -o ServerAliveInterval=60 proxy.tunnl.gg

Wyślij URL klientowi - działa na każdym urządzeniu z przeglądarką.

Testowanie na urządzeniach mobilnych

Zamiast szukać IP w sieci lokalnej:

Code
Bash
ssh -t -R 80:localhost:5173 proxy.tunnl.gg

Otwórz URL na telefonie - HTTPS działa out of the box.

Dla telefonu podpiętego do tej samej sieci Wi-Fi to jest jednak rozwiązanie na wyrost, bo aplikacja idzie wtedy przez publiczny internet tylko po to, żeby wrócić do urządzenia stojącego obok. Portless załatwia ten sam problem bez wychodzenia poza sieć lokalną, podstawiając nazwany adres w miejsce szukania IP komputera. Tunel wygrywa dopiero wtedy, gdy telefon jest w innej sieci albo trzyma go ktoś inny.

Debugowanie integracji OAuth

Wiele providerów OAuth wymaga publicznego callback URL:

Code
Bash
ssh -t -R 80:localhost:3000 proxy.tunnl.gg

Ustaw callback URL w konfiguracji providera na https://twoja-subdomena.tunnl.gg/auth/callback.

Czego tunel nie zastąpi

Warto nazwać granicę, bo tunel bywa używany do rzeczy, do których się nie nadaje, i kończy się to zawsze podobnie.

Tunel nie jest środowiskiem testowym. Działa dopóki Twój laptop jest włączony, podłączony do sieci i ma otwartą sesję, a maksymalnie dwadzieścia cztery godziny. Klient, który dostał odnośnik w piątek po południu i otworzył go w poniedziałek, zobaczy błąd. Do czegoś, co ma stać przez tydzień, potrzebujesz podglądu wdrożenia na Vercelu albo Railway, gdzie każda gałąź dostaje własny adres i nie zależy od Twojego sprzętu.

Tunel nie jest też sposobem na wystawienie usługi na stałe. Brak uwierzytelniania po stronie SSH oznacza, że każdy może utworzyć tunel na publicznej instancji, a losowa subdomena jest jedyną barierą przed dostępem do tego, co wystawiłeś. To ochrona przez nieodgadnięcie adresu, a nie kontrola dostępu. Jeśli za tunelem stoi panel administracyjny bez logowania, wystawiłeś go światu.

Trzecia granica dotyczy szyfrowania. Ruch jest zaszyfrowany między przeglądarką a serwerem usługi oraz między serwerem a Twoim komputerem, natomiast na serwerze pośrednim jest odszyfrowany. Operator publicznej instancji może technicznie zobaczyć jego treść. Do demonstracji to nie ma znaczenia, do danych osobowych klienta ma i wtedy właściwą odpowiedzią jest własna instancja albo tunel Cloudflare z uwierzytelnianiem.

Praktyczna reguła brzmi tak: tunel do tego, co trwa godziny i co możesz pokazać obcej osobie bez konsekwencji. Wszystko poza tym zasługuje na prawdziwe wdrożenie.

Kilka rzeczy, które oszczędzają czas

Nagłówek Host przychodzi z domeny tunelu, nie z Twojego localhosta. Część frameworków odrzuca takie żądania jako niedozwolone, więc jeśli widzisz błąd o nieprawidłowym nagłówku zamiast swojej aplikacji, dodaj domenę do listy dozwolonych hostów w konfiguracji serwera rozwojowego.

Odświeżanie modułów w locie działa przez ten sam tunel, ale klient próbuje łączyć się z adresem, który zna z konfiguracji budowania. Gdy podgląd na telefonie ładuje się raz i przestaje reagować na zmiany, to zwykle ten problem, a nie usterka tunelu.

Adresy bezwzględne w kodzie psują się natychmiast. Wszystko, co ma na sztywno wpisane http://localhost:3000, po drugiej stronie tunelu wskazuje na komputer odbiorcy. Ścieżki względne rozwiązują to bez żadnej konfiguracji.

Przy testowaniu webhooków pamiętaj, że po ponownym połączeniu dostajesz nową subdomenę i adres w panelu dostawcy przestaje być aktualny. Przy dłuższej pracy nad integracją to argument za własną instancją ze stałą domeną.

Warto też sprawdzić, jak Twoja aplikacja zachowuje się przy wolniejszym łączu. Ruch przechodzi przez serwer pośredni, więc opóźnienie jest zauważalnie większe niż przy wejściu na localhost, a to bywa jedyna okazja, żeby zobaczyć własny interfejs w warunkach zbliżonych do tego, co widzi użytkownik na telefonie w terenie.

FAQ

Czy tunnl.gg jest darmowe?

Tak, w 100%. Nie ma żadnych płatnych planów. Projekt jest open-source pod licencją MIT.

Czy potrzebuję konta?

Nie. Nie ma rejestracji, logowania, tokenów ani kluczy API.

Czy mogę wybrać swoją subdomenę?

Nie, subdomeny są generowane losowo. Jeśli potrzebujesz custom subdomen, rozważ ngrok lub self-hosting z modyfikacją kodu.

Jak długo działa tunel?

Maksymalnie 24 godziny. Po 2 godzinach bezczynności tunel jest zamykany automatycznie.

Czy obsługuje WebSocket?

Tak, z limitem 1 GB danych w każdym kierunku i 2-godzinnym timeoutem bezczynności.

Czy mogę go postawić na własnym serwerze?

Tak, tunnl.gg jest w pełni open-source. Instrukcje self-hostingu znajdziesz w repozytorium na GitHubie.

Czym się różni od ngrok?

ngrok to komercyjne narzędzie z bogatym zestawem funkcji (dashboard, replay, custom domeny). tunnl.gg to minimalistyczna, darmowa alternatywa - zero instalacji, zero kont, zero konfiguracji.

Kiedy sięgnąć po coś innego

Przy potrzebie stałej subdomeny, panelu z podglądem żądań i możliwością ich powtórzenia, ngrok daje więcej i przy intensywnej pracy nad integracjami ta różnica się broni. Przy usłudze, która ma stać na dłużej i mieć kontrolę dostępu, właściwym wyborem jest tunel od dostawcy sieci dostarczania treści. A przy czymś, co ma po prostu działać bez Twojego komputera, żaden tunel nie jest odpowiedzią, tylko wdrożenie.

Kod źródłowy i instrukcje samodzielnego uruchomienia stoją w repozytorium projektu, a opis architektury w osobnym dokumencie.