Skip to content

About

A terminal UI for managing SSH port forwarding tunnels with profile support. Inspired by Bitvise SSH Client's tunnel management feature.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

Β 

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

SSH Tunnel Manager

A terminal UI for managing SSH port forwarding tunnels with profile support. Inspired by Bitvise SSH Client's tunnel management feature.

Python 3.9+ License: MIT Platform: macOS | Linux

Features

  • Profile-based configuration - Create and switch between multiple connection profiles
  • Profile selector - Visual profile picker on startup (like Bitvise)
  • Remembers last profile - Automatically opens your last used profile
  • Vim-style navigation - Familiar keybindings for efficient navigation
  • Import from Bitvise - Parse and import .tlp tunnel configuration files
  • Auto-reconnect - Automatic retry with exponential backoff on disconnect
  • Real-time logs - Scrollable log panel with connection status
  • PPK key support - Automatic conversion of PuTTY keys (requires puttygen)
  • Inline editing - Edit tunnels directly in the interface

Table of Contents

Installation

From Source (Recommended)

# Clone the repository
git clone https://github.com/saidkamolxon/ssh-tunnel-manager.git
cd ssh-tunnel-manager

# Install in development mode
pip install -e .

# Now you can run it with:
stm

Without Installation

# Run directly from the source directory
python main.py

Quick Start

  1. First run - Creates a default profile and shows the setup wizard:

    stm
  2. Configure SSH connection - Enter your server details in the setup wizard:

    • Host: your-server.com
    • Port: 22
    • User: your-username
    • Key file: ~/.ssh/id_rsa (optional, press Tab to browse)
  3. Add tunnels - Press a to add a new tunnel:

    • Listen Address: 127.0.0.1
    • Listen Port: 8080
    • Remote Address: 172.16.0.10
    • Remote Port: 80
    • Name: Web Server
  4. Connect - Press c to establish the SSH connection

  5. Save - Type :w to save your configuration

Usage

Command Line Options

stm [profile] [options]
Option Description
profile Profile name or path to .stm file
--new NAME, -n NAME Create a new profile with the given name
--list, -l List all available profiles
--select, -s Always show profile selector on startup
--import FILE, -i FILE Import tunnels from a Bitvise .tlp file
--profiles-dir Print the profiles directory path
--version, -v Show version number
--help, -h Show help message

Examples

# Show profile selector (when multiple profiles exist)
stm

# Open a specific profile by name
stm production

# Open a profile file directly
stm ~/configs/my-server.stm

# Create a new profile
stm --new staging

# Import tunnels from Bitvise and create a profile
stm --new work --import ~/Downloads/office.tlp

# List all profiles (* marks last used)
stm --list

# Always show profile selector
stm --select

Profile Management

Profiles allow you to maintain separate configurations for different servers or environments.

Creating profiles:

# Via command line
stm --new production

# Or press 'n' in the profile selector

Switching profiles:

# Open specific profile
stm work

# Or use the profile selector
stm --select

Listing profiles:

stm --list
# Output:
# Available profiles:
#   default
#   production *    <- last used
#   staging

Profile Selector

When you have multiple profiles, the profile selector appears on startup:

                    SSH Tunnel Manager
                     Profile Selector

    β”Œβ”€ Profiles ─────────────────────────────────────┐
    β”‚  β–Ά production β˜…                                β”‚
    β”‚    staging                                     β”‚
    β”‚    development                                 β”‚
    β”‚    default                                     β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

    Server: ubuntu@prod.example.com:22
    Tunnels: 5/8 enabled

         Enter: Open  |  n: New  |  q: Quit  |  j/k: Navigate
Key Action
j / ↓ Move down
k / ↑ Move up
Enter Open selected profile
n Create new profile
g Go to top
G Go to bottom
q / Esc Quit

The β˜… symbol marks your last used profile.

Main Interface

SSH Tunnel Manager [production] (3/5 enabled)    ubuntu@server.com [●]

 #   β”‚ ST β”‚ Listen Addr     β”‚    Port β”‚ Remote Addr       β”‚    Port β”‚ Name
─────┼────┼─────────────────┼─────────┼───────────────────┼─────────┼──────────
  1  β”‚ ●  β”‚ 127.0.0.1       β”‚    8080 β”‚ 172.16.100.10     β”‚      80 β”‚ Web App
  2  β”‚ ●  β”‚ 127.0.0.1       β”‚    5432 β”‚ 172.16.100.20     β”‚    5432 β”‚ PostgreSQL
> 3* β”‚ ●  β”‚ 127.0.0.1       β”‚    6379 β”‚ 172.16.100.30     β”‚    6379 β”‚ Redis
  4  β”‚ β—‹  β”‚ 127.0.0.1       β”‚    3306 β”‚ 172.16.100.40     β”‚    3306 β”‚ MySQL
  5  β”‚ β—‹  β”‚ 127.0.0.1       β”‚    9000 β”‚ 172.16.100.50     β”‚    9000 β”‚ Minio

─── Logs ───────────────────────────────────────────────────────────────────
[INF] 14:23:01 SSH Tunnel Manager started
[INF] 14:23:01 Profile: production
[INF] 14:23:05 Connected! 3 tunnels active

j/k:nav Space:toggle i:edit a:add d:del s:ssh c:connect l:logs :help

Interface elements:

Element Meaning
[production] Current profile name
(3/5 enabled) 3 of 5 tunnels are enabled
[●] Connected to SSH server
[β—‹] Disconnected
[...] Connecting
> Selected row
* Unsaved changes
Green text Enabled tunnel
Gray text Disabled tunnel

Keyboard Shortcuts

Navigation

Key Action
j / ↓ Move down
k / ↑ Move up
g Go to first tunnel
G Go to last tunnel

Tunnel Operations

Key Action
Space Toggle tunnel enabled/disabled
i Edit selected tunnel
a Add new tunnel
d Delete selected tunnel

Connection

Key Action
c Connect or disconnect
s Open SSH settings

Other

Key Action
l Enter log scroll mode
: Enter command mode
q Quit (warns if unsaved)

Edit Mode (when editing a tunnel)

Key Action
Tab Next field
Shift+Tab Previous field
Enter Save changes
Esc Cancel editing

Log Mode (when viewing logs)

Key Action
j / ↓ Scroll down (newer)
k / ↑ Scroll up (older)
g Go to oldest log
G Go to newest log
PgUp / PgDn Page up/down
l / q / Esc Exit log mode

Commands

Enter command mode by pressing :, then type a command and press Enter.

File Operations

Command Description
:w Save profile
:wc Save profile and reconnect tunnels
:q Quit (warns if unsaved changes)
:q! Force quit without saving
:wq Save and quit

Connection

Command Description
:c or :connect Connect to SSH server
:dc or :disconnect Disconnect from SSH server
:ssh Open SSH settings editor

Tunnel Management

Command Description
:all on or :enable all Enable all tunnels
:all off or :disable all Disable all tunnels
:sort <field> Sort tunnels by field
:import <path> Import tunnels from .tlp file

Sort fields: id, name, port, remote

Settings

Command Description
:verbose or :v Toggle verbose SSH logging
:retry or :autoretry Toggle auto-reconnect
:profiles List all available profiles

Help

Command Description
:help Show available commands

Configuration

Directory Structure

~/.config/ssh-tunnel-manager/
β”œβ”€β”€ profiles/
β”‚   β”œβ”€β”€ default.stm      # Default profile
β”‚   β”œβ”€β”€ production.stm   # Custom profiles
β”‚   β”œβ”€β”€ staging.stm
β”‚   └── ...
└── state.json           # Application state (last profile, etc.)

Profile File Format

Profiles are stored as JSON files with .stm extension:

{
  "name": "production",
  "ssh": {
    "host": "server.example.com",
    "port": 22,
    "user": "ubuntu",
    "key_file": "~/.ssh/production_key"
  },
  "tunnels": [
    {
      "listen_host": "127.0.0.1",
      "listen_port": 8080,
      "remote_host": "172.16.100.10",
      "remote_port": 80,
      "name": "Web Application",
      "enabled": true
    },
    {
      "listen_host": "127.0.0.1",
      "listen_port": 5432,
      "remote_host": "172.16.100.20",
      "remote_port": 5432,
      "name": "PostgreSQL Database",
      "enabled": true
    }
  ]
}

State File

The state.json file tracks application state:

{
  "last_profile": "production",
  "recent_profiles": ["production", "staging", "default"],
  "auto_connect": false
}

Importing from Bitvise

You can import tunnel configurations from Bitvise SSH Client .tlp files:

# Import into a new profile
stm --new work --import ~/Downloads/office-tunnels.tlp

# Import into existing profile (via command mode)
stm work
# Then type: :import ~/Downloads/office-tunnels.tlp

The importer extracts:

  • SSH host, port, and username
  • All tunnel configurations (local port forwarding)
  • Tunnel names and enabled states

Troubleshooting

Connection Issues

"Permission denied" error:

  • Check that your key file path is correct
  • Ensure the key file has proper permissions: chmod 600 ~/.ssh/your_key
  • Verify the username is correct

"Connection refused" error:

  • Verify the SSH server is running on the target host
  • Check the port number (default: 22)
  • Ensure firewall allows SSH connections

"Host key verification failed":

  • The server's host key has changed or is unknown
  • Connect once manually with ssh user@host to accept the key

PPK Key Conversion

If using PuTTY .ppk keys:

# Install puttygen on macOS
brew install putty

# Install on Ubuntu/Debian
sudo apt install putty-tools

The application automatically converts PPK keys to OpenSSH format when needed.

Verbose Mode

Enable verbose logging for debugging connection issues:

  1. Press : to enter command mode
  2. Type verbose and press Enter
  3. Try connecting again
  4. Check the log panel for detailed SSH output

Log Scrolling

If logs scroll too fast:

  1. Press l to enter log mode
  2. Use j/k to scroll through logs
  3. Press l or Esc to exit log mode

Requirements

  • Python 3.9+
  • SSH client - OpenSSH (ssh command must be available)
  • curses - Included in Python on Unix systems
  • puttygen (optional) - For PPK key conversion

Platform Support

Platform Status
macOS Fully supported
Linux Fully supported
Windows Not supported (curses limitation)

Project Structure

ssh-tunnel-manager/
β”œβ”€β”€ src/
β”‚   └── ssh_tunnel_manager/
β”‚       β”œβ”€β”€ __init__.py      # Package exports
β”‚       β”œβ”€β”€ cli.py           # Command line interface
β”‚       β”œβ”€β”€ config.py        # Profile & configuration management
β”‚       β”œβ”€β”€ ssh_manager.py   # SSH connection handling
β”‚       β”œβ”€β”€ tlp_parser.py    # Bitvise .tlp file parser
β”‚       └── tui.py           # Terminal UI components
β”œβ”€β”€ main.py                  # Development entry point
β”œβ”€β”€ pyproject.toml           # Package configuration
β”œβ”€β”€ README.md                # This file
└── LICENSE                  # MIT License

License

MIT License - see LICENSE for details.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

About

A terminal UI for managing SSH port forwarding tunnels with profile support. Inspired by Bitvise SSH Client's tunnel management feature.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages