Skip to content

jmsperu/xcossh

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

xcossh

A cross-platform SSH & Windows connection manager. Drop-in sshpass replacement with saved connections, WinRM, RDP session management, service control, and credential encryption.

Single binary. No dependencies. Works on Windows, macOS, and Linux.

4,600+ lines of Go. Manages both Linux (SSH) and Windows (WinRM/RDP) from one tool.


Table of Contents


Install

Download binary

Download the latest release for your platform:

Platform Binary
Windows (x64) xcossh-windows-amd64.exe
Linux (x64) xcossh-linux-amd64
Linux (ARM64) xcossh-linux-arm64
macOS (Apple Silicon) xcossh-darwin-arm64

Build from source

go install github.com/jmsperu/xcossh@latest

Homebrew (macOS/Linux)

brew tap jmsperu/tap
brew install xcossh

Quick Start

# 1. Add a Linux host
xcossh add quick mylinux 'root@192.168.1.100' 'MyPassword'

# 2. Add a Windows host
xcossh add quick mywindows 'admin@192.168.1.50' 'WinPass123' -P winrm

# 3. Connect
xcossh connect mylinux       # SSH terminal
xcossh connect mywindows     # interactive PowerShell

# 4. Run commands
xcossh exec mylinux "uptime"
xcossh exec mywindows "Get-Service"

# 5. Get system info
xcossh info mylinux
xcossh info mywindows

# 6. Encrypt your passwords
xcossh encrypt

Legacy sshpass Mode

Drop-in replacement for Linux sshpass. Works exactly the same way:

# Password on command line
xcossh -p MyPassword ssh user@192.168.1.100

# Password from environment variable
export SSHPASS=MyPassword
xcossh -e ssh user@192.168.1.100

# Password from file
echo "MyPassword" > /tmp/passfile
xcossh -f /tmp/passfile ssh user@192.168.1.100

# Run a remote command
xcossh -p MyPassword ssh user@host "uptime && df -h"

# With SSH flags (all standard flags supported)
xcossh -p MyPassword ssh -p 2222 -o StrictHostKeyChecking=no user@host

# SCP via legacy mode
xcossh -p MyPassword scp user@host:/etc/hosts ./hosts

Saved Connections

Add hosts

# Interactive (prompts for all fields)
xcossh add myserver

# Quick add — SSH
xcossh add quick mylinux 'root@192.168.1.100' 'Password123'

# Quick add — with port
xcossh add quick mylinux 'root@192.168.1.100:2222' 'Password123'

# Quick add — with jump host
xcossh add quick internal 'root@10.0.0.5' 'Secret' -J jumphost

# Quick add — with tags
xcossh add quick web1 'deploy@10.0.0.10' 'Pass' -t web,production

# Quick add — Windows (WinRM)
xcossh add quick dc01 'admin@10.0.0.5' 'WinPass' -P winrm

# Quick add — Windows (WinRM over HTTPS)
xcossh add quick dc01 'admin@10.0.0.5' 'WinPass' -P winrm --https

# Quick add — Windows (WinRM with AD domain)
xcossh add quick dc01 'admin@10.0.0.5' 'WinPass' -P winrm --domain CORP

# Quick add — RDP
xcossh add quick desktop 'user@192.168.1.50' 'Pass' -P rdp

List hosts

xcossh list                 # all hosts
xcossh list -t production   # filter by tag

Remove hosts

xcossh remove myserver

SSH Operations

Connect (interactive shell)

xcossh connect mylinux                # interactive SSH session
xcossh connect mylinux -p NewPass     # override password

Execute commands

xcossh exec mylinux "uptime"
xcossh exec mylinux "df -h && free -m"
xcossh exec mylinux "cat /etc/os-release"

Ping (connectivity test)

xcossh ping mylinux           # 3 pings (default)
xcossh ping mylinux -c 5      # 5 pings

# Output shows TCP, SSH handshake, and keepalive latency:
# mylinux: TCP=5ms SSH=120ms PING=15ms OK

Windows Management (WinRM)

Prerequisites

Enable WinRM on the Windows target (run as Administrator):

# Quick setup
winrm quickconfig -q

# Allow basic auth (for non-domain environments)
winrm set winrm/config/service '@{AllowUnencrypted="true"}'
winrm set winrm/config/service/auth '@{Basic="true"}'

# If using HTTPS, configure a certificate instead

One-off commands (no saved connection needed)

# PowerShell (default)
xcossh winrm -p 'WinPass' admin@192.168.1.50 "Get-Process"
xcossh winrm -p 'WinPass' admin@192.168.1.50 "Get-Service | Where Status -eq Running"
xcossh winrm -p 'WinPass' admin@192.168.1.50 "Get-EventLog -LogName System -Newest 10"

# cmd.exe
xcossh winrm -p 'WinPass' --cmd admin@192.168.1.50 "ipconfig /all"
xcossh winrm -p 'WinPass' --cmd admin@192.168.1.50 "dir C:\\"

# With HTTPS
xcossh winrm -p 'WinPass' --https admin@server.domain.com "hostname"

# With AD domain
xcossh winrm -p 'WinPass' --domain CORP admin@dc01 "Get-ADUser -Filter *"

# Custom port
xcossh winrm -p 'WinPass' -P 5986 admin@server "hostname"

Saved connection commands

# Add Windows host
xcossh add quick dc01 'admin@10.0.0.5' 'WinPass' -P winrm

# Connect (interactive PowerShell prompt)
xcossh connect dc01
# Type commands interactively:
#   PS 10.0.0.5> Get-Service
#   PS 10.0.0.5> Get-Process | Sort CPU -Desc | Select -First 10
#   PS 10.0.0.5> exit

# Execute commands
xcossh exec dc01 "Get-Process"
xcossh exec dc01 "Get-Service | Where Status -eq Stopped"
xcossh exec dc01 --cmd "ipconfig /all"       # force cmd.exe
xcossh exec dc01 --ps "Get-Date"             # force PowerShell

# Ping (WinRM connectivity test)
xcossh ping dc01
# dc01: TCP(5985)=5ms WinRM=200ms EXEC=150ms OK

RDP Session Management

Manage Remote Desktop sessions on Windows hosts. Uses WinRM behind the scenes.

# Launch RDP desktop connection
xcossh rdp mywindows

# List active RDP sessions
xcossh rdp sessions mywindows
# Output (qwinsta format):
#  SESSIONNAME  USERNAME  ID  STATE   TYPE
#  console                0   Conn
#  rdp-tcp#0    admin     2   Active
#  rdp-tcp#1    john      3   Active

# Shadow a session (view what the user sees)
xcossh rdp shadow mywindows 2               # view-only
xcossh rdp shadow mywindows 2 --control     # take control
xcossh rdp shadow mywindows 2 --no-consent  # skip user prompt (admin)

# Disconnect a session (keeps it alive)
xcossh rdp disconnect mywindows 2

# Log off a session (ends it)
xcossh rdp logoff mywindows 3

# Send a popup message to a session
xcossh rdp message mywindows 2 "Server rebooting in 5 minutes"
xcossh rdp message mywindows '*' "Maintenance starting"

# List processes in a session
xcossh rdp processes mywindows 2

System Information

Get OS, CPU, RAM, disk, uptime, and network info — works on both Linux and Windows:

xcossh info mylinux
# System Information: mylinux (via SSH)
# ──────────────────────────────────────────────────
#   Hostname:      web01
#   OS:            Ubuntu 22.04.3 LTS
#   Kernel:        5.15.0-91-generic
#   Architecture:  x86_64
#   Uptime:        up 45 days, 3 hours, 12 minutes
#   CPU:           Intel(R) Xeon(R) E5-2680 v4 @ 2.40GHz
#   CPU Cores:     4
#   RAM Total:     8192MB
#   RAM Used:      5120MB
#   RAM Free:      3072MB
#   Disk (root):   100G used:45G avail:55G (45%)
#   Load Average:  0.45 0.32 0.28
#   IP Addresses:  192.168.1.100 10.0.0.10
#   Active Users:  2
#   Processes:     187

xcossh info mywindows
# System Information: mywindows (via WinRM)
# ──────────────────────────────────────────────────
#   Hostname:      DC01
#   OS:            Microsoft Windows Server 2022 Standard 10.0.20348
#   Kernel:        20348
#   Architecture:  64-bit
#   Uptime:        12d 5h 30m
#   CPU:           Intel(R) Xeon(R) Silver 4210R CPU @ 2.40GHz
#   CPU Cores:     8
#   RAM Total:     16384MB
#   RAM Used:      8500MB
#   RAM Free:      7884MB
#   Disk (root):   500GB used:120GB avail:380GB (24%)
#   IP Addresses:  192.168.1.50, fe80::1234:5678
#   Active Users:  3
#   Processes:     142

Service Management

Manage services on Linux (systemd) and Windows (PowerShell) hosts:

Linux (systemd)

xcossh service mylinux status nginx
xcossh service mylinux start nginx
xcossh service mylinux stop nginx
xcossh service mylinux restart nginx
xcossh service mylinux enable nginx
xcossh service mylinux disable nginx
xcossh service mylinux logs nginx          # last 50 journal lines
xcossh service mylinux list                # all services
xcossh service mylinux list --filter running

Windows

xcossh service mywindows status W3SVC
xcossh service mywindows start Spooler
xcossh service mywindows stop Spooler
xcossh service mywindows restart W3SVC
xcossh service mywindows enable W3SVC
xcossh service mywindows disable Telnet
xcossh service mywindows logs W3SVC        # event log entries
xcossh service mywindows list              # all services
xcossh service mywindows list --filter running
xcossh service mywindows list --filter stopped
xcossh service mywindows list --filter IIS  # search by name

File Transfer

SSH hosts (SFTP)

# Download
xcossh scp mylinux:/etc/hosts ./hosts
xcossh scp mylinux:/var/log/syslog ./

# Upload
xcossh scp ./config.txt mylinux:/tmp/
xcossh scp ./app.tar.gz mylinux:/opt/

# Recursive
xcossh scp -r mylinux:/var/log ./logs/
xcossh scp -r ./website mylinux:/var/www/html/

Windows hosts (WinRM)

# Upload to Windows
xcossh copy ./script.ps1 mywindows:C:\temp\
xcossh copy ./config.xml mywindows:C:\inetpub\wwwroot\web.config
xcossh copy ./installer.msi mywindows:C:\temp\installer.msi

# Download from Windows
xcossh copy mywindows:C:\logs\app.log ./
xcossh copy mywindows:C:\Windows\System32\drivers\etc\hosts ./win-hosts

SSH Tunnels

From command line

# Local forward (access remote MySQL on localhost:3306)
xcossh tunnel -L 3306:localhost:3306 mylinux

# Remote forward (expose local dev server on remote port 8080)
xcossh tunnel -R 8080:localhost:3000 mylinux

# SOCKS5 proxy (route all traffic through remote host)
xcossh tunnel -D 1080 mylinux

Saved tunnels (in config file)

# In ~/.xcossh/xcossh.yml
tunnels:
  db-forward:
    host: mylinux
    local_port: 3306
    remote_host: localhost
    remote_port: 3306
    type: local
xcossh tunnel db-forward

Multi-Host Execution

Run commands across multiple hosts in parallel:

# By host names
xcossh multi -H "web1,web2,web3" "uptime"

# By group
xcossh multi -g webservers "systemctl restart nginx"

# By tag
xcossh multi -t production "df -h"

# With concurrency limit
xcossh multi -g all-servers -c 5 "hostname"

# Mixed Linux + Windows (auto-detects protocol per host)
xcossh multi -H "linux1,windows1,linux2" "hostname"

Groups and Tags

Define groups in your config:

groups:
  webservers:
    - web1
    - web2
    - web3
  databases:
    - db1
    - db2

Tag hosts when adding:

xcossh add quick web1 'deploy@10.0.0.10' 'Pass' -t web,production
xcossh add quick db1 'dba@10.0.0.20' 'Pass' -t database,production

SSH Key Management

# Generate a new Ed25519 key pair
xcossh keygen

# Deploy public key to a host (enables passwordless login)
xcossh keygen deploy mylinux

# Deploy to all saved hosts
xcossh keygen deploy --all

Credential Encryption

Encrypt passwords stored in the config file:

# Check current status
xcossh encrypt --check
#   mylinux: PLAIN TEXT
#   mywindows: PLAIN TEXT
#   2 plain text, 0 encrypted

# Encrypt all passwords
xcossh encrypt
#   Encrypted: mylinux
#   Encrypted: mywindows
#   2 passwords encrypted.

# Verify
xcossh encrypt --check
#   mylinux: ENCRYPTED
#   mywindows: ENCRYPTED
#   0 plain text, 2 encrypted

# Passwords are auto-decrypted when used — no workflow change
xcossh exec mylinux "uptime"    # just works

# Decrypt back to plain text (if needed)
xcossh decrypt

How it works:

  • AES-256-GCM encryption
  • Key derived from machine-unique salt + machine ID (PBKDF2, 100K iterations)
  • Encrypted passwords prefixed with ENC: in the config file
  • Auto-decrypted on load — transparent to all commands
  • Machine-bound: config file is safe to backup, passwords only work on this machine

Config File Reference

Location: ~/.xcossh/xcossh.yml

defaults:
  port: 22
  timeout: 10s
  keepalive: 30s
  retry:
    enabled: true
    max_attempts: 3
    backoff: 5s

hosts:
  # Linux host (SSH)
  mylinux:
    host: 192.168.1.100
    port: 22
    user: root
    password: MyPassword          # or ENC:xxxxx after encryption
    key_file: ~/.ssh/id_ed25519   # alternative to password
    jump: jumphost                # ProxyJump via another saved host
    protocol: ssh
    tags:
      - production
      - web
    description: "Production web server"

  # Windows host (WinRM)
  mywindows:
    host: 192.168.1.50
    port: 5985
    user: admin
    password: WinPass123
    protocol: winrm
    use_https: false              # true for port 5986
    shell: powershell             # or cmd
    domain: CORP                  # AD domain (optional)
    tags:
      - production
      - windows

  # Windows host (RDP)
  desktop:
    host: 192.168.1.50
    user: user
    password: Pass123
    protocol: rdp
    rdp_port: 3389
    rdp_fullscreen: true
    rdp_width: 1920
    rdp_height: 1080

groups:
  webservers:
    - web1
    - web2
    - web3
  windows-servers:
    - dc01
    - fileserver
    - exchange

tunnels:
  db-forward:
    host: mylinux
    local_port: 3306
    remote_host: localhost
    remote_port: 3306
    type: local

logging:
  enabled: false
  directory: ~/.xcossh/logs
  format: raw

encryption:
  enabled: false

Environment variables:

  • SSHPASS — default password for legacy mode
  • SSHPASS_CONFIG — override config file path

Testing Guide

Prerequisites

You need at least one of:

  • A Linux/macOS host with SSH enabled
  • A Windows host with WinRM enabled
  • Both (to test cross-platform features)

Test 1: Basic SSH

# Add a test host
xcossh add quick testhost 'user@YOUR_HOST_IP' 'YOUR_PASSWORD'

# Verify it's saved
xcossh list

# Test connectivity
xcossh ping testhost

# Run a command
xcossh exec testhost "hostname && uptime"

# Get system info
xcossh info testhost

# Interactive shell
xcossh connect testhost
# (type 'exit' to disconnect)

Test 2: Legacy xcossh mode

# Direct password
xcossh -p 'YOUR_PASSWORD' ssh user@YOUR_HOST_IP "echo hello"

# Environment variable
export SSHPASS='YOUR_PASSWORD'
xcossh -e ssh user@YOUR_HOST_IP "echo hello"

# Password file
echo 'YOUR_PASSWORD' > /tmp/pw
xcossh -f /tmp/pw ssh user@YOUR_HOST_IP "echo hello"
rm /tmp/pw

Test 3: File transfer (SSH)

# Download
xcossh scp testhost:/etc/hostname /tmp/test_download
cat /tmp/test_download

# Upload
echo "test file" > /tmp/test_upload.txt
xcossh scp /tmp/test_upload.txt testhost:/tmp/
xcossh exec testhost "cat /tmp/test_upload.txt"

# Cleanup
rm /tmp/test_download /tmp/test_upload.txt
xcossh exec testhost "rm /tmp/test_upload.txt"

Test 4: Service management (Linux)

# List running services
xcossh service testhost list --filter running

# Check a specific service
xcossh service testhost status sshd

# View logs
xcossh service testhost logs sshd

Test 5: SSH tunnels

# Start a local forward (e.g., forward local 8080 to remote 80)
xcossh tunnel -L 8080:localhost:80 testhost
# Open http://localhost:8080 in browser (Ctrl+C to stop)

# SOCKS proxy
xcossh tunnel -D 1080 testhost
# Configure browser to use SOCKS5 proxy at localhost:1080

Test 6: Multi-host execution

# Add a second host
xcossh add quick testhost2 'user@SECOND_HOST_IP' 'PASSWORD'

# Run on both
xcossh multi -H "testhost,testhost2" "hostname"

# Cleanup
xcossh remove testhost2

Test 7: Key management

# Generate key pair
xcossh keygen

# Deploy to host (enables passwordless login)
xcossh keygen deploy testhost

# Verify passwordless works
xcossh exec testhost "whoami"

Test 8: Credential encryption

# Check status
xcossh encrypt --check

# Encrypt
xcossh encrypt

# Verify encrypted
xcossh encrypt --check

# Verify still works
xcossh exec testhost "echo 'encryption works'"

# Decrypt
xcossh decrypt

# Verify decrypted
xcossh encrypt --check

Test 9: Windows (WinRM)

# Add Windows host
xcossh add quick wintest 'admin@WIN_HOST_IP' 'WinPassword' -P winrm

# Test connectivity
xcossh ping wintest

# Run PowerShell
xcossh exec wintest "Get-Process | Select -First 5"
xcossh exec wintest "Get-Service | Where Status -eq Running | Select -First 5"

# Run cmd.exe
xcossh exec wintest --cmd "ipconfig"

# System info
xcossh info wintest

# Service management
xcossh service wintest list --filter running
xcossh service wintest status W3SVC

# File transfer
echo "test" > /tmp/wintest.txt
xcossh copy /tmp/wintest.txt wintest:C:\temp\wintest.txt
xcossh copy wintest:C:\temp\wintest.txt /tmp/wintest_downloaded.txt
cat /tmp/wintest_downloaded.txt

# Interactive PowerShell
xcossh connect wintest
# PS> Get-Date
# PS> exit

# One-off WinRM (no saved connection)
xcossh winrm -p 'WinPassword' admin@WIN_HOST_IP "hostname"

# Cleanup
xcossh remove wintest

Test 10: RDP session management

# Add Windows host (needs WinRM for session management)
xcossh add quick wintest 'admin@WIN_HOST_IP' 'WinPassword' -P winrm

# List RDP sessions
xcossh rdp sessions wintest

# Launch RDP connection
xcossh rdp wintest

# Shadow a session (get session ID from 'sessions' first)
xcossh rdp shadow wintest 2
xcossh rdp shadow wintest 2 --control

# Send message
xcossh rdp message wintest 2 "Hello from xcossh!"

# Disconnect/logoff
xcossh rdp disconnect wintest 2
xcossh rdp logoff wintest 2

Test 11: Cross-platform builds

# Build for all platforms
cd /path/to/xcossh
make build-all

# Verify binaries
ls -lh dist/
file dist/xcossh-*

Cleanup

xcossh remove testhost
xcossh remove wintest

Command Reference

Command Description
xcossh connect <name> Interactive shell (SSH/WinRM/RDP)
xcossh exec <name> <cmd> Run command (SSH/WinRM)
xcossh multi -H/-g/-t <cmd> Parallel execution
xcossh scp <src> <dst> File transfer (SSH/SFTP)
xcossh copy <src> <dst> File transfer (WinRM)
xcossh tunnel [-L/-R/-D] <name> SSH tunnel
xcossh info <name> System info
xcossh service <name> <action> <svc> Service management
xcossh ping <name> Connectivity test
xcossh rdp <name> Launch RDP
xcossh rdp sessions <name> List RDP sessions
xcossh rdp shadow <name> <id> Shadow session
xcossh rdp logoff <name> <id> Logoff session
xcossh rdp disconnect <name> <id> Disconnect session
xcossh rdp message <name> <id> <msg> Send message
xcossh rdp processes <name> [id] Session processes
xcossh winrm <user@host> <cmd> One-off WinRM
xcossh add [quick] <name> Save host
xcossh list List hosts
xcossh remove <name> Remove host
xcossh keygen [deploy] Key management
xcossh encrypt Encrypt passwords
xcossh decrypt Decrypt passwords

Building from Source

git clone https://github.com/jmsperu/xcossh.git
cd xcossh

# Build for current platform
make build

# Build for all platforms
make build-all

# Install to /usr/local/bin
make install

# Run tests
make test

Dependencies

  • Go 1.21+
  • golang.org/x/crypto — SSH client
  • github.com/pkg/sftp — SFTP transfers
  • github.com/spf13/cobra — CLI framework
  • gopkg.in/yaml.v3 — config parsing

All vendored into the binary. No runtime dependencies.


License

XcoBean Community License v1.0 — see LICENSE.

Derived from MIT with attribution + trademark clauses. Commercial use permitted; attribution ("Built on XcoBean open technology — https://xcobean.co.ke") required in --version output, docs, or SaaS footers.


Author

James Peru (@jmsperu) — XcoBean Ltd, Nairobi, Kenya

About

Cross-platform sshpass replacement with saved connections, jump hosts, tunnels, SCP, and multi-host execution. Single binary, no dependencies.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors