š SSHM - SSH Manager

> A modern, interactive SSH Manager for your terminal š„
SSHM is a beautiful command-line tool that transforms how you manage and connect to your SSH hosts. Built with Go and featuring an intuitive TUI interface, it makes SSH connection management effortless and enjoyable.
<em>š±ļø Click on the image to view in full size</em>
⨠Features
š Core Capabilities
- šØ Beautiful TUI Interface - Navigate your SSH hosts with an elegant, interactive terminal UI
- ā” Quick Connect - Connect to any host instantly through the TUI or the CLI with
sshm
- š Port Forwarding - Easy setup for Local, Remote, and Dynamic (SOCKS) forwarding with history persistence
- š Easy Management - Add, edit, move, and manage SSH configurations seamlessly
- š·ļø Tag Support - Organize your hosts with custom tags for better categorization; use the special
hidden tag to exclude hosts from the list while keeping them connectable
- š Smart Search - Find hosts quickly with built-in filtering and search
- š Connectivity Status - Color-coded SSH connectivity indicators, checked in the background when the TUI starts and on demand
- š Smart Updates - Automatic version checking with update notifications
- š Connection History - Track your SSH connections with last login timestamps
š ļø Technical Features
- š Secure - Works directly with your existing
~/.ssh/config file
- š Custom Config Support - Use any SSH configuration file with the
-c flag
- š SSH Include Support - Full support for SSH Include directives to organize configurations across multiple files
- āļø SSH Options Support - Add any SSH configuration option through intuitive forms
- š Automatic Conversion - Seamlessly converts between command-line and config formats
- š Automatic Backups - Backup configurations automatically before changes
- ā
Validation - Prevent configuration errors with built-in validation
- š ProxyJump/ProxyCommand Support - Secure connection tunneling through bastion hosts
- āØļø Keyboard Shortcuts - Power user navigation with vim-like shortcuts
- š Cross-platform - Supports Linux, macOS (Intel & Apple Silicon), and Windows
- ā” Lightweight - Single binary with no dependencies, zero configuration required
š Quick Start
Installation
Homebrew (Recommended for macOS):
brew install Gu1llaum-3/sshm/sshm
Unix/Linux/macOS (One-line install):
curl -sSL https://raw.githubusercontent.com/Gu1llaum-3/sshm/main/install/unix.sh | bash
Windows (PowerShell):
irm https://raw.githubusercontent.com/Gu1llaum-3/sshm/main/install/windows.ps1 | iex
Alternative methods:
Linux/macOS:
# Download specific release
wget https://github.com/Gu1llaum-3/sshm/releases/latest/download/sshm-linux-amd64.tar.gz
# Extract and install
tar -xzf sshm-linux-amd64.tar.gz
sudo mv sshm-linux-amd64 /usr/local/bin/sshm
Windows:
# Download and extract
Invoke-WebRequest -Uri "https://github.com/Gu1llaum-3/sshm/releases/latest/download/sshm-windows-amd64.zip" -OutFile "sshm-windows-amd64.zip"
Expand-Archive sshm-windows-amd64.zip -DestinationPath C:\tools\
# Add C:\tools to your PATH environment variable
š Usage
Interactive Mode
Launch SSHM without arguments to enter the beautiful TUI interface:
sshm
Search (focused at startup):
- Type to filter hosts by name, hostname or tag
ā/ā or Ctrl+P/Ctrl+N - Select a host without leaving the search
Enter - Connect to the selected host
Esc - Clear the search (quits when the search is empty)
Tab - Switch to the host table, where the shortcuts below work
Host table:
ā/ā or j/k - Navigate hosts
Enter - Connect to selected host
a - Add new host
e - Edit selected host
d - Delete selected host
m - Move host to another config file (requires SSH Include directives)
f - Port forwarding setup
p - Check the status of all hosts again
H - Toggle hidden hosts visibility
q - Quit
/ or Tab - Back to the search
Status Indicators (checked when the TUI starts, and again with p):
- š¢ Online - Host is reachable via SSH
- š” Connecting - Currently checking host connectivity
- š“ Offline - Host is unreachable or SSH connection failed
- ā« Unknown - Connectivity status not yet determined
Sorting & Filtering:
s - Switch between sorting modes (name ā last login)
n - Sort by name (alphabetical)
r - Sort by recent (last login time)
The interactive forms will guide you through configuration:
- Hostname/IP - Server address
- Username - SSH user
- Port - SSH port (default: 22)
- Identity File - Private key path
- ProxyJump - Jump server for connection tunneling
- ProxyCommand - Jump command for connection tunneling
- SSH Options - Additional SSH options in
-o format (e.g., -o Compression=yes -o ServerAliveInterval=60)
- Tags - Comma-separated tags for organization
Port Forwarding
SSHM provides an intuitive interface for setting up SSH port forwarding. Press f while selecting a host to open the port forwarding setup:
Forward Types:
-
Local (-L) - Forward a local port to a remote host/port through the SSH connection
- Example: Access a remote database on
localhost:5432 via local port 15432
- Use case:
ssh -L 15432:localhost:5432 server ā Database accessible on localhost:15432
-
Remote (-R) - Forward a remote port back to a local host/port
- Example: Expose local web server on remote host's port
8080
- Use case:
ssh -R 8080:localhost:3000 server ā Local app accessible from remote host's port 8080
- ā ļø Requirements for external access:
- SSH Server Config: Add
GatewayPorts yes to /etc/ssh/sshd_config and restart SSH service
- Firewall: Open the remote port in the server's firewall (
ufw allow 8080 or equivalent)
- Port Availability: Ensure the remote port is not already in use
- Bind Address: Use
0.0.0.0 for external access, 127.0.0.1 for local-only
-
Dynamic (-D) - Create a SOCKS proxy for secure browsing
- Example: Route web traffic through the SSH connection
- Use case:
ssh -D 1080 server ā Configure browser to use localhost:1080 as SOCKS proxy
- ā ļø Configuration requirements:
- Browser Setup: Configure SOCKS v5 proxy in browser settings
- DNS: Enable "Proxy DNS when using SOCKS v5" for full privacy
- Applications: Only SOCKS-aware applications will use the proxy
- Bind Address: Use
127.0.0.1 for security (local access only)
Port Forwarding Interface:
- Choose forward type with ā/ā arrow keys
- Configure ports and addresses with guided forms
- Optional bind address configuration (defaults to 127.0.0.1)
- Real-time validation of port numbers and addresses
- Port forwarding history - Save frequently used configurations for quick reuse
- Connect automatically with configured forwarding options
Troubleshooting Port Forwarding:
Remote Forwarding Issues:
# Error: "remote port forwarding failed for listen port X"
# Solutions:
1. Check if port is already in use: ssh server "netstat -tln | grep :X"
2. Use a different port that's available
3. Enable GatewayPorts in SSH config for external access
SSH Server Configuration for Remote Forwarding:
# Edit SSH daemon config on the server:
sudo nano /etc/ssh/sshd_config
# Add or uncomment:
GatewayPorts yes
# Restart SSH service:
sudo systemctl restart sshd # Ubuntu/Debian/CentOS 7+
# OR
sudo service ssh restart # Older systems
Firewall Configuration:
# Ubuntu/Debian (UFW):
sudo ufw allow [port_number]
# CentOS/RHEL/Rocky (firewalld):
sudo firewall-cmd --add-port=[port_number]/tcp --permanent
sudo firewall-cmd --reload
# Check if port is accessible:
telnet [server_ip] [port_number]
Dynamic Forwarding (SOCKS) Browser Setup:
Firefox: about:preferences ā Network Settings
- Manual proxy configuration
- SOCKS Host: localhost, Port: [your_port]
- SOCKS v5: ā
- Proxy DNS when using SOCKS v5: ā
Chrome: Launch with proxy
chrome --proxy-server="socks5://localhost:[your_port]"
CLI Usage
SSHM provides both command-line operations and an interactive TUI interface:
# Launch interactive TUI mode for browsing and connecting to hosts
sshm
# Connect directly to a specific host (with history tracking)
sshm my-server
# Execute a command on a remote host
sshm my-server uptime
# Execute command with arguments
sshm my-server ls -la /var/log
# Force TTY allocation for interactive commands
sshm -t my-server sudo systemctl restart nginx
# Launch TUI with custom SSH config file
sshm -c /path/to/custom/ssh_config
# Connect directly with custom SSH config file
sshm my-server -c /path/to/custom/ssh_config
# Add a new host using interactive form
sshm add
# Add a new host with pre-filled hostname
sshm add hostname
# Add a new host with custom SSH config file
sshm add hostname -c /path/to/custom/ssh_config
# Edit an existing host configuration
sshm edit my-server
# Edit host with custom SSH config file
sshm edit my-server -c /path/to/custom/ssh_config
# Move a host to another SSH config file (requires Include directives)
sshm move my-server
# Move host with custom SSH config file (requires Include directives)
sshm move my-server -c /path/to/custom/ssh_config
# Search for hosts (interactive filter)
sshm search
# Print machine-readable info (JSON) for scripting
sshm info prod-server
sshm info prod-server --pretty
# With a custom SSH config file
sshm -c /path/to/custom/ssh_config info prod-server
# Pipe to jq
sshm info prod-server | jq -r '.result.target.hostname'
sshm info prod-server | jq -r '.result.target.user'
# Show version information
sshm --version
# Disable automatic update check (useful on air-gapped machines)
sshm --no-update-check
# Show help and available commands
sshm --help
Host Info (JSON)
sshm info prints a single JSON object to stdout so you can script against it with jq.
# Extract fields
sshm info prod-server | jq -r '.result.target.hostname'
sshm info prod-server | jq -r '.result.target.port'
# Check not-found (exit code 2)
sshm info does-not-exist | jq -r '.error.code'
Shell Completion
SSHM supports shell completion for host names, making it easy to connect to hosts without typing full names:
sshm # Lists all available hosts
sshm pro # Completes to hosts starting with "pro" (e.g., prod-server)
Setup Instructions:
Bash:
# Enable for current session
source <(sshm completion bash)
# Enable permanently (add to ~/.bashrc)
echo 'source <(sshm completion bash)' >> ~/.bashrc
Zsh:
# Enable for current session
source <(sshm completion zsh)
# Enable permanently (add to ~/.zshrc)
echo 'source <(sshm completion zsh)' >> ~/.zshrc
Fish:
# Enable for current session
sshm completion fish | source
# Enable permanently
sshm completion fish > ~/.config/fish/completions/sshm.fish
PowerShell:
# Enable for current session
sshm completion powershell | Out-String | Invoke-Expression
# Enable permanently (add to your PowerShell profile)
Add-Content $PROFILE 'sshm completion powershell | Out-String | Invoke-Expression'
Direct Host Connection
SSHM supports direct connection to hosts via the command line, making it easy to integrate into your existing workflow:
# Connect directly to any configured host
sshm production-server
sshm db-staging
sshm web-01
# All direct connections are tracked in your history
# Use the TUI to see your most recently connected hosts
Features of Direct Connection:
- Instant connection - No TUI navigation required
- History tracking - All connections are recorded with timestamps
- Error handling - Clear messages if host doesn't exist or configuration issues
- Config file support - Works with custom config files using
-c flag
Remote Command Execution
Execute commands on remote hosts without opening an interactive shell:
# Execute a single command
sshm prod-server uptime
# Execute command with arguments
sshm prod-server ls -la /var/log
# Check disk usage
sshm prod-server df -h
# View logs (pipe to local commands)
sshm prod-server 'cat /var/log/nginx/access.log' | grep 404
# Force TTY allocation for interactive commands (sudo, vim, etc.)
sshm -t prod-server sudo systemctl restart nginx
Features:
- Exit code propagation - Remote command exit codes are passed through
- TTY support - Use
-t flag for commands requiring terminal interaction
- Pipe-friendly - Output can be piped to local commands for processing
- History tracking - Command executions are recorded in connection history
Backup Configuration
SSHM automatically creates backups of your SSH configuration files before making any changes to ensure your configurations are safe.
Backup Location:
- Unix/Linux/macOS:
~/.config/sshm/backups/ (or $XDG_CONFIG_HOME/sshm/backups/ if set)
- Windows:
%APPDATA%\sshm\backups\ (fallback: %USERPROFILE%\.config\sshm\backups\)
Key Features:
- Automatic backup before any modification
- One backup per file (overwrites previous backup)
- Stored separately to avoid SSH Include conflicts
- Easy manual recovery if needed
Additional Storage:
- Connection History: Stored in the same config directory for persistent tracking
- Port Forwarding History: Saved configurations for quick reuse of common forwarding setups
Quick Recovery:
# Unix/Linux/macOS
cp ~/.config/sshm/backups/config.backup ~/.ssh/config
# Windows
copy "%APPDATA%\sshm\backups\config.backup" "%USERPROFILE%\.ssh\config"
Configuration File Options
By default, SSHM uses the standard SSH configuration file at ~/.ssh/config. You can specify a different configuration file using the -c flag:
# Use custom config file in TUI mode
sshm -c /path/to/custom/ssh_config
# Use custom config file with commands
sshm add hostname -c /path/to/custom/ssh_config
sshm edit hostname -c /path/to/custom/ssh_config
sshm move hostname -c /path/to/custom/ssh_config
Advanced Features
Host Movement Between Config Files
SSHM provides a powerful move command to relocate SSH hosts between different configuration files. This feature requires SSH Include directives to be present in your SSH configuration.
# Move a host to another config file (requires Include directives)
sshm move my-server
# Move with custom config file (requires Include directives)
sshm move my-server -c /path/to/custom/ssh_config
ā ļø Important Requirements:
- SSH Include directives must be present in your SSH config file (either
~/.ssh/config or the file specified with -c)
- The config file must contain
Include statements referencing other SSH configuration files
- Without Include directives, the move command will display an error message
Features:
- Interactive file selector - Choose destination config file from Include directives
- Include support - Works seamlessly with SSH Include directives structure
- Atomic operations - Safe host movement with automatic backups
- Validation - Prevents conflicts and ensures configuration integrity
- Error handling - Clear messages when Include files are needed but not found
Use Cases:
- Reorganize hosts from main config to specialized include files
- Move development hosts to separate environment-specific configs
- Consolidate configurations for better organization
Example Setup Required:
Your main SSH config file must contain Include directives like:
# ~/.ssh/config
Include ~/.ssh/config.d/*
Include work-servers.conf
Include projects/*.conf
Host personal-server
HostName personal.example.com
User myuser
Connectivity Status
SSHM features asynchronous SSH connectivity checking that provides visual indicators of host availability:
Status Indicators:
- š¢ Online - SSH connection successful (shows response time)
- š” Connecting - Currently testing connectivity
- š“ Offline - SSH connection failed or host unreachable
- ā« Unknown - Status not yet determined
Features:
- Non-blocking checks - Status updates happen in the background
- Response time tracking - See connection latency for online hosts
- Checked at startup - Every visible host is checked when the TUI starts; press
p to check again. Set ping_on_start to false to check only on demand
- Error details - Detailed error information for failed connections
Automatic Update Checking
SSHM includes built-in version checking that notifies you of available updates:
Features:
- Background checking - Version check happens asynchronously, never blocking startup
- Release notifications - Clear indicators when updates are available
- Pre-release detection - Identifies beta and development versions
- GitHub integration - Direct links to release pages
- Non-intrusive - Updates don't interrupt your workflow
- Configurable - Can be disabled for air-gapped or offline environments
Update notifications appear:
- In the main TUI interface as a subtle notification
- Only when a newer stable version is available
Disabling update checks:
Via the CLI flag (one-time):
sshm --no-update-check
Via ~/.config/sshm/config.json (persistent):
{
"check_for_updates": false
}
Port Forwarding History
SSHM remembers your port forwarding configurations for easy reuse:
Features:
- Automatic saving - Successful forwarding setups are saved automatically
- Quick reuse - Previously used configurations appear as suggestions
- Per-host history - Forwarding history is tracked per SSH host
- All forward types - Supports Local (-L), Remote (-R), and Dynamic (-D) forwarding history
- Persistent storage - History survives application restarts
Windows:
- SSHM works with the built-in OpenSSH client (Windows 10/11)
- Configuration file location:
%USERPROFILE%\.ssh\config
- Compatible with WSL SSH configurations
- Supports the same SSH options as Unix systems
Unix/Linux/macOS:
- Standard SSH configuration file:
~/.ssh/config
- Full compatibility with OpenSSH features
- Preserves file permissions automatically
šļø Configuration
SSHM works directly with your standard SSH configuration file (~/.ssh/config). It adds special comment tags for enhanced functionality while maintaining full compatibility with standard SSH tools.
SSH Include Support
SSHM fully supports SSH Include directives, allowing you to organize your SSH configurations across multiple files. This is particularly useful for managing large numbers of hosts or organizing configurations by environment, project, or team.
Include Examples:
# Main ~/.ssh/config file
Host personal-server
HostName personal.example.com
User myuser
# Include work-related configurations
Include work-servers.conf
# Include all configurations from a directory
Include projects/*
# Include with relative paths
Include ~/.ssh/configs/production.conf
Organization Examples:
work-servers.conf:
# Tags: work, production
Host prod-web-01
HostName 10.0.1.10
User deploy
ProxyJump bastion.company.com
# Tags: work, staging
Host staging-api
HostName staging-api.company.com
User developer
projects/client-alpha.conf:
# Tags: client, development
Host client-alpha-dev
HostName dev.client-alpha.com
User admin
Port 2222
Example configuration:
Include ~/.ssh/conf.d/*
# Tags: production, web, frontend
Host web-prod-01
HostName 192.168.1.10
User deploy
Port 22
IdentityFile ~/.ssh/production_key
Compression yes
ServerAliveInterval 60
# Tags: development, database
Host db-dev
HostName dev-db.company.com
User admin
Port 2222
IdentityFile ~/.ssh/dev_key
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
# Tags: production, backend
Host backend-prod
HostName 10.0.1.50
User app
Port 22
ProxyJump bastion.company.com
ProxyCommand ssh -W %h:%p Jumphost
IdentityFile ~/.ssh/production_key
Compression yes
ServerAliveInterval 300
BatchMode yes
Supported SSH Options
SSHM supports all standard SSH configuration options:
Built-in Fields:
HostName - Server hostname or IP address
User - Username for SSH connection
Port - SSH port number
IdentityFile - Path to private key file
ProxyJump - Jump server for connection tunneling (e.g., user@jumphost:port)
ProxyCommand - Jump command for connection tunneling (e.g, ssh -W %h:%p Jumphost)
Tags - Custom tags (SSHM extension); the special tag hidden hides the host from the TUI and sshm search while keeping it connectable via sshm
Additional SSH Options:
You can add any valid SSH option using the "SSH Options" field in the interactive forms. Enter them in command-line format (e.g., -o Compression=yes -o ServerAliveInterval=60) and SSHM will automatically convert them to the proper SSH config format.
Common SSH Options:
Compression - Enable/disable compression (yes/no)
ServerAliveInterval - Interval in seconds for keepalive messages
ServerAliveCountMax - Maximum number of keepalive messages
StrictHostKeyChecking - Host key verification (yes/no/ask)
UserKnownHostsFile - Path to known hosts file
BatchMode - Disable interactive prompts (yes/no)
ConnectTimeout - Connection timeout in seconds
ControlMaster - Connection multiplexing (yes/no/auto)
ControlPath - Path for control socket
ControlPersist - Keep connection alive duration
ForwardAgent - Forward SSH agent (yes/no)
LocalForward - Local port forwarding (e.g., 8080:localhost:80)
RemoteForward - Remote port forwarding
DynamicForward - SOCKS proxy port forwarding
Example usage in forms:
SSH Options: -o Compression=yes -o ServerAliveInterval=60 -o StrictHostKeyChecking=no
This will be automatically converted to:
Compression yes
ServerAliveInterval 60
StrictHostKeyChecking no
Application Configuration
SSHM supports a configuration file to customize its behavior, including key bindings and update checking.
Configuration File Location:
- Linux/macOS:
~/.config/sshm/config.json
- Windows:
%APPDATA%\sshm\config.json
Example Configuration:
{
"check_for_updates": false,
"focus_search_on_start": false,
"ping_on_start": false,
"key_bindings": {
"quit_keys": ["q", "ctrl+c"],
"disable_esc_quit": true
}
}
Available Options:
- check_for_updates: Boolean to enable or disable the automatic update check at startup. Default:
true. Set to false on air-gapped or offline machines to avoid connection delays.
- focus_search_on_start: Boolean to choose where the focus is when the TUI starts. Default:
true (the search bar). Set to false to start on the host table; the -s / --search flag still starts on the search bar.
- ping_on_start: Boolean to check the status of every visible host when the TUI starts. Default:
true. Set to false to check only when you press p (for example with many hosts, or hosts behind a slow ProxyJump).
- quit_keys: Array of keys that will quit the application. Default:
["q", "ctrl+c"]
- disable_esc_quit: Boolean flag to disable ESC key from quitting the application. Default:
false
For Vim Users:
If you frequently press ESC accidentally causing the application to quit, set disable_esc_quit to true. This will disable ESC as a quit key while preserving all other functionality.
For Air-gapped Machines:
If SSHM is slow to start due to DNS timeouts when reaching GitHub, set check_for_updates to false. You can also use the --no-update-check CLI flag for a one-time override without editing the config file.
Default Configuration:
If no configuration file exists, SSHM will automatically create one with default settings that maintain backward compatibility.
š ļø Development
Prerequisites
Build from Source
# Clone the repository
git clone https://github.com/Gu1llaum-3/sshm.git
cd sshm
# Build the binary
go build -o sshm .
# Run
./sshm
Project Structure
sshm/
āāā main.go # Application entry point
āāā cmd/ # CLI commands (Cobra)
ā āāā root.go # Root command and interactive mode
ā āāā add.go # Add host command
ā āāā edit.go # Edit host command
ā āāā move.go # Move host command
ā āāā search.go # Search command
āāā internal/
ā āāā config/ # SSH configuration management
ā ā āāā ssh.go # Config parsing and manipulation
ā āāā connectivity/ # SSH connectivity checking
ā ā āāā ping.go # Asynchronous SSH ping functionality
ā āāā history/ # Connection history tracking
ā ā āāā history.go # History management and last login tracking
ā ā āāā port_forward_test.go # Port forwarding history tests
ā āāā version/ # Version checking and updates
ā ā āāā version.go # GitHub release checking and version comparison
ā ā āāā version_test.go # Version parsing and comparison tests
ā āāā ui/ # Terminal UI components (Bubble Tea)
ā ā āāā tui.go # Main TUI interface and program setup
ā ā āāā model.go # Core TUI model and state
ā ā āāā update.go # Message handling and state updates
ā ā āāā view.go # UI rendering and layout
ā ā āāā table.go # Host list table component with status indicators
ā ā āāā add_form.go # Add host form interface
ā ā āāā edit_form.go# Edit host form interface
ā ā āāā move_form.go# Move host form interface
ā ā āāā port_forward_form.go # Port forwarding setup with history
ā ā āāā styles.go # Lip Gloss styling definitions
ā ā āāā sort.go # Sorting and filtering logic
ā ā āāā utils.go # UI utility functions
ā āāā validation/ # Input validation
ā āāā ssh.go # SSH config validation
āāā images/ # Documentation assets
ā āāā logo.png # Project logo
ā āāā sshm.gif # Demo animation
āāā install/ # Installation scripts
ā āāā unix.sh # Unix/Linux/macOS installer
ā āāā README.md # Installation guide
āāā .github/ # GitHub configuration
ā āāā copilot-instructions.md # Development guidelines
ā āāā workflows/ # CI/CD pipelines
ā āāā build.yml # Multi-platform builds
āāā go.mod # Go module definition
āāā go.sum # Go module checksums
āāā LICENSE # MIT license
āāā README.md # Project documentation
Dependencies
š¦ Releases
Automated releases are built for multiple platforms:
š¤ Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
Development Workflow
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature)
- Commit your changes (
git commit -m 'Add amazing feature')
- Push to the branch (
git push origin feature/amazing-feature)
- Open a Pull Request
š License
This project is licensed under the MIT License - see the LICENSE file for details.
š Acknowledgments
- Charm for the amazing TUI libraries
- Cobra for the excellent CLI framework
- @yimeng for contributing SSH Include directive support
- @ldreux for contributing multi-word search functionality
- @qingfengzxr for contributing custom key bindings support
- The Go community for building such fantastic tools
Made with ā¤ļø by Guillaume
ā Star this repo if you found it useful! ā