82 Stars 🍴 2 Forks 👀 82 Watchers TypeScript
GitHub 链接https://github.com/R44VC0RP/pgrok
项目简介Personal ngrok alternative. Expose local ports to the internet with automatic HTTPS via SSH tunnels + Caddy.
创建时间2026-02-06
更新时间2026-02-11
📖 README English
# 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. <img width="1956" height="1900" alt="image" src="https://github.com/user-attachments/assets/277ef194-a135-407a-83a4-deaad4330dee" /> ## 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) ```bash 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: ```bash 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 ```bash pgrok myapp 4000 # => https://myapp.yourdomain.com -> localhost:4000 ``` ## Usage ```bash # 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: ```bash ./setup.sh client --rebuild ``` ## How it works <img width="932" height="331" alt="image" src="https://github.com/user-attachments/assets/9d56fb43-bafe-4697-9c72-3e001a0c92aa" /> - **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](https://opentui.com)) 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: ```bash 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 ```bash 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