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:
ssh -t -R 80:localhost:8080 proxy.tunnl.ggPo 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
| Cecha | tunnl.gg | ngrok | localtunnel | Cloudflare Tunnel |
|---|---|---|---|---|
| Instalacja | Nie (SSH) | Tak (CLI) | Tak (npm) | Tak (CLI) |
| Konto | Nie | Tak | Nie | Tak |
| Darmowy plan | Tak (100%) | Ograniczony | Tak | Tak |
| HTTPS | Automatyczny | Automatyczny | Automatyczny | Automatyczny |
| Custom subdomena | Nie | Płatne | Opcjonalnie | Tak |
| WebSocket | Tak | Tak | Nie | Tak |
| Open source | Tak (MIT) | Nie | Tak | Nie |
| Self-hosting | Tak | Nie | Tak | Nie |
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:
ssh -t -R 80:localhost:8080 proxy.tunnl.ggFlaga -t jest obowiązkowa - alokuje pseudo-terminal (TTY), dzięki czemu serwer może wyświetlić URL twojego tunelu. Po połączeniu zobaczysz:
Tunnel established!
https://crisp-cedar-c8b5.tunnl.ggWystawianie różnych portów
Jeśli twoja aplikacja działa na porcie 3000 (np. Next.js, React dev server):
ssh -t -R 80:localhost:3000 proxy.tunnl.ggAplikacja na porcie 5173 (Vite):
ssh -t -R 80:localhost:5173 proxy.tunnl.ggWystawianie zdalnego hosta
Możesz też wystawić aplikację działającą na innej maszynie w sieci lokalnej:
ssh -t -R 80:192.168.1.100:3000 proxy.tunnl.ggStabilne połączenie
Dla dłuższych sesji warto dodać keep-alive, żeby połączenie SSH nie zostało przerwane:
ssh -t -R 80:localhost:8080 -o ServerAliveInterval=60 proxy.tunnl.ggPomijanie 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ąć:
curl -H "tunnl-skip-browser-warning: 1" https://subdomain.tunnl.ggArchitektura 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
Przeglądarka → HTTPS (tunnl.gg) → TLS termination → SSH tunnel → localhost:port- Przeglądarka wysyła żądanie do
https://happy-tiger-a1b2c3d4.tunnl.gg - Serwer HTTPS terminuje TLS
- Na podstawie subdomeny znajduje odpowiedni tunel SSH
- Proxy'uje żądanie przez połączenie SSH
- Żądanie dociera do twojej lokalnej aplikacji
- Odpowiedź wraca tą samą drogą
Limity i ograniczenia
tunnl.gg ma sensowne limity zabezpieczające przed nadużyciami:
| Limit | Wartość | Opis |
|---|---|---|
| Tunele na IP | 3 | Maksymalnie 3 jednoczesne tunele |
| Łącznie tuneli | 1000 | Limit globalny serwera |
| Żądania | 10/s (burst 20) | Rate limiting per tunel |
| Body żądania | 128 MB | Maksymalny rozmiar uploadu |
| Body odpowiedzi | 128 MB | Maksymalny rozmiar downloadu |
| WebSocket | 1 GB/kierunek | Limit danych per połączenie |
| Czas życia tunelu | 24h | Maksymalny czas trwania |
| Timeout bezczynności | 2h | Automatyczne zamknięcie przy braku ruchu |
| Połączenia/min na IP | 10 | Ochrona przed flood |
| Blokada IP | 1h | Kara 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:
tunnl.twojadomena.com → IP_SERWERA
*.tunnl.twojadomena.com → IP_SERWERACertyfikat SSL
Wygeneruj certyfikat wildcard za pomocą Certbot:
certbot certonly --manual --preferred-challenges dns \
-d "tunnl.twojadomena.com" \
-d "*.tunnl.twojadomena.com"Docker Compose
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-stoppedZmienne środowiskowe
| Zmienna | Domyślna wartość | Opis |
|---|---|---|
| SSH_ADDR | :22 | Adres serwera SSH |
| HTTP_ADDR | :80 | Adres serwera HTTP |
| HTTPS_ADDR | :443 | Adres serwera HTTPS |
| STATS_ADDR | 127.0.0.1:9090 | Endpoint metryk |
| HOST_KEY_PATH | host_key | Ścieżka do klucza hosta SSH |
| TLS_CERT | - | Ścieżka do certyfikatu TLS |
| TLS_KEY | - | Ścieżka do klucza prywatnego TLS |
| DOMAIN | tunnl.gg | Domena usługi |
Budowanie ze źródeł
Projekt wymaga Go 1.24+:
git clone https://github.com/klipitkas/tunnl.gg.git
cd tunnl.gg
make buildDostępne targety:
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: nosniffX-Frame-Options: DENYX-XSS-Protection: 1; mode=blockReferrer-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
ssh -t -R 80:localhost:3000 proxy.tunnl.ggNastępnie w panelu Stripe podaj URL: https://twoja-subdomena.tunnl.gg/api/webhooks/stripe
Prezentacja dla klienta
Szybkie demo bez deployu:
ssh -t -R 80:localhost:3000 -o ServerAliveInterval=60 proxy.tunnl.ggWyślij URL klientowi - działa na każdym urządzeniu z przeglądarką.
Testowanie na urządzeniach mobilnych
Zamiast szukać IP w sieci lokalnej:
ssh -t -R 80:localhost:5173 proxy.tunnl.ggOtwórz URL na telefonie - HTTPS działa out of the box.
Debugowanie integracji OAuth
Wiele providerów OAuth wymaga publicznego callback URL:
ssh -t -R 80:localhost:3000 proxy.tunnl.ggUstaw 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:
ssh -t -R 80:localhost:8080 proxy.tunnl.ggAfter 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
| Feature | tunnl.gg | ngrok | localtunnel | Cloudflare Tunnel |
|---|---|---|---|---|
| Installation | No (SSH) | Yes (CLI) | Yes (npm) | Yes (CLI) |
| Account | No | Yes | No | Yes |
| Free plan | Yes (100%) | Limited | Yes | Yes |
| HTTPS | Automatic | Automatic | Automatic | Automatic |
| Custom subdomain | No | Paid | Optional | Yes |
| WebSocket | Yes | Yes | No | Yes |
| Open source | Yes (MIT) | No | Yes | No |
| Self-hosting | Yes | No | Yes | No |
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:
ssh -t -R 80:localhost:8080 proxy.tunnl.ggThe -t flag is required - it allocates a pseudo-terminal (TTY), allowing the server to display your tunnel URL. After connecting, you'll see:
Tunnel established!
https://crisp-cedar-c8b5.tunnl.ggExposing different ports
If your app runs on port 3000 (e.g., Next.js, React dev server):
ssh -t -R 80:localhost:3000 proxy.tunnl.ggApp on port 5173 (Vite):
ssh -t -R 80:localhost:5173 proxy.tunnl.ggExposing a remote host
You can also expose an application running on another machine in your local network:
ssh -t -R 80:192.168.1.100:3000 proxy.tunnl.ggStable connection
For longer sessions, it's worth adding keep-alive so the SSH connection doesn't get interrupted:
ssh -t -R 80:localhost:8080 -o ServerAliveInterval=60 proxy.tunnl.ggBypassing 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:
curl -H "tunnl-skip-browser-warning: 1" https://subdomain.tunnl.ggArchitecture 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-hexformat (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
Browser → HTTPS (tunnl.gg) → TLS termination → SSH tunnel → localhost:port- Browser sends a request to
https://happy-tiger-a1b2c3d4.tunnl.gg - HTTPS server terminates TLS
- Based on the subdomain, it finds the corresponding SSH tunnel
- Proxies the request through the SSH connection
- The request reaches your local application
- The response travels back the same way
Limits and restrictions
tunnl.gg has sensible limits to protect against abuse:
| Limit | Value | Description |
|---|---|---|
| Tunnels per IP | 3 | Maximum 3 simultaneous tunnels |
| Total tunnels | 1000 | Global server limit |
| Requests | 10/s (burst 20) | Rate limiting per tunnel |
| Request body | 128 MB | Maximum upload size |
| Response body | 128 MB | Maximum download size |
| WebSocket | 1 GB/direction | Data limit per connection |
| Tunnel lifetime | 24h | Maximum duration |
| Inactivity timeout | 2h | Auto-close on no traffic |
| Connections/min per IP | 10 | Flood protection |
| IP block | 1h | Abuse 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:
tunnl.yourdomain.com → SERVER_IP
*.tunnl.yourdomain.com → SERVER_IPSSL certificate
Generate a wildcard certificate with Certbot:
certbot certonly --manual --preferred-challenges dns \
-d "tunnl.yourdomain.com" \
-d "*.tunnl.yourdomain.com"Docker Compose
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-stoppedEnvironment variables
| Variable | Default | Description |
|---|---|---|
| SSH_ADDR | :22 | SSH server address |
| HTTP_ADDR | :80 | HTTP server address |
| HTTPS_ADDR | :443 | HTTPS server address |
| STATS_ADDR | 127.0.0.1:9090 | Metrics endpoint |
| HOST_KEY_PATH | host_key | SSH host key path |
| TLS_CERT | - | TLS certificate path |
| TLS_KEY | - | TLS private key path |
| DOMAIN | tunnl.gg | Service domain |
Building from source
The project requires Go 1.24+:
git clone https://github.com/klipitkas/tunnl.gg.git
cd tunnl.gg
make buildAvailable targets:
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: nosniffX-Frame-Options: DENYX-XSS-Protection: 1; mode=blockReferrer-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
ssh -t -R 80:localhost:3000 proxy.tunnl.ggThen in the Stripe dashboard, provide the URL: https://your-subdomain.tunnl.gg/api/webhooks/stripe
Client demo
Quick demo without deploying:
ssh -t -R 80:localhost:3000 -o ServerAliveInterval=60 proxy.tunnl.ggSend 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:
ssh -t -R 80:localhost:5173 proxy.tunnl.ggOpen the URL on your phone - HTTPS works out of the box.
Debugging OAuth integrations
Many OAuth providers require a public callback URL:
ssh -t -R 80:localhost:3000 proxy.tunnl.ggSet 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.