SSH Commander is a powerful, colorful command-line tool for executing commands across multiple SSH servers simultaneously. It supports both password and key-based authentication, custom ports, and can execute both single commands and command files.
- 🔑 Supports both password and key-based authentication
- 🌈 Colorized output for better readability
- 📁 Execute commands from files
- 🔄 Interactive server management
- 🔒 Secure password handling (never shown in terminal)
- 🚀 Single binary deployment
- ⚙️ YAML-based configuration
- 📊 Real-time output streaming
- ⌨️ Graceful interrupt handling (Ctrl+C support)
Ubuntu/Debian:
- Modern systems:
libffi8andlibssl3 - Older systems:
libffi7andlibssl1.1
CentOS/RHEL:
- Modern systems:
libffi-8andopenssl-3 - Older systems:
libffi-7andopenssl-1.1
- Microsoft Visual C++ Redistributable
- No additional requirements
- Download the latest .deb package from the releases page
- Install using dpkg:
sudo dpkg -i ssh-commander_*.debIf you encounter any dependency errors during installation, run:
sudo apt -f installThis will automatically install any missing dependencies and complete the installation.
- Download the latest release for your platform from the releases page
- Extract the archive
- Run the installation script:
./install.sh # For macOS/Linux
.\install.ps1 # For Windows (Run as Administrator)- Clone the repository:
git clone https://github.com/AthenaNetworks/ssh_commander.git
cd ssh_commander- Create a virtual environment and install dependencies:
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt- Build the executable:
./build_all.shSSH Commander stores server configurations in ~/.config/ssh-commander/servers.yaml. This file is automatically created when you add your first server.
The configuration file uses YAML format and supports both key-based and password authentication:
# Key-based authentication (recommended)
- hostname: web1.example.com
username: admin
key_file: ~/.ssh/id_rsa # Path to your SSH key
port: 22 # Optional, defaults to 22
tags: [prod, web] # Optional, defaults to ['default']
# Password authentication
- hostname: db1.example.com
username: dbadmin
password: your_secure_password # Not recommended for production use
port: 2222
tags: [prod, db] # Optional server tags- Passwords are stored in plaintext and are NOT secure
- Anyone with access to your config file can see the passwords
- This includes backup systems, cloud sync, etc.
✅ Recommended Approach:
- Use key-based authentication instead
- Generate an SSH key:
ssh-keygen -t ed25519 - Copy to server:
ssh-copy-id user@hostname - Use
key_file: ~/.ssh/id_ed25519in config
- Generate an SSH key:
- Config file is searched for in the following order:
- Path specified by
--configargument servers.yamlin the same directory as the executable~/.config/ssh-commander/servers.yaml
- Path specified by
- File permissions are set to user-only read/write (600)
- SSH key paths support
~expansion to your home directory
- Add a new server interactively:
ssh-commander add- Add a server non-interactively (great for scripts/automation):
ssh-commander add -y \
--hostname web1.example.com \
--username admin \
--key-file ~/.ssh/id_ed25519 \
--tags prod,web- Edit an existing server in place:
ssh-commander edit web1.example.com --port 2222 --tags prod,web,frontend
ssh-commander edit web1.example.com --rename web1-new.example.com
ssh-commander edit db1.example.com --key-file ~/.ssh/id_ed25519- List configured servers (with optional filter and machine-readable output):
ssh-commander list # pretty
ssh-commander list -t prod -o hosts # one hostname per line
ssh-commander list -o json # JSON dump for jq/scripting- Remove one or more servers (prompts for confirmation):
ssh-commander remove web1.example.com web2.example.com
ssh-commander remove old-host.example.com --yes # no prompt- Test SSH connectivity to all (or a subset of) servers:
ssh-commander test
ssh-commander test -t prod --parallel 8- Show the resolved config file path:
ssh-commander config-path- Run a single command on all servers:
ssh-commander exec -c "uptime"- Run a command on servers with specific tags:
ssh-commander exec -c "uptime" -t prod,web- Run a command across many servers in parallel:
ssh-commander exec -c "uptime" --parallel 8- Run multiple commands from a file:
ssh-commander exec -f commands.txt- Run commands from file on specific tags, stopping on the first failure:
ssh-commander exec -f commands.txt -t staging --stop-on-errorExample commands.txt:
# This is a comment - it will be skipped.
uptime
df -h
free -m
who- Use a different config file:
ssh-commander --config prod-servers.yaml exec -c "docker ps"All commands accept the following global options:
| Flag | Description |
|---|---|
--config FILE |
Override the config file path. |
--timeout SECONDS |
SSH connect/banner/auth timeout (default 10). |
--no-color |
Disable ANSI color output (also respects piped output where possible). |
-q, --quiet |
Suppress informational output (errors still print). |
-v, --verbose |
Print extra diagnostic detail (incl. tracebacks on failure). |
--strict-host-key-checking |
Reject unknown SSH host keys instead of auto-adding them. |
| Code | Meaning |
|---|---|
0 |
Success. |
1 |
User error (bad flags, missing config, etc.). |
2 |
Invalid CLI argument. |
3 |
One or more servers exited non-zero / failed connectivity. |
4 |
DNS / network error. |
130 |
Interrupted (Ctrl+C). |
- Check system status across all servers:
ssh-commander exec -c "systemctl status nginx"- Deploy updates:
ssh-commander exec -c "sudo apt update && sudo apt upgrade -y"- Monitor disk space:
ssh-commander exec -c "df -h / /var /home"- Check running Docker containers:
ssh-commander exec -c "docker ps --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}'"- Execute a maintenance script:
# maintenance.txt
systemctl status nginx
df -h
free -m
find /var/log -type f -size +100M -exec ls -lh {} \;
# Run maintenance checks
ssh-commander exec -f maintenance.txtSSH Commander uses colors to make output more readable:
- 🔵 Server names are highlighted in blue
- 🟢 Successful output is shown in green
- 🔴 Errors are displayed in red
- 🟣 Command execution status in purple
-
Password Storage:
- Passwords in the config file should be treated with care
- Consider using key-based authentication when possible
- Use appropriate file permissions for your config file:
chmod 600 servers.yaml
-
SSH Keys:
- Key files should have proper permissions:
chmod 600 ~/.ssh/id_rsa - Consider using different keys for different server groups
- Key files should have proper permissions:
-
Network Security:
- Be mindful of firewalls and network policies
- Use custom ports if needed
- Consider using jump hosts for isolated networks
- Fork the repository
- Create your 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
This project is licensed under the GNU General Public License v3.0 (GPL-3.0) - see the LICENSE file for details.
Key points of the GPL-3.0 license:
- ✅ You can use this software for commercial purposes
- ✅ You can modify the source code
- ✅ You can distribute your modifications
⚠️ You must disclose the source code of your modifications⚠️ You must license your modifications under the GPL-3.0⚠️ You must state the significant changes you made
If you encounter any issues or have questions:
- Check the Issues page
- Create a new issue with detailed information about your problem
- Include your OS version and Python version when reporting bugs
