Getting Started

Learn how to use TunnelForge CLI to create secure tunnels and expose your local services.

Installation

Download CLI

Download the TunnelForge CLI for your platform from the download page.

Download CLI

Windows

After downloading the Windows executable:

  1. Extract or move the tunnelforge.exe file to a directory in your PATH
  2. Open Command Prompt or PowerShell
  3. Run tunnelforge --help to verify installation
bash
# Example: Add to PATH
# Move to a directory in PATH (e.g., C:\Program Files\TunnelForge)
# Or add current directory to PATH in System Environment Variables

macOS

After downloading the macOS binary (choose ARM64 for Apple Silicon, x64 for Intel):

bash
# Open Terminal
# Make it executable
chmod +x tunnelforge

# Move to a directory in your PATH
sudo mv tunnelforge /usr/local/bin/

# Verify installation
tunnelforge --help

Linux

After downloading the Linux binary (choose ARM64 or x64 based on your system):

bash
# Open Terminal
# Make it executable
chmod +x tunnelforge

# Move to a directory in your PATH
sudo mv tunnelforge /usr/local/bin/

# Verify installation
tunnelforge --help

Alternative Installation

You can also place the binary in any directory and add it to your PATH, or run it directly from the download location.

Quick Start

Note

You'll need an API token to use TunnelForge. Get your token from the Tokens page after logging in.

1. Authenticate

First, save your authentication token:

bash
# Save your token (get it from the Tokens page)
tunnelforge auth your-token-here

2. Start a Tunnel

The simplest way to create a tunnel is to forward a local port:

bash
# Forward local HTTP server on port 3000
tunnelforge http 3000

This will create a public URL like: https://abc123.yourdomain.com

3. View Statistics

The CLI displays real-time statistics in the terminal and provides a local web interface:

  • Request count and traffic statistics
  • Recent requests with method, path, and status
  • Bytes in/out
  • Error count
  • Local web interface at http://127.0.0.1:4040

4. Stop the Tunnel

Press Ctrl+C to stop the tunnel.

Configuration

Config File Location

TunnelForge uses a configuration file to store your settings. The default location is:

bash
~/.tunnelforge/config.yaml  # YAML format (recommended)
~/.tunnelforge/config.json  # JSON format (legacy)

YAML Configuration (Recommended)

YAML format is recommended for better readability and multiple tunnel support:

yaml
# ~/.tunnelforge/config.yaml
token: your-auth-token-here
server_url: https://tunnelforge.com

# Local web interface address (optional, default: 127.0.0.1:4040)
inspect_addr: 127.0.0.1:4040

# HTTP proxy address (optional)
# http_proxy: http://proxy.example.com:8080

# Trust host root certificates (optional, default: false)
# trust_host_root_certs: false

# Tunnel definitions
tunnels:
  web:
    name: web
    proto: http
    subdomain: myapp
    target_url: localhost
    target_port: 3000
    host_header_rewrite: false

  api:
    name: api
    proto: https
    subdomain: api
    target_url: localhost
    target_port: 8080
    host_header_rewrite: true

  database:
    name: database
    proto: tcp
    target_url: localhost
    target_port: 3306

JSON Configuration (Legacy)

JSON format is also supported for backward compatibility:

json
{
  "token": "your-auth-token-here",
  "server_url": "https://tunnelforge.com",
  "inspect_addr": "127.0.0.1:4040",
  "http_proxy": "http://proxy.example.com:8080",
  "trust_host_root_certs": false,
  "tunnels": {
    "web": {
      "name": "web",
      "proto": "http",
      "subdomain": "myapp",
      "target_url": "localhost",
      "target_port": 3000
    }
  }
}

Configuration Parameters

ParameterDescriptionDefault
tokenAuthentication token (required)-
server_urlServer URLhttps://tunnelforge.com
inspect_addrLocal web interface address127.0.0.1:4040
http_proxyHTTP proxy address (can also use HTTP_PROXY env var)-
trust_host_root_certsTrust host root certificates for TLSfalse

Tunnel Configuration Options

ParameterDescriptionRequired
nameTunnel nameYes
protoProtocol: http, https, tcp, tls, udpYes
subdomainSubdomain name (for HTTP/HTTPS)No
hostnameCustom hostname (requires DNS setup)No
target_urlTarget hostnamelocalhost
target_portTarget portYes
host_header_rewriteRewrite Host headerfalse
basic_authBasic auth in user:password formatNo

Multiple Tunnels

List Configured Tunnels

View all tunnels defined in your configuration file:

bash
tunnelforge list

# Output:
# Configured tunnels (3):
#
#   web:
#     Protocol: http
#     Subdomain: myapp
#     Target Port: 3000
#     Host Header Rewrite: enabled
#
#   api:
#     Protocol: https
#     Subdomain: api
#     Target Port: 8080
#
#   database:
#     Protocol: tcp
#     Target Port: 3306

Start Specific Tunnels

Start one or more tunnels by name:

bash
# Start specific tunnels
tunnelforge start web api

# Start single tunnel
tunnelforge start web

Tunnels are started in parallel. Each tunnel will display its own terminal UI.

Start All Tunnels

Start all tunnels defined in your configuration:

bash
tunnelforge start-all

# Output:
# Starting 3 tunnel(s)...
# [web] Starting http tunnel: localhost:3000
# [api] Starting https tunnel: localhost:8080
# [database] Starting tcp tunnel: localhost:3306

Complete Example

Example configuration file with multiple tunnels:

yaml
# ~/.tunnelforge/config.yaml
token: your-token-here
server_url: https://tunnelforge.com
inspect_addr: 127.0.0.1:4040

tunnels:
  # Web application
  web:
    proto: http
    subdomain: myapp
    target_url: localhost
    target_port: 3000
    host_header_rewrite: false

  # API server
  api:
    proto: https
    subdomain: api
    target_url: localhost
    target_port: 8080
    host_header_rewrite: true

  # Database
  database:
    proto: tcp
    target_url: localhost
    target_port: 3306

  # PostgreSQL with TLS
  postgres:
    proto: tls
    target_url: localhost
    target_port: 5432

  # DNS server
  dns:
    proto: udp
    target_url: localhost
    target_port: 53

HTTP/HTTPS Tunneling

Basic Usage

bash
# HTTP tunnel
tunnelforge http 3000

# HTTPS tunnel
tunnelforge https 443

URL-based Forwarding

Forward to any URL, not just localhost:

bash
# Forward to localhost
tunnelforge http http://localhost:3000

# Forward to different host
tunnelforge http http://192.168.1.100:8080

# Forward to custom domain
tunnelforge http http://app.local:3000

Host Header Rewriting

Some applications check the Host header. Use --host-header=rewrite to rewrite it:

bash
tunnelforge http 3000 --host-header=rewrite
tunnelforge http http://app.local:3000 --host-header=rewrite

Custom Subdomain

Request a specific subdomain:

bash
tunnelforge http 3000 --subdomain=myapp
# Creates: https://myapp.yourdomain.com

Subdomains must be unique. If the requested subdomain is already taken, a random one will be assigned.

HTTP/2 & gRPC Tunneling

New Feature

TunnelForge now supports HTTP/2 h2c (cleartext) for gRPC and other HTTP/2 services!

What is HTTP/2 h2c?

HTTP/2 h2c (HTTP/2 cleartext) allows HTTP/2 connections without TLS. This is commonly used by gRPC servers running locally during development. TunnelForge automatically detects HTTP/2 servers and uses the appropriate protocol.

gRPC Tunnel

Forward gRPC traffic to your local gRPC server. gRPC uses HTTP/2, so you can use a standard HTTP tunnel:

bash
# Start gRPC tunnel (gRPC typically runs on port 50051)
tunnelforge http 50051

# Your gRPC server is now accessible at:
# https://your-subdomain.tunnelforge.xyz

HTTP/2 Server Example

Create a simple HTTP/2 test server in Go:

go
package main

import (
    "fmt"
    "net/http"
    "golang.org/x/net/http2"
    "golang.org/x/net/http2/h2c"
)

func main() {
    handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "Protocol: %s\n", r.Proto)
    })
    
    h2s := &http2.Server{}
    h2cHandler := h2c.NewHandler(handler, h2s)
    
    http.ListenAndServe(":50051", h2cHandler)
}

Testing HTTP/2

Test your HTTP/2 tunnel with curl:

bash
# Test local server directly
curl --http2-prior-knowledge http://localhost:50051/test

# Test through tunnel (should show Protocol: HTTP/2.0)
curl https://your-subdomain.tunnelforge.xyz/test

Automatic Fallback

TunnelForge automatically falls back to HTTP/1.1 if the target server doesn't support HTTP/2. This ensures compatibility with all HTTP servers.

WebSocket Tunneling

WebSocket Support

TunnelForge fully supports WebSocket connections through HTTP tunnels. WebSocket upgrade requests are automatically detected and handled with bidirectional data streaming.

Basic Usage

Simply create an HTTP tunnel to your WebSocket server:

bash
# Start tunnel to WebSocket server
tunnelforge http 8080

# Your WebSocket server is accessible at:
# wss://your-subdomain.tunnelforge.xyz

Testing WebSocket

Test your WebSocket tunnel with wscat:

bash
# Install wscat
npm install -g wscat

# Connect to WebSocket through tunnel
wscat -c wss://your-subdomain.tunnelforge.xyz/ws

WebSocket Server Example

Example WebSocket echo server in Go:

go
package main

import (
    "log"
    "net/http"
    "github.com/gorilla/websocket"
)

var upgrader = websocket.Upgrader{
    CheckOrigin: func(r *http.Request) bool { return true },
}

func echo(w http.ResponseWriter, r *http.Request) {
    conn, _ := upgrader.Upgrade(w, r, nil)
    defer conn.Close()
    
    for {
        msgType, msg, _ := conn.ReadMessage()
        conn.WriteMessage(msgType, msg)
    }
}

func main() {
    http.HandleFunc("/ws", echo)
    log.Fatal(http.ListenAndServe(":8080", nil))
}

Note

WebSocket connections work seamlessly through HTTPS tunnels. The wss:// protocol is automatically handled when connecting through a TunnelForge HTTPS endpoint.

TCP/TLS/UDP Tunneling

TCP Tunnel

Forward raw TCP traffic. Perfect for databases and other TCP services:

bash
# MySQL
tunnelforge tcp 3306

# Redis
tunnelforge tcp 6379

# SSH
tunnelforge tcp 22

TLS Tunnel

Forward TLS-encrypted traffic:

bash
# PostgreSQL
tunnelforge tls 5432

# Any TLS service
tunnelforge tls 8443

UDP Tunnel

Forward UDP packets:

bash
# DNS
tunnelforge udp 53

# Custom UDP service
tunnelforge udp 1234

Public URL Format

TCP/TLS/UDP tunnels get a public URL in the format: protocol://subdomain.protocol.domain:port

Options & Flags

FlagDescriptionExample
--serverCustom server URL--server=https://tunnel.example.com
--subdomainRequest specific subdomain--subdomain=myapp
--host-headerRewrite Host header--host-header=rewrite
--tokenOverride API token--token=abc123
--configConfig file path--config=/path/to/config.yaml
--helpShow help message--help

Examples

Web Development

Share your local development server with teammates:

bash
# Terminal 1: Start your dev server
npm run dev  # Runs on port 3000

# Terminal 2: Create tunnel
tunnelforge http 3000 --subdomain=myapp

API Testing

Test webhooks and API integrations:

bash
# Start API server
python app.py  # Port 5000

# Create tunnel
tunnelforge http 5000 --subdomain=api

# Use public URL for webhook callbacks

Database Access

Securely access local databases:

bash
# MySQL
tunnelforge tcp 3306

# PostgreSQL
tunnelforge tls 5432

# Connect using public URL from your DB client

Multiple Tunnels

Start multiple tunnels from configuration:

bash
# Define tunnels in config.yaml
tunnels:
  web:
    proto: http
    target_port: 3000
  api:
    proto: https
    target_port: 8080

# Start all tunnels
tunnelforge start-all

# Or start specific ones
tunnelforge start web api

Troubleshooting

Connection Issues

If you're having trouble connecting, check that your API token is valid and the server URL is correct.

Configuration File Issues

If you're having issues with your configuration file:

  • Check the file location: ~/.tunnelforge/config.yaml
  • Verify YAML syntax is correct (use a YAML validator)
  • Ensure all required fields are present (token, tunnels)
  • Check file permissions (should be readable)
bash
# Check if config file exists
ls -la ~/.tunnelforge/config.yaml

# View config file
cat ~/.tunnelforge/config.yaml

# Test YAML syntax (if yq is installed)
yq eval . ~/.tunnelforge/config.yaml

Subdomain Already Taken

If your requested subdomain is unavailable, TunnelForge will automatically assign a random subdomain.

Port Already in Use

Make sure the port you're trying to forward is not already in use:

bash
# Check if port is in use
# Linux/macOS
lsof -i :3000

# Windows
netstat -ano | findstr :3000