Skip to content

Latest commit

 

History

History
186 lines (130 loc) · 5.91 KB

File metadata and controls

186 lines (130 loc) · 5.91 KB

pgrok

Personal ngrok alternative. Expose local ports to the internet with automatic HTTPS, an interactive TUI dashboard, and HTTP request inspection -- all through your own VPS.

image

Quick Start

Prerequisites

  • A VPS (any provider) with ports 80 and 443 open (nothing else running on them for now)
  • Docker + Docker Compose on the VPS
  • A domain name you control
  • An SSH key on your Mac/Linux (You can run ssh-keygen to generate one if you don't have one)

1. DNS Setup: Point your domain at the VPS

Add a wildcard A record with your DNS provider (Cloudflare, Vercel, Namecheap, etc):

Type Name Value
A * <your-vps-ip>

2. Client Setup: Install on your Mac/Linux (run this first)

curl -fsSL https://raw.githubusercontent.com/R44VC0RP/pgrok/main/install.sh | bash -s client

(if you have a windows machine, and you get this running, please open a PR!)

You'll be prompted for your VPS IP, domain, and email. The installer will:

  • Auto-detects your SSH key
  • Builds and installs the pgrok command
  • Copies a server setup command to your clipboard (with your SSH key embedded)

3. Server -- Set up your VPS

SSH into your VPS and paste the command from step 2. Or run:

curl -fsSL https://raw.githubusercontent.com/R44VC0RP/pgrok/main/install.sh | sudo bash -s server

The script installs Caddy, configures SSH tunneling, adds your SSH key, and starts everything.

4. Use it

pgrok myapp 4000
# => https://myapp.yourdomain.com -> localhost:4000

Usage

# Expose a local dev server
pgrok myapp 4000
# -> https://myapp.yourdomain.com

# Expose an API
pgrok api 3000
# -> https://api.yourdomain.com

# Any subdomain works instantly
pgrok staging 8080
# -> https://staging.yourdomain.com

# Debug mode -- dumps raw tunnel logs on exit
pgrok myapp 4000 --print-logs

Press Ctrl+C to stop. The route is cleaned up automatically.

Rebuild the binary after pulling updates:

./setup.sh client --rebuild

How it works

image
  • Caddy on the VPS handles HTTPS with on-demand TLS -- certs are auto-provisioned per subdomain. Falls back to ZeroSSL if Let's Encrypt is rate-limited.
  • SSH reverse tunnels carry traffic -- no extra tunnel software.
  • A small Python script on the server dynamically configures Caddy routes when tunnels connect/disconnect.
  • The TUI client (built with OpenTUI) provides a live dashboard with request inspection, connection stats, and color-coded HTTP logs.

TUI Dashboard

The dashboard shows in real-time:

  • Session Status -- connecting / provisioning TLS / online / error
  • Forwarding -- your public URL and local port
  • TLS Certificate -- provisioning status (Let's Encrypt)
  • Connection Stats -- total requests, open connections, request rates (1m/5m), response time percentiles (p50/p90)
  • HTTP Request Log -- scrollable, color-coded log of every request through the tunnel

Request log colors:

  • Methods: GET (blue), POST (purple), PUT/PATCH (yellow), DELETE (red)
  • Status: 2xx (green), 3xx (cyan), 4xx (yellow), 5xx (red)
  • Duration: <100ms (green), 100-500ms (yellow), >500ms (red)

How SSL Works

  1. A request arrives for myapp.yourdomain.com
  2. Caddy checks with pgrok-ask: "Should I get a cert for this domain?"
  3. pgrok-ask verifies it's a single-level subdomain of *.yourdomain.com
  4. Caddy uses HTTP-01 challenge to get a cert -- tries Let's Encrypt first, falls back to ZeroSSL if rate-limited
  5. Cert is cached and auto-renewed
  6. The TUI client triggers cert provisioning during tunnel setup, so it's ready before you open the URL

Security

  • SSH key authentication only (no passwords)
  • Dedicated pgrok user with restricted SSH (remote forwarding only)
  • Caddy admin API only on localhost (not exposed externally)
  • SSH tunnels bind to localhost only (GatewayPorts no)
  • pgrok-ask prevents cert abuse -- only allows single-level subdomains

Configuration

Client (~/.pgrok/config)

Generated by the installer. Edit manually if needed:

PGROK_HOST=your-vps-ip
PGROK_DOMAIN=yourdomain.com
PGROK_USER=pgrok
PGROK_SSH_KEY=~/.ssh/id_ed25519

Server (/opt/pgrok/)

File Purpose
Caddyfile On-demand TLS config with LE + ZeroSSL
docker-compose.yml Caddy container
Script (/usr/local/bin/) Purpose
pgrok-tunnel Manages Caddy routes + provisions TLS certs
pgrok-ask Validates cert requests (systemd service)

Troubleshooting

Stuck on "connecting" in the TUI:

  • Run with --print-logs, press Ctrl+C, check /tmp/pgrok-debug.log
  • Verify SSH works: ssh pgrok@your-vps-ip echo ok

Stuck on "provisioning TLS...":

  • Let's Encrypt may be rate-limited (50 certs/week). ZeroSSL fallback handles this.
  • Check Caddy logs: docker compose logs caddy in /opt/pgrok

SSL certificate errors:

  • Verify pgrok-ask is running: systemctl status pgrok-ask
  • Make sure ports 80 and 443 are open
  • Cloudflare proxy (orange cloud) must be OFF for the wildcard record

Development

cd client/tui
bun install
bun run index.ts myapp 4000    # dev mode
bun run build                   # compile binary
bun run tsc --noEmit            # type-check

Limitations

  • Single user (personal tool, not multi-tenant)
  • Mac and Linux only (no Windows)
  • No automatic reconnection (restart pgrok if connection drops)
  • Stale routes possible on abrupt disconnection (self-heal on next connect)
  • HTTP request logging only (WebSocket passthrough works but isn't logged)

CONTRIBUTING

We welcome contributions! Please open an issue or PR.

LICENSE

MIT