Skip to content

Latest commit

 

History

16 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

go install go-ssh

Go SSH Host Manager

A full-screen TUI (terminal UI) application written in Go for organizing SSH hosts in a tree structure and connecting to them quickly.

Features

  • 🎨 Full-screen terminal user interface (TUI)
  • 🌳 Tree-based category and host organization
  • 📁 Nested categories support
  • ⌨️ Keyboard navigation with arrow keys or Vim-style keys
  • 🔗 SSH connections via multiple hosts (jump hosts)
  • 📜 Sequential command execution for complex connection scenarios
  • 🤖 Interactive mode for automatic password entry and command sending
  • 📝 YAML-based configuration
  • 🏠 Automatic config management under the user home directory

Installation

go build -o go-ssh
sudo mv go-ssh /usr/local/bin/

or:

go install

Usage

Run the application:

go-ssh

On first run, the config file ~/.go-ssh/config.yaml will be created automatically.

Keyboard Shortcuts

Key Action
↑/↓ or j/k Navigate up/down
←/→ or h/l Collapse/expand category
Enter or Space Open/close category or connect to host
e Expand all categories
C (Shift+c) Collapse all categories
p Open password manager
c Open config editor
q or Ctrl+C Quit

Configuration

Config file path: ~/.go-ssh/config.yaml

Tree Structure

Categories can be nested. Each category can contain both subcategories and hosts:

categories:
  - name: Production
    description: Production environment servers
    categories:
      - name: Web Servers
        description: Frontend web servers
        hosts:
          - name: Web Server 1
            description: Primary web server
            command: ssh -t jumphost@bastion "ssh -t deploy@web1 'cd /var/www && exec bash'"
          - name: Web Server 2
            description: Secondary web server
            command: ssh -t jumphost@bastion "ssh -t deploy@web2 'cd /var/www && exec bash'"
      - name: Database Servers
        description: Database servers
        hosts:
          - name: MySQL Master
            description: Primary MySQL server
            command: ssh -t jumphost@bastion "ssh -t dba@mysql-master 'exec bash'"
    hosts:
      - name: Bastion Host
        description: Jump server for production
        command: ssh jumphost@bastion

  - name: Staging
    description: Staging environment
    hosts:
      - name: Staging Server
        description: Staging environment server
        command: ssh deploy@staging

  - name: Development
    description: Development servers
    categories:
      - name: Local VMs
        description: Local virtual machines
        hosts:
          - name: Dev VM 1
            description: Development VM
            command: ssh dev@192.168.1.100
    hosts:
      - name: Dev Server
        description: Main development server
        command: ssh dev@devserver

Config Schema

Category:

  • name: Category name
  • description: Description (optional)
  • icon: Emoji icon (optional)
  • categories: Subcategories (optional)
  • hosts: Hosts (optional)

Host:

  • name: Display name of the host
  • description: Host description (optional)
  • command: Single SSH command to run (for simple connections)
  • commands: List of commands to run sequentially (for complex connections)

Note: For a host you should use either command or commands, not both.

Simple Connection Example

Direct connection with a single command:

hosts:
  - name: Production Server
    description: Main production server
    command: ssh user@production.example.com

Complex Connection Example (Sequential Commands)

For multi-hop connections or jump hosts:

hosts:
  - name: Inner Server
    description: Server behind jump host
    commands:
      - ssh jumphost@bastion.example.com   # Connect to bastion first
      - sleep 2                             # Wait for connection to establish
      - ssh user@internal-server            # Then connect to internal server

  - name: Complex Setup
    description: Multi-step connection
    commands:
      - echo "Connecting to production..."
      - ssh -t jump@gateway "cd /opt/scripts && ./prepare.sh"
      - sleep 1
      - ssh -t jump@gateway "ssh app@prod-server"

How Sequential Commands Work:

  • The first SSH command is detected and extended with -tt (for terminal allocation).
  • All subsequent commands are embedded as remote commands executed within the first SSH session.
  • If the last command is an SSH command, it is run via exec so that the user is attached directly to that session.
  • Example: ["ssh host1", "sleep 2", "ssh host2"] → ssh -tt host1 'sleep 2; exec ssh host2'

Example Transformation:

commands:
  - ssh jumphost@bastion
  - sleep 2
  - ssh user@internal-server

Automatically becomes:

ssh -tt jumphost@bastion 'sleep 2; exec ssh user@internal-server'

Interactive Mode (Automatic Password/Command Input)

Interactive mode lets the Go app control the SSH connection via a PTY (pseudo-terminal). This allows you to:

  • Automatically enter passwords
  • Send commands after the connection is established
  • Finally hand control back to the user

Special Command Prefixes:

  • SEND:text – Send text to the terminal (followed by Enter)
  • SENDPASS:id – Send password from password manager (followed by Enter)
  • WAIT:N – Wait N seconds (e.g., WAIT:5 waits 5 seconds)
  • EXPECT:text – Wait until the specified text appears in output (30 second timeout)
  • INTERACT – Give control back to the user

Example 1: Login with Password

hosts:
  - name: Server with Password
    description: Auto-login with password
    commands:
      - ssh user@server.com          # Start SSH
      - WAIT:2                       # Wait 2 seconds for password prompt
      - SEND:mypassword123           # Send password
      - INTERACT                     # Hand control to user

Example 2: Using EXPECT for Dynamic Prompts

hosts:
  - name: Server with EXPECT
    description: Wait for specific prompts instead of fixed delays
    commands:
      - ssh user@server.com          # Start SSH
      - EXPECT:Password:             # Wait until "Password:" appears in output
      - SEND:mypassword123           # Send password
      - EXPECT:$                     # Wait until shell prompt appears
      - SEND:cd /opt/app             # Change directory
      - INTERACT                     # Hand control to user
  - WAIT:2                       # Wait for password prompt
  - SEND:mypassword123           # Send password
  - INTERACT                     # Hand control to user

**Example 3: Password + Automatic Commands**
```yaml
hosts:
  - name: Auto Setup Server
    description: Login and run setup commands
    commands:
      - ssh user@server.com
      - EXPECT:Password:             # Wait for password prompt (better than fixed WAIT)
      - SEND:mypassword              # Send password
      - EXPECT:$                     # Wait for shell prompt
      - SEND:cd /opt/app             # Change directory
      - SEND:./setup.sh              # Run script
      - INTERACT                     # User continues

Example 4: Complex Scenario with Jump Host and Passwords

hosts:
  - name: Multi-Hop with Passwords
    description: Jump through multiple hosts with passwords
    commands:
      - ssh jumphost@bastion.com
      - EXPECT:Password:             # More reliable than WAIT:2
      - SEND:bastion_password
      - EXPECT:$                     # Wait for shell prompt
      - SEND:ssh user@internal-server
      - EXPECT:Password:
      - SEND:internal_password
      - INTERACT

EXPECT vs WAIT:

  • WAIT:N – Waits for a fixed number of seconds. Simple but may wait too long or too short depending on network conditions.
  • EXPECT:text – Waits until specific text appears in the output (max 30 seconds). More reliable for dynamic scenarios like waiting for prompts.
  • Use EXPECT when you need to wait for specific output (like "Password:", prompt symbols "$" or "#")
  • Use WAIT for simple delays where timing is predictable

🔐 Password Manager

Go-SSH includes a built-in password manager to store your passwords securely. Passwords are encrypted with AES-256-GCM and stored safely on disk.

Using the Password Manager

Open the password manager from the host selector by pressing p.

Note: The legacy ./go-ssh --passwords flag still works for backward compatibility, but the main way to access it is through the p shortcut on the host selector screen.

On first run, you will be asked to create a master password. This master password protects all stored secrets.

Password Manager Shortcuts

Key Action
↑/↓ or j/k Navigate through stored passwords
a Add a new password
e Edit the selected password
d Delete the selected password
Enter or v View the selected password
m Change the master password
q or Esc Return to the host selector

Each password has:

  • ID: Unique identifier for the secret (e.g. prod-db, staging-app)
  • Description: Description for the secret
  • Password: The password to store

Using SENDPASS in Config

To use stored passwords in SSH connections, use the SENDPASS:password_id command:

categories:
  - name: Production
    hosts:
      - name: Database Server
        description: Production database with password
        commands:
          - ssh user@db-server.com
          - SENDPASS:prod-db        # Send password from password manager
          - INTERACT

Security Features

  • ✅ AES-256-GCM encryption
  • ✅ PBKDF2 key derivation (100,000 iterations)
  • ✅ Encryption with a master password
  • ✅ Only encrypted data stored on disk
  • ✅ File permissions 0600 (owner read/write only)
  • ✅ Passwords are decrypted in memory only when needed

Example Workflow

  1. Run go-ssh:

    ./go-ssh
  2. Open the password manager by pressing p.

  3. Add a new password:

    • ID: prod-web
    • Description: Production web server password
    • Password: <your-secure-password>
  4. Use it in your config (or add it via the config editor by pressing c):

    - name: Web Server
      commands:
        - ssh admin@web-server.com
        - SENDPASS:prod-web
        - INTERACT
  5. Press q to return to the host selector, select the host, and enter your master password for automatic login.

Security Note: The password manager uses AES-256 encryption and is designed to be secure, but in production environments you should prefer SSH key authentication whenever possible. Storing plain passwords directly in the YAML config (e.g. via SEND:) is not recommended.

Config Editor

Go-SSH includes a built-in config editor so you can manage hosts and categories without manually editing YAML files.

Opening the Config Editor

From the host selector, press c to open the config editor.

Config Editor Shortcuts

Key Action
↑/↓ or j/k Navigate the config tree
←/→ or h/l Collapse/expand categories
a Add a category or host under the selection
e Edit the selected category or host
d Delete the selected category or host
s Confirm all changes are saved
q or Esc Return to the host selector

Adding New Entries

When you add a new category or host, the editor will ask you to choose a target file:

  • ~/.go-ssh/config.yaml (main config)
  • Any existing .yaml file in ~/.go-ssh/conf.d/
  • A new file under ~/.go-ssh/conf.d/

This keeps modular configs organized while editing from a single UI.

Important Notes

  • The config editor writes YAML files atomically.
  • YAML comments in edited files may be lost after saving because the editor re-serializes the structure.
  • When multiple conf.d files define a category with the same name, they are merged into a single tree in the UI. Editing that category updates the source file of the first occurrence.

UI Preview

┌─────────────────────────────────────────────────────────────┐
│ 🔐 SSH Host Manager                            Hosts: 7     │
├─────────────────────────────────────────────────────────────┤
│   ▼ 🔴 Production                                           │
│     ▼ 🌐 Web Servers                                        │
│ ➤       🖥️ Web Server 1                                     │
│         🖥️ Web Server 2                                     │
│     ▶ 🗄️ Database Servers                                   │
│       🖥️ Bastion Host                                       │
│   ▶ 🟡 Staging                                              │
│   ▶ 🟢 Development                                          │
├─────────────────────────────────────────────────────────────┤
│ 🖥️ Web Server 1                                             │
│ Primary web server                                          │
│                                                             │
│ 💻 Command: ssh -t jumphost@bastion "ssh -t deploy@web1..." │
├─────────────────────────────────────────────────────────────┤
│ ↑↓/jk: Navigate  ←→/hl: Collapse/Expand  Enter: Select     │
└─────────────────────────────────────────────────────────────┘

Modular Configuration with conf.d

For large configurations, you can split your config into multiple files using the conf.d directory.

How It Works

All .yaml and .yml files in ~/.go-ssh/conf.d/ are automatically loaded and merged with the main config file. This allows you to organize your hosts by team, environment, or any other criteria.

Categories with the same name across multiple files are merged into a single tree. For example, if conf.d/turkcell-inventum.yaml, conf.d/turkcell-monicat.yaml, and conf.d/turkcell-star.yaml each define a root category named Turkcell, they will appear as one Turkcell category with Inventum, MoniCat, and Star subcategories.

Directory Structure

~/.go-ssh/
├── config.yaml              # Main config (optional, can be empty)
├── conf.d/
│   ├── production.yaml      # Production servers
│   ├── staging.yaml         # Staging servers
│   ├── development.yaml     # Development servers
│   ├── team-backend.yaml    # Backend team servers
│   └── team-frontend.yaml   # Frontend team servers
└── README.md                # Auto-generated documentation

Example

Main config (~/.go-ssh/config.yaml):

# Can be empty or contain common/shared categories
categories: []

conf.d/production.yaml:

categories:
  - name: Production
    description: Production environment
    hosts:
      - name: Web Server
        description: Production web server
        command: ssh user@web.prod.example.com

conf.d/staging.yaml:

categories:
  - name: Staging
    description: Staging environment
    hosts:
      - name: Staging Server
        command: ssh user@staging.example.com

All files are automatically loaded and merged when you run go-ssh.

Benefits

  • 📁 Organization: Split large configs into logical units
  • 👥 Team collaboration: Each team can maintain their own config file
  • 🔄 Easy updates: Add/remove servers by adding/removing files
  • 🚀 No code changes: Works automatically, no setup needed

Development

To run the project:

go run main.go

To build:

go build -o go-ssh

Dependencies

License

MIT

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages