Metadata-Version: 2.4
Name: tunnelmate-cli
Version: 1.1.0
Summary: TunnelMate by Shashan Lumbhani — Cloudflare Quick Tunnel manager with CLI, Interactive TUI, Daemon IPC, and Telegram Bot
Author-email: Shashan Lumbhani <lumbhanishashan1510@gmail.com>
License: MIT
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: typer>=0.9.0
Requires-Dist: rich>=13.0.0
Requires-Dist: questionary>=2.0.0
Requires-Dist: pydantic>=2.0.0
Requires-Dist: python-telegram-bot>=20.0
Requires-Dist: httpx>=0.24.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"

# ⚡ TunnelMate by Shashan Lumbhani

> **Production-Grade Cloudflare Quick Tunnel Manager & Cross-Platform Ingress Orchestrator**  
> *Seamless Localhost Ingress, Background Daemon, Multi-Device SSH Discovery, Server-Side Session Security, and Telegram Bot Remote Management.*

**Author:** [Shashan Lumbhani](mailto:lumbhanishashan1510@gmail.com)  
**License:** [MIT License](LICENSE)  
**Supported Platforms:** Linux, macOS, Windows (PowerShell / CMD / WSL)  
**Python Compatibility:** Python 3.10+  

---

## 📑 Table of Contents

- [⚡ TunnelMate by Shashan Lumbhani](#-tunnelmate-by-shashan-lumbhani)
  - [📑 Table of Contents](#-table-of-contents)
  - [🚨 The Problem Statement](#-the-problem-statement)
  - [💡 The Solution: What TunnelMate Delivers](#-the-solution-what-tunnelmate-delivers)
  - [🎯 Real-World Use Cases](#-real-world-use-cases)
  - [🏛️ System Architecture](#️-system-architecture)
  - [🚀 Installation \& Setup](#-installation--setup)
    - [Option 1: Automated Installer (Linux / macOS)](#option-1-automated-installer-linux--macos)
    - [Option 2: Automated Installer (Windows PowerShell)](#option-2-automated-installer-windows-powershell)
    - [Option 3: Manual Installation](#option-3-manual-installation)
  - [🏁 Quick Start Guide](#-quick-start-guide)
  - [⚡ Multi-Device SSH Ingress (`tunnelmate-ssh`)](#-multi-device-ssh-ingress-tunnelmate-ssh)
  - [🤖 Telegram Bot Remote Management](#-telegram-bot-remote-management)
    - [1. Configuration](#1-configuration)
    - [2. Bot Process Control](#2-bot-process-control)
    - [3. Server-Side Session Management](#3-server-side-session-management)
    - [4. Telegram Bot Chat Interface](#4-telegram-bot-chat-interface)
  - [🔁 Reboot Persistence \& Daemon Autostart](#-reboot-persistence--daemon-autostart)
  - [🖥️ Complete CLI Command Reference](#️-complete-cli-command-reference)
  - [🐍 Python Library API](#-python-library-api)
  - [🔒 Security \& Privacy Architecture](#-security--privacy-architecture)
  - [🧪 Test Suite \& Validation](#-test-suite--validation)
  - [📄 License \& Credits](#-license--credits)

---

## 🚨 The Problem Statement

Modern software engineers, system administrators, and homelab builders face significant friction when trying to expose local servers or remotely access machines behind private networks:

1. **Carrier-Grade NAT (CGNAT) & Dynamic IPs:**  
   Most residential ISPs, mobile 4G/5G hotspots, university Wi-Fi, and corporate intranets place devices behind Carrier-Grade NAT. There is no publicly routable IPv4 address, and incoming ports cannot be opened on the upstream router.
2. **Ephemeral URL Instability & Process Death:**  
   Standard Cloudflare Quick Tunnels (`cloudflared tunnel --url http://localhost:8080`) are helpful, but closing the terminal or a transient network glitch terminates the tunnel. The newly assigned `https://*.trycloudflare.com` URL changes every restart, requiring manual re-discovery and copy-pasting.
3. **Reboot Amnesia (No Persistence Across Restarts):**  
   When a machine restarts or updates, running tunnel processes and management bots do not automatically recover without complex custom scripting. For headless servers, home workstations, and IoT gateways, this results in extended outages.
4. **Multi-Device SSH Remote Access Chaos:**  
   Managing remote SSH into multiple physical machines (e.g. office workstation, development laptop, home server) requires tracking different URLs, changing hostnames, and figuring out which machine has which URL active.
5. **OpenSSH ProxyCommand Configuration Complexity:**  
   Connecting to an SSH server over Cloudflare requires configuring `ProxyCommand cloudflared access ssh --hostname %h` inside `~/.ssh/config` on every single client computer, downloading the appropriate `cloudflared` binary for the OS, and specifying exact flags.
6. **Security, Privacy & Notification Leaks:**  
   Naive remote-management bots broadcast sensitive live tunnel URLs to anyone who triggers `/start` in Telegram. Without strict server-side session authentication, unauthorized chat users can discover private tunnels and access internal services.

---

## 💡 The Solution: What TunnelMate Delivers

**TunnelMate by Shashan Lumbhani** is an all-in-one tunnel management and remote ingress orchestrator that eliminates these hurdles:

| Challenge | How TunnelMate Solves It |
|---|---|
| **CGNAT & Closed Routers** | Creates secure outbound tunnels to Cloudflare's global edge network. Zero port forwarding, zero router configuration, and zero custom domain registration required. |
| **Process Death & URL Loss** | A background daemon runs continuously, supervises `cloudflared` subprocesses, detects disconnections, and auto-recovers with exponential backoff while persisting state in a WAL-mode SQLite database. |
| **System Restarts / Reboots** | Built-in autostart engine restores running tunnels and the Telegram Bot automatically when the operating system boots up. |
| **Multi-Device SSH Discovery** | Uses Telegram Bot metadata as a private, token-encrypted registry. Any number of devices can publish their active SSH tunnels, and the `tunnelmate-ssh` client discovers and presents them in an interactive menu with hostnames, devices, and detected usernames. |
| **ProxyCommand Headache** | The `tunnelmate-ssh` CLI automatically locates or installs `cloudflared` and dynamically establishes the OpenSSH `ProxyCommand` bridge on Linux, macOS, and Windows. |
| **Security & Privacy Leaks** | Telegram notifications and menus are strictly gated behind server-side session authentication. Logged-out users receive **0 URLs or alerts**. Administrators can view active sessions via `tunnelmate bot sessions` and revoke access instantly via `tunnelmate bot revoke-sessions`. |

---

## 🎯 Real-World Use Cases

### 1. Remote SSH Access to CGNAT / Home Servers
Connect to your home workstation, Raspberry Pi, or local VM from anywhere in the world (coffee shop, airport, office) without a static public IP, port forwarding, or third-party VPN configurations.

### 2. Multi-Machine Fleet SSH Management (`tunnelmate-ssh`)
Run TunnelMate across your laptop, desktop, and remote server with the same Telegram Bot token. Launch `tunnelmate-ssh` on your client machine to instantly see all active devices, select one with arrow keys, and SSH in seamlessly.

### 3. Ephemeral Webhook & Payment Gateway Testing
Instantly expose local HTTP servers (FastAPI, Next.js, Django, Express, Flask) to public webhooks from Stripe, GitHub, Shopify, or PayPal with secure HTTPS URLs.

### 4. Client Demonstrations & Staging Previews
Share live work-in-progress web applications directly from your local development machine with clients or team members without deploying to staging servers.

### 5. Remote Server Management from Mobile (Telegram Bot)
Monitor your host machine from your phone: start, stop, or restart tunnels, change forwarded ports, inspect daemon statistics, run health checks, and receive real-time alerts when URLs update.

### 6. Dynamic Port Remapping for Multi-Service Workflows
Switch target ports on the fly (e.g. from port `3000` to `8080`) using `tunnelmate port <name> <new_port>`. TunnelMate safely swaps the running process without breaking tunnel configurations.

### 7. Automated CI/CD Preview Environments
Integrate `tunnelmate url <name>` into automated CI/CD scripts to launch temporary test tunnels and export live URLs for integration tests.

---

## 🏛️ System Architecture

```text
┌─────────────────────────────────┐       ┌─────────────────────────────────┐
│     Interactive TUI / CLI       │       │       Telegram Bot Client       │
│    (Questionary + Rich + Typer) │       │   (Session Auth + Notifications)│
└────────────────┬────────────────┘       └────────────────┬────────────────┘
                 │                                         │
                 │          Unix Domain Socket IPC         │
                 │      (mode 0600) / Local TCP Fallback   │
                 └───────────────────┬─────────────────────┘
                                     │
                  ┌──────────────────▼──────────────────┐
                  │       TunnelMate Daemon Service     │
                  │  ┌───────────────────────────────┐  │
                  │  │       Async IPC Server        │  │
                  │  └───────────────┬───────────────┘  │
                  │                  │                  │
                  │  ┌───────────────▼───────────────┐  │
                  │  │       Tunnel Supervisor       │  │
                  │  │  (Auto-Recovery & Health)     │  │
                  │  └───────┬───────────────┬───────┘  │
                  └──────────┼───────────────┼──────────┘
                             │               │
            ┌────────────────▼─┐           ┌─▼────────────────┐
            │   cloudflared    │           │ SQLite Database  │
            │   Subprocesses   │           │   (WAL Mode)     │
            │ (no shell=True)  │           └──────────────────┘
            └──────────────────┘
```

---

## 🚀 Installation & Setup

### Option 1: Automated Installer (Linux / macOS)

```bash
chmod +x install.sh
./install.sh
```

The script will:
1. Verify Python 3.10+
2. Download official `cloudflared` binary for your architecture (`x86_64`, `aarch64`, `armv7`)
3. Initialize `~/.tunnelmate` state directory with secure `0700` permissions
4. Install `tunnelmate` and `tunnelmate-ssh` into your environment
5. Register systemd user service units for background operation

### Option 2: Automated Installer (Windows PowerShell)

Run the included PowerShell installer in PowerShell:

```powershell
powershell -ExecutionPolicy Bypass -File .\install.ps1
```

The script will:
1. Verify Python 3.10+
2. Auto-download official `cloudflared.exe` for Windows
3. Initialize `%USERPROFILE%\.tunnelmate` state directory
4. Install `tunnelmate` and `tunnelmate-ssh` CLI executables

### Option 3: Manual Installation

```bash
# Clone the repository
git clone https://github.com/soni-shashan/tunnelmate.git
cd tunnelmate

# Create and activate virtual environment
python3 -m venv .venv
source .venv/bin/activate  # On Windows: .venv\Scripts\activate

# Install TunnelMate in editable mode
pip install -e .

# Auto-download official cloudflared binary
tunnelmate install-cloudflared
```

---

## 🏁 Quick Start Guide

### Step 1: Start the Background Daemon
```bash
tunnelmate daemon start
```
Verify daemon status:
```bash
tunnelmate daemon status
```

### Step 2: Open the Interactive Arrow-Key TUI Menu
Simply run:
```bash
tunnelmate
```
*(or explicitly: `tunnelmate menu`)*

The interactive menu lets you create, start, stop, restart tunnels, remap ports, view live logs, inspect daemon stats, manage Telegram Bot settings, and connect via SSH.

### Step 3: Direct CLI Commands

```bash
# Create a tunnel for a web server on port 8080
tunnelmate create my-web --port 8080

# Create an SSH tunnel for local port 22
tunnelmate create my-ssh --port 22 --protocol tcp

# Start the tunnel and get the live trycloudflare.com URL
tunnelmate start my-web

# Print only the URL (ideal for shell scripts)
tunnelmate url my-web

# Remap target port on the fly (e.g. from 8080 to 3000)
tunnelmate port my-web 3000

# Run diagnostics on local port & Cloudflare ingress
tunnelmate health my-web

# View real-time logs (last 50 lines)
tunnelmate logs my-web --lines 50

# List all configured tunnels
tunnelmate list

# Stop a tunnel
tunnelmate stop my-web

# Delete a tunnel
tunnelmate delete my-web --yes
```

---

## ⚡ Multi-Device SSH Ingress (`tunnelmate-ssh`)

TunnelMate includes a specialized `tunnelmate-ssh` client that turns any SSH tunnel into a frictionless remote shell without touching `~/.ssh/config`:

```bash
# 1. Interactive Mode: Auto-discover all SSH tunnels from your Telegram Bot
tunnelmate-ssh

# 2. Discover SSH tunnels using a specific Bot Token:
tunnelmate-ssh --token <YOUR_TELEGRAM_BOT_TOKEN>

# 3. List active SSH tunnels discovered from your bot:
tunnelmate-ssh --list

# 4. Direct non-interactive connection:
tunnelmate-ssh user@<trycloudflare_url>

# Examples:
tunnelmate-ssh shashansoni@subjective-lenses-working-subscription.trycloudflare.com
tunnelmate-ssh root@https://my-app.trycloudflare.com -i ~/.ssh/id_rsa
```

### How Multi-Device Discovery Works:
1. Each host machine running TunnelMate publishes its active SSH tunnels to private Telegram Bot metadata using token-derived encryption.
2. The payload contains the machine's detected hostname, device model, and current OS username (e.g. `shashansoni`).
3. Running `tunnelmate-ssh` on any client machine decrypts the registry and displays all online devices.
4. Selecting a machine auto-configures the Cloudflare `ProxyCommand` bridge and opens an SSH session immediately.

---

## 🤖 Telegram Bot Remote Management

TunnelMate includes a full-featured Telegram Bot interface for remote mobile management.

### 1. Configuration
```bash
# 1. Set Telegram Bot token (from @BotFather)
tunnelmate bot set-token "123456789:ABCdefGhIJKlmNoPQRstuVWXyz"

# 2. Set salted SHA-256 administrator password
tunnelmate bot set-password "YourStrongPassword"

# 3. View discovered chat IDs from recent interactions
tunnelmate bot chats

# 4. Whitelist a Chat ID as Administrator
tunnelmate bot whitelist <CHAT_ID>
```

### 2. Bot Process Control
```bash
# Start Telegram bot in background (enables auto-restore on reboot)
tunnelmate bot start

# Check bot running status & PID
tunnelmate bot status

# Stop background bot (disables auto-restore on reboot)
tunnelmate bot stop
```

### 3. Server-Side Session Management
Strict server-side session management guarantees that unauthenticated users cannot see live links or receive notifications:

```bash
# Inspect all registered chat IDs and their active session status
tunnelmate bot sessions

# Revoke all active sessions on the server (logs out all users immediately)
tunnelmate bot revoke-sessions
```

### 4. Telegram Bot Chat Interface
- `/start` — Opens the main interactive control hub. Unauthenticated users see restricted menus with no tunnel links.
- `/login <password>` — Authenticates the user as an Administrator (the password message is auto-deleted for privacy).
- `/logout` — Clears the active admin session and revokes access.
- `/create <name> <port> [protocol]` — Creates a new tunnel configuration directly from chat.
- `/port <name> <new_port>` — Updates the target port for an existing tunnel.
- **Inline Menus:**
  - `[📋 Tunnels List]` — View running and stopped tunnels across local and remote devices.
  - `[▶️ Start] / [⏹️ Stop] / [🔄 Restart]` — Full real-time process controls.
  - `[🔗 Latest Link]` — Retrieve active URL with one-click `[🌐 Open in Browser]` button.
  - `[🩺 Health Check]` — Diagnose target service and Cloudflare edge status.
  - `[🔔 Notifications]` — Opt in/out of real-time alerts when URLs update or tunnels recover.

---

## 🔁 Reboot Persistence & Daemon Autostart

TunnelMate includes an auto-restoration engine:

```bash
# Check current autostart configuration
tunnelmate autostart status

# Enable autostart on system boot / restart
tunnelmate autostart enable

# Disable autostart on boot
tunnelmate autostart disable
```

When enabled:
- If the **Daemon** was running before a reboot, it starts automatically on system startup and restores all active tunnels.
- If the **Telegram Bot** was running before a reboot, it relaunches in the background and restores tunnel synchronization.

### Systemd User Services (Linux)
```bash
mkdir -p ~/.config/systemd/user
cp systemd/tunnelmate-daemon.service ~/.config/systemd/user/
cp systemd/tunnelmate-bot.service ~/.config/systemd/user/

systemctl --user daemon-reload
systemctl --user enable --now tunnelmate-daemon
systemctl --user enable --now tunnelmate-bot

# Keep services active without an open SSH login session:
loginctl enable-linger $USER
```

---

## 🖥️ Complete CLI Command Reference

### Main Commands
| Command | Arguments | Description |
|---|---|---|
| `tunnelmate menu` | — | Open interactive arrow-key TUI dashboard |
| `tunnelmate list` | — | Display color-coded table of all configured tunnels |
| `tunnelmate create` | `<name> --port <port> [--protocol http\|tcp\|tls]` | Create a new Quick Tunnel |
| `tunnelmate start` | `<name>` | Launch tunnel subprocess and acquire live URL |
| `tunnelmate stop` | `<name>` | Gracefully stop running tunnel subprocess |
| `tunnelmate restart` | `<name>` | Restart tunnel and assign fresh trycloudflare.com URL |
| `tunnelmate port` | `<name> <new_port>` | Dynamically remap target port on the fly |
| `tunnelmate url` | `<name>` | Output raw URL for shell scripts and piping |
| `tunnelmate health` | `<name>` | Test local service response and Cloudflare edge status |
| `tunnelmate logs` | `<name> [--lines 50]` | Stream or view recent cloudflared process logs |
| `tunnelmate history` | `<name>` | Inspect full lifecycle audit trail |
| `tunnelmate delete` | `<name> [--yes]` | Delete tunnel configuration and purge history |
| `tunnelmate install-cloudflared` | — | Auto-download official Cloudflare binary |
| `tunnelmate ssh` | `[target]` | Connect to Cloudflare SSH tunnel |

### Daemon Commands (`tunnelmate daemon`)
| Command | Description |
|---|---|
| `tunnelmate daemon start` | Launch background daemon service process |
| `tunnelmate daemon stop` | Stop background daemon service |
| `tunnelmate daemon status` | Check daemon PID, uptime, and IPC connectivity |
| `tunnelmate daemon run` | Run daemon in foreground (for systemd or debugging) |

### Telegram Bot Commands (`tunnelmate bot`)
| Command | Arguments | Description |
|---|---|---|
| `tunnelmate bot start` | — | Launch Telegram Bot process in background |
| `tunnelmate bot stop` | — | Stop background Telegram Bot process |
| `tunnelmate bot status` | — | Inspect bot process status, token, and admin whitelist |
| `tunnelmate bot set-token` | `<token>` | Configure Telegram bot API token |
| `tunnelmate bot set-password`| `<password>` | Set salted SHA-256 admin password |
| `tunnelmate bot chats` | — | List all historical chat IDs and subscriber names |
| `tunnelmate bot whitelist` | `<chat_id>` | Add Telegram Chat ID to administrator whitelist |
| `tunnelmate bot unwhitelist` | `<chat_id>` | Remove Telegram Chat ID from whitelist |
| `tunnelmate bot sessions` | — | Display active server-side session status table |
| `tunnelmate bot revoke-sessions` | — | Invalidate all active sessions (force logout) |
| `tunnelmate bot clear-tunnels` | — | Purge published SSH tunnel metadata from Telegram |

---

## 🐍 Python Library API

Embed TunnelMate directly into your Python scripts and services:

```python
from tunnelmate.client import TunnelMateClient

client = TunnelMateClient()

# Check daemon connectivity
if not client.is_daemon_online():
    print("Daemon is offline. Start with 'tunnelmate daemon start'")
    exit(1)

# Create and start a tunnel
client.create_tunnel(name="fastapi-app", port=8000)
tunnel = client.start_tunnel("fastapi-app")
print(f"Public Quick Tunnel URL: {tunnel.current_url}")

# Health diagnostics
health, details = client.check_health("fastapi-app")
print(f"Status: {health.value} -> {details['message']}")

# Change target port dynamically
client.change_port("fastapi-app", 8080)

# Stop tunnel
client.stop_tunnel("fastapi-app")
```

---

## 🔒 Security & Privacy Architecture

1. **Subprocess Isolation (No `shell=True`):**  
   All `cloudflared` instances are spawned using explicit argument lists via `subprocess.Popen` without `shell=True`. Process groups prevent orphan or zombie processes.
2. **Restricted Unix Domain Socket:**  
   The IPC socket (`~/.tunnelmate/tunnelmate.sock`) is strictly restricted to filesystem permissions `0600` (read/write only by the owning user).
3. **State Directory Permissions:**  
   The configuration and SQLite database directory `~/.tunnelmate` is initialized with permissions `0700`.
4. **Salted SHA-256 Authentication:**  
   Admin passwords use high-entropy random salts (`secrets.token_hex(16)`) and SHA-256 hashing. Password verification uses constant-time string comparisons (`secrets.compare_digest`) to prevent timing attacks.
5. **Private Encrypted SSH Tunnel Metadata:**  
   Published SSH tunnels are encrypted with token-derived keys (counter-mode HMAC keystream + SHA-256 HMAC authentication) and stored under hidden language tags. Public visitors to the bot see only the default description.
6. **Server-Side Session Verification:**  
   Broadcast notifications are strictly restricted to subscribers with an active, authenticated server session (`is_authenticated == True`). Logged-out users receive zero URLs.

---

## 🧪 Test Suite & Validation

TunnelMate comes with a comprehensive test suite covering database operations, IPC serialization, process lifecycle, password hashing, SSH discovery, and session security:

```bash
# Run all unit and integration tests
pytest -v tests/
```

Test coverage includes:
- `test_cross_platform.py` — Process termination, cross-platform paths, reboot persistence, session revocation, and notification security.
- `test_ssh_discovery.py` — Hostname parsing, token keystream encryption/decryption, username/device detection, and multi-device merging.
- `test_db.py` — SQLite schema migrations, WAL mode transactions, subscriber preferences, and session tracking.
- `test_config.py` — Salted password hashing, configuration serialization, and validation.
- `test_ipc.py` — Unix socket / TCP client-server roundtrips and serialization.
- `test_cli.py` — Typer CLI command dispatch, formatting panels, and help outputs.
- `test_health.py` — Ephemeral HTTP origin and TCP latency verification.

---

## 📄 License & Credits

Created by **Shashan Lumbhani** ([lumbhanishashan1510@gmail.com](mailto:lumbhanishashan1510@gmail.com)).  
Distributed under the **MIT License**. See `LICENSE` for details.

*Built with ❤️ for seamless, secure localhost ingress across every device.*
