We use cookies to enhance your experience on the site
CodeWorlds
Back to collections
Guide17 min read

tunnl.gg - Expose localhost to the internet with a single SSH command

tunnl.gg is a free, open-source SSH tunneling tool that exposes local applications to the internet with a single command. No installation, no account, automatic SSL. Alternative to ngrok and localtunnel.

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-c8b5.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
WebSocketTakTakNieTak
Open sourceTak (MIT)NieTakNie
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-c8b5.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 i obsługuje wyzwania ACME (Let's Encrypt).

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

Code
YAML
services:
  tunnl:
    image: ghcr.io/klipitkas/tunnl.gg:latest
    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:/app/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-Ścieżka do certyfikatu TLS
TLS_KEY-Ś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 kompresja (~6MB)
make build-dev    # Szybka kompilacja z symbolami debugowania
make build-all    # Cross-platform (Linux, macOS, Windows)

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.

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.

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.

Podsumowanie

tunnl.gg to narzędzie, które robi jedną rzecz i robi ją doskonale. Jeśli potrzebujesz szybko wystawić lokalną aplikację w internet bez instalowania czegokolwiek, bez zakładania kont i bez konfiguracji - to idealne rozwiązanie. Jedna komenda SSH i masz publiczny URL z automatycznym HTTPS.

Dla bardziej zaawansowanych potrzeb (custom domeny, dashboard, analytics) ngrok lub Cloudflare Tunnel będą lepszym wyborem. Ale do szybkiego testowania, prezentacji i webhooków - tunnl.gg jest trudne do pobicia pod względem prostoty.


tunnl.gg - Expose local applications to the internet with a single SSH command

You're working on an app at localhost:3000 and suddenly need to show it to a client, test Stripe webhooks, or check how it works on a colleague's phone. What do you do? Deploy to staging? Set up ngrok with tokens and accounts? Or maybe just type a single SSH command and have a public URL in 2 seconds?

tunnl.gg is a minimalist SSH-based tunneling tool that does exactly one thing - and does it well. It exposes your local application to the internet without any installation, without creating an account, without configuring tokens. The only thing you need is SSH, which you already have on your machine.

What is tunnl.gg?

tunnl.gg is a free, open-source SSH tunneling service written in Go. It lets you expose any application running on localhost (or your local network) at a public HTTPS address with an automatic SSL certificate. The entire process comes down to a single command:

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

After running this command, you get a random subdomain, e.g., https://crisp-cedar-c8b5.tunnl.gg, where your local application is accessible from anywhere in the world.

The project was created by klipitkas and is available on GitHub under the MIT license.

Why tunnl.gg?

Zero installation, zero configuration

This is tunnl.gg's biggest advantage. You don't need to:

  • Install any client or CLI
  • Create an account
  • Generate API tokens
  • Configure anything

SSH is preinstalled on virtually every operating system - macOS, Linux, and even Windows 10+ has a built-in SSH client.

Comparison with alternatives

Featuretunnl.ggngroklocaltunnelCloudflare Tunnel
InstallationNo (SSH)Yes (CLI)Yes (npm)Yes (CLI)
AccountNoYesNoYes
Free planYes (100%)LimitedYesYes
HTTPSAutomaticAutomaticAutomaticAutomatic
Custom subdomainNoPaidOptionalYes
WebSocketYesYesNoYes
Open sourceYes (MIT)NoYesNo
Self-hostingYesNoYesNo

When to choose tunnl.gg?

tunnl.gg works perfectly when you:

  • Need to quickly show something to a client or colleague
  • Are testing webhooks (Stripe, GitHub, Slack)
  • Are debugging the mobile version of your app on a physical device
  • Are working on OAuth integration and need a public callback URL
  • Don't want to install yet another tool on your system

How to use tunnl.gg?

Basic usage

Exposing a local server on port 8080:

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

The -t flag is required - it allocates a pseudo-terminal (TTY), allowing the server to display your tunnel URL. After connecting, you'll see:

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

Exposing different ports

If your app runs on port 3000 (e.g., Next.js, React dev server):

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

App on port 5173 (Vite):

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

Exposing a remote host

You can also expose an application running on another machine in your local network:

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

Stable connection

For longer sessions, it's worth adding keep-alive so the SSH connection doesn't get interrupted:

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

Bypassing the warning page

tunnl.gg displays a warning page (interstitial) on the first browser visit - this is phishing protection. If you're using an API or curl, you can skip it:

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

Architecture and how it works

tunnl.gg consists of four main components:

1. SSH server (port 22)

Accepts SSH connections with the -R flag (remote port forwarding). It doesn't require authentication - this is an intentional design decision for a free service. For each connection:

  • Generates a memorable subdomain in adjective-noun-hex format (e.g., happy-tiger-a1b2c3d4)
  • Creates an internal TCP listener
  • Registers the tunnel in the central registry
  • Sends the URL to the client via the SSH channel

2. HTTP server (port 80)

Redirects all traffic to HTTPS and handles ACME challenges (Let's Encrypt).

3. HTTPS server (port 443)

Terminates TLS and proxies requests back through SSH tunnels to users' local applications.

4. Stats endpoint (port 9090)

Accessible only from localhost, provides metrics: active tunnels, unique IPs, total requests, blocked addresses.

Request flow

Code
TEXT
Browser → HTTPS (tunnl.gg) → TLS termination → SSH tunnel → localhost:port
  1. Browser sends a request to https://happy-tiger-a1b2c3d4.tunnl.gg
  2. HTTPS server terminates TLS
  3. Based on the subdomain, it finds the corresponding SSH tunnel
  4. Proxies the request through the SSH connection
  5. The request reaches your local application
  6. The response travels back the same way

Limits and restrictions

tunnl.gg has sensible limits to protect against abuse:

LimitValueDescription
Tunnels per IP3Maximum 3 simultaneous tunnels
Total tunnels1000Global server limit
Requests10/s (burst 20)Rate limiting per tunnel
Request body128 MBMaximum upload size
Response body128 MBMaximum download size
WebSocket1 GB/directionData limit per connection
Tunnel lifetime24hMaximum duration
Inactivity timeout2hAuto-close on no traffic
Connections/min per IP10Flood protection
IP block1hAbuse penalty

Technical limitations

  • Only supports HTTP/HTTPS traffic (no TCP/UDP)
  • No custom subdomains - always random
  • TLS is terminated server-side (server sees unencrypted traffic)
  • Single-server architecture (no scaling)
  • No tunnel authentication

Self-hosting

tunnl.gg is fully open-source and can be deployed on your own server. This is a great option if you:

  • Need control over your data
  • Want your own domain
  • Need higher limits

Requirements

  • Docker and Docker Compose
  • A domain with DNS A records (root and wildcard)
  • SSL certificate (Let's Encrypt)

DNS configuration

Add two A records pointing to your server's IP:

Code
TEXT
tunnl.yourdomain.com    →  SERVER_IP
*.tunnl.yourdomain.com  →  SERVER_IP

SSL certificate

Generate a wildcard certificate with Certbot:

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

Docker Compose

Code
YAML
services:
  tunnl:
    image: ghcr.io/klipitkas/tunnl.gg:latest
    ports:
      - "22:22"
      - "80:80"
      - "443:443"
    environment:
      - DOMAIN=tunnl.yourdomain.com
      - TLS_CERT=/certs/fullchain.pem
      - TLS_KEY=/certs/privkey.pem
    volumes:
      - ./data/certs:/certs:ro
      - ./data/host_key:/app/host_key
    restart: unless-stopped

Environment variables

VariableDefaultDescription
SSH_ADDR:22SSH server address
HTTP_ADDR:80HTTP server address
HTTPS_ADDR:443HTTPS server address
STATS_ADDR127.0.0.1:9090Metrics endpoint
HOST_KEY_PATHhost_keySSH host key path
TLS_CERT-TLS certificate path
TLS_KEY-TLS private key path
DOMAINtunnl.ggService domain

Building from source

The project requires Go 1.24+:

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

Available targets:

Code
Bash
make build        # Optimized version
make build-small  # Maximum compression (~6MB)
make build-dev    # Fast build with debug symbols
make build-all    # Cross-platform (Linux, macOS, Windows)

Security

Subdomain generation

tunnl.gg generates subdomains in the adjective-noun-hex8 format, yielding ~4.4 trillion possible combinations (32 adjectives x 32 nouns x 4 billion hex values). Enumeration is impractical.

Phishing protection

On the first browser visit, a warning page (interstitial) is displayed, informing the user that the content comes from a tunnel. After accepting, a cookie valid for 24 hours is set.

Security headers

Every response includes headers:

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

What to watch out for

  • No SSH authentication means anyone can create a tunnel
  • TLS terminated server-side - the operator can theoretically see the traffic
  • Don't use it for transmitting sensitive data through the public instance
  • Self-hosting solves these concerns

Practical use cases

Testing webhooks

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

Then in the Stripe dashboard, provide the URL: https://your-subdomain.tunnl.gg/api/webhooks/stripe

Client demo

Quick demo without deploying:

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

Send the URL to your client - it works on any device with a browser.

Testing on mobile devices

Instead of finding the IP on your local network:

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

Open the URL on your phone - HTTPS works out of the box.

Debugging OAuth integrations

Many OAuth providers require a public callback URL:

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

Set the callback URL in the provider's config to https://your-subdomain.tunnl.gg/auth/callback.

FAQ

Is tunnl.gg free?

Yes, 100%. There are no paid plans. The project is open-source under the MIT license.

Do I need an account?

No. There's no registration, login, tokens, or API keys.

Can I choose my own subdomain?

No, subdomains are randomly generated. If you need custom subdomains, consider ngrok or self-hosting with code modifications.

How long does a tunnel last?

Maximum 24 hours. After 2 hours of inactivity, the tunnel is automatically closed.

Does it support WebSocket?

Yes, with a 1 GB data limit in each direction and a 2-hour inactivity timeout.

Can I host it on my own server?

Yes, tunnl.gg is fully open-source. Self-hosting instructions can be found in the GitHub repository.

How does it differ from ngrok?

ngrok is a commercial tool with a rich feature set (dashboard, replay, custom domains). tunnl.gg is a minimalist, free alternative - zero installation, zero accounts, zero configuration.

Summary

tunnl.gg is a tool that does one thing and does it excellently. If you need to quickly expose a local application to the internet without installing anything, without creating accounts, and without configuration - it's the perfect solution. One SSH command and you have a public URL with automatic HTTPS.

For more advanced needs (custom domains, dashboard, analytics), ngrok or Cloudflare Tunnel will be a better choice. But for quick testing, demos, and webhooks - tunnl.gg is hard to beat in terms of simplicity.